Revision 5dd5e97b
Von Bernd Bleßmann vor etwa 9 Jahren hinzugefügt
SL/Controller/Order.pm | ||
---|---|---|
|
||
use Rose::Object::MakeMethods::Generic
|
||
(
|
||
scalar => [ qw(item_ids_to_delete) ],
|
||
'scalar --get_set_init' => [ qw(order valid_types type cv p multi_items_models) ],
|
||
);
|
||
|
||
... | ... | |
__PACKAGE__->run_before('_check_auth');
|
||
|
||
__PACKAGE__->run_before('_recalc',
|
||
only => [ qw(edit update save save_and_delivery_order create_pdf send_email) ]);
|
||
only => [ qw(update save save_and_delivery_order create_pdf send_email) ]);
|
||
|
||
__PACKAGE__->run_before('_get_unalterable_data',
|
||
only => [ qw(save save_and_delivery_order create_pdf send_email) ]);
|
||
... | ... | |
sub action_edit {
|
||
my ($self) = @_;
|
||
|
||
$self->_load_order;
|
||
$self->_recalc();
|
||
$self->_pre_render();
|
||
$self->render(
|
||
'order/form',
|
||
... | ... | |
my ($self) = @_;
|
||
|
||
my $idx = first_index { $_ eq $::form->{item_id} } @{ $::form->{orderitem_ids} };
|
||
my $item = $self->order->items->[$idx];
|
||
my $item = $self->order->items_sorted->[$idx];
|
||
|
||
my $old_unit_obj = SL::DB::Unit->new(name => $::form->{old_unit})->load;
|
||
$item->sellprice($item->unit_obj->convert_to($item->sellprice, $old_unit_obj));
|
||
... | ... | |
|
||
return unless $form_attr->{parts_id};
|
||
|
||
my $item = _make_item($self->order, $form_attr);
|
||
my $item = _new_item($self->order, $form_attr);
|
||
$self->order->add_items($item);
|
||
|
||
$self->_recalc();
|
||
... | ... | |
|
||
my @items;
|
||
foreach my $attr (@form_attr) {
|
||
push @items, _make_item($self->order, $attr);
|
||
push @items, _new_item($self->order, $attr);
|
||
}
|
||
$self->order->add_items(@items);
|
||
|
||
... | ... | |
my ($self) = @_;
|
||
|
||
my $idx = first_index { $_ eq $::form->{item_id} } @{ $::form->{orderitem_ids} };
|
||
my $item = $self->order->items->[$idx];
|
||
my $item = $self->order->items_sorted->[$idx];
|
||
|
||
$self->render_price_dialog($item);
|
||
}
|
||
... | ... | |
sub _js_redisplay_linetotals {
|
||
my ($self) = @_;
|
||
|
||
my @data = map {$::form->format_amount(\%::myconfig, $_->{linetotal}, 2, 0)} @{ $self->order->items };
|
||
my @data = map {$::form->format_amount(\%::myconfig, $_->{linetotal}, 2, 0)} @{ $self->order->items_sorted };
|
||
$self->js
|
||
->run('redisplay_linetotals', \@data);
|
||
}
|
||
... | ... | |
}
|
||
|
||
sub init_order {
|
||
_make_order();
|
||
$_[0]->_make_order;
|
||
}
|
||
|
||
sub init_multi_items_models {
|
||
... | ... | |
$self->js->render;
|
||
}
|
||
|
||
sub _load_order {
|
||
my ($self) = @_;
|
||
|
||
return if !$::form->{id};
|
||
|
||
$self->order(SL::DB::Manager::Order->find_by(id => $::form->{id}));
|
||
}
|
||
|
||
sub _make_order {
|
||
my ($self) = @_;
|
||
|
||
... | ... | |
$order = SL::DB::Manager::Order->find_by(id => $::form->{id}) if $::form->{id};
|
||
$order ||= SL::DB::Order->new(orderitems => []);
|
||
|
||
my $form_orderitems = delete $::form->{order}->{orderitems};
|
||
$order->assign_attributes(%{$::form->{order}});
|
||
|
||
# remove deleted items
|
||
$self->item_ids_to_delete([]);
|
||
foreach my $idx (reverse 0..$#{$order->orderitems}) {
|
||
my $item = $order->orderitems->[$idx];
|
||
if (none { $item->id == $_->{id} } @{$form_orderitems}) {
|
||
splice @{$order->orderitems}, $idx, 1;
|
||
push @{$self->item_ids_to_delete}, $item->id;
|
||
}
|
||
}
|
||
|
||
my @items;
|
||
my $pos = 1;
|
||
foreach my $form_attr (@{$form_orderitems}) {
|
||
my $item = _make_item($order, $form_attr);
|
||
$item->position($pos);
|
||
push @items, $item;
|
||
$pos++;
|
||
}
|
||
$order->add_items(grep {!$_->id} @items);
|
||
|
||
return $order;
|
||
}
|
||
|
||
|
||
# Make item objects from form values. For items already existing read from db.
|
||
# Create a new item else. And assign attributes.
|
||
sub _make_item {
|
||
my ($record, $attr) = @_;
|
||
|
||
my $item;
|
||
$item = first { $_->id == $attr->{id} } @{$record->items} if $attr->{id};
|
||
|
||
# add_custom_variables adds cvars to an orderitem with no cvars for saving, but
|
||
# they cannot be retrieved via custom_variables until the order/orderitem is
|
||
# saved. Adding empty custom_variables to new orderitem here solves this problem.
|
||
$item ||= SL::DB::OrderItem->new(custom_variables => []);
|
||
$item->assign_attributes(%$attr);
|
||
|
||
return $item;
|
||
}
|
||
|
||
sub _new_item {
|
||
my ($record, $attr) = @_;
|
||
|
||
my $item = SL::DB::OrderItem->new;
|
||
$item->assign_attributes(%$attr);
|
||
|
||
... | ... | |
|
||
$db->do_transaction(
|
||
sub {
|
||
$self->order->save();
|
||
SL::DB::OrderItem->new(id => $_)->delete for @{$self->item_ids_to_delete};
|
||
$self->order->save(cascade => 1);
|
||
}) || push(@{$errors}, $db->error);
|
||
|
||
return $errors;
|
||
... | ... | |
|
||
$self->{current_employee_id} = SL::DB::Manager::Employee->current->id;
|
||
|
||
foreach my $item (@{$self->order->items}) {
|
||
foreach my $item (@{$self->order->orderitems}) {
|
||
my $price_source = SL::PriceSource->new(record_item => $item, record => $self->order);
|
||
$item->active_price_source( $price_source->price_from_source( $item->active_price_source ));
|
||
$item->active_discount_source($price_source->discount_from_source($item->active_discount_source));
|
||
|
||
}
|
||
|
||
if ($self->order->ordnumber && $::instance_conf->get_webdav) {
|
Auch abrufbar als: Unified diff
Auftrags-Controller: vorhandene orderitems vor Neu-Schreiben nicht löschen …
Hintergrund: Wird einem Rose-Object eine Relationship als Array übergeben (z.B.
$order->orderitems(@items), so löscht Rose dei DB-Einträge und schreibt sie neu.
In dem Fall werden allerdings auch DB-Trigger ausgelöst, was hier zum
unerwünschten Löschen der record_links auf item-Ebene führte.
Hier wurden die items via assign_attributes als ganzes dem Order-Objekt
hinzugefügt.
Jetzt werden die items einzeln hinzugefügt, wenn sie neu sind und die
vorhandenen, die aus der Makse entfernt wurde, werden extra gelöscht.