Revision 5dd5e97b
Von Bernd Bleßmann vor fast 9 Jahren hinzugefügt
SL/Controller/Order.pm | ||
---|---|---|
34 | 34 |
|
35 | 35 |
use Rose::Object::MakeMethods::Generic |
36 | 36 |
( |
37 |
scalar => [ qw(item_ids_to_delete) ], |
|
37 | 38 |
'scalar --get_set_init' => [ qw(order valid_types type cv p multi_items_models) ], |
38 | 39 |
); |
39 | 40 |
|
... | ... | |
42 | 43 |
__PACKAGE__->run_before('_check_auth'); |
43 | 44 |
|
44 | 45 |
__PACKAGE__->run_before('_recalc', |
45 |
only => [ qw(edit update save save_and_delivery_order create_pdf send_email) ]);
|
|
46 |
only => [ qw(update save save_and_delivery_order create_pdf send_email) ]); |
|
46 | 47 |
|
47 | 48 |
__PACKAGE__->run_before('_get_unalterable_data', |
48 | 49 |
only => [ qw(save save_and_delivery_order create_pdf send_email) ]); |
... | ... | |
70 | 71 |
sub action_edit { |
71 | 72 |
my ($self) = @_; |
72 | 73 |
|
74 |
$self->_load_order; |
|
75 |
$self->_recalc(); |
|
73 | 76 |
$self->_pre_render(); |
74 | 77 |
$self->render( |
75 | 78 |
'order/form', |
... | ... | |
333 | 336 |
my ($self) = @_; |
334 | 337 |
|
335 | 338 |
my $idx = first_index { $_ eq $::form->{item_id} } @{ $::form->{orderitem_ids} }; |
336 |
my $item = $self->order->items->[$idx]; |
|
339 |
my $item = $self->order->items_sorted->[$idx];
|
|
337 | 340 |
|
338 | 341 |
my $old_unit_obj = SL::DB::Unit->new(name => $::form->{old_unit})->load; |
339 | 342 |
$item->sellprice($item->unit_obj->convert_to($item->sellprice, $old_unit_obj)); |
... | ... | |
354 | 357 |
|
355 | 358 |
return unless $form_attr->{parts_id}; |
356 | 359 |
|
357 |
my $item = _make_item($self->order, $form_attr);
|
|
360 |
my $item = _new_item($self->order, $form_attr);
|
|
358 | 361 |
$self->order->add_items($item); |
359 | 362 |
|
360 | 363 |
$self->_recalc(); |
... | ... | |
407 | 410 |
|
408 | 411 |
my @items; |
409 | 412 |
foreach my $attr (@form_attr) { |
410 |
push @items, _make_item($self->order, $attr);
|
|
413 |
push @items, _new_item($self->order, $attr);
|
|
411 | 414 |
} |
412 | 415 |
$self->order->add_items(@items); |
413 | 416 |
|
... | ... | |
448 | 451 |
my ($self) = @_; |
449 | 452 |
|
450 | 453 |
my $idx = first_index { $_ eq $::form->{item_id} } @{ $::form->{orderitem_ids} }; |
451 |
my $item = $self->order->items->[$idx]; |
|
454 |
my $item = $self->order->items_sorted->[$idx];
|
|
452 | 455 |
|
453 | 456 |
$self->render_price_dialog($item); |
454 | 457 |
} |
... | ... | |
456 | 459 |
sub _js_redisplay_linetotals { |
457 | 460 |
my ($self) = @_; |
458 | 461 |
|
459 |
my @data = map {$::form->format_amount(\%::myconfig, $_->{linetotal}, 2, 0)} @{ $self->order->items }; |
|
462 |
my @data = map {$::form->format_amount(\%::myconfig, $_->{linetotal}, 2, 0)} @{ $self->order->items_sorted };
|
|
460 | 463 |
$self->js |
461 | 464 |
->run('redisplay_linetotals', \@data); |
462 | 465 |
} |
... | ... | |
516 | 519 |
} |
517 | 520 |
|
518 | 521 |
sub init_order { |
519 |
_make_order();
|
|
522 |
$_[0]->_make_order;
|
|
520 | 523 |
} |
521 | 524 |
|
522 | 525 |
sub init_multi_items_models { |
... | ... | |
603 | 606 |
$self->js->render; |
604 | 607 |
} |
605 | 608 |
|
609 |
sub _load_order { |
|
610 |
my ($self) = @_; |
|
611 |
|
|
612 |
return if !$::form->{id}; |
|
613 |
|
|
614 |
$self->order(SL::DB::Manager::Order->find_by(id => $::form->{id})); |
|
615 |
} |
|
616 |
|
|
606 | 617 |
sub _make_order { |
607 | 618 |
my ($self) = @_; |
608 | 619 |
|
... | ... | |
613 | 624 |
$order = SL::DB::Manager::Order->find_by(id => $::form->{id}) if $::form->{id}; |
614 | 625 |
$order ||= SL::DB::Order->new(orderitems => []); |
615 | 626 |
|
627 |
my $form_orderitems = delete $::form->{order}->{orderitems}; |
|
616 | 628 |
$order->assign_attributes(%{$::form->{order}}); |
617 | 629 |
|
630 |
# remove deleted items |
|
631 |
$self->item_ids_to_delete([]); |
|
632 |
foreach my $idx (reverse 0..$#{$order->orderitems}) { |
|
633 |
my $item = $order->orderitems->[$idx]; |
|
634 |
if (none { $item->id == $_->{id} } @{$form_orderitems}) { |
|
635 |
splice @{$order->orderitems}, $idx, 1; |
|
636 |
push @{$self->item_ids_to_delete}, $item->id; |
|
637 |
} |
|
638 |
} |
|
639 |
|
|
640 |
my @items; |
|
641 |
my $pos = 1; |
|
642 |
foreach my $form_attr (@{$form_orderitems}) { |
|
643 |
my $item = _make_item($order, $form_attr); |
|
644 |
$item->position($pos); |
|
645 |
push @items, $item; |
|
646 |
$pos++; |
|
647 |
} |
|
648 |
$order->add_items(grep {!$_->id} @items); |
|
649 |
|
|
618 | 650 |
return $order; |
619 | 651 |
} |
620 | 652 |
|
653 |
|
|
654 |
# Make item objects from form values. For items already existing read from db. |
|
655 |
# Create a new item else. And assign attributes. |
|
621 | 656 |
sub _make_item { |
622 | 657 |
my ($record, $attr) = @_; |
623 | 658 |
|
659 |
my $item; |
|
660 |
$item = first { $_->id == $attr->{id} } @{$record->items} if $attr->{id}; |
|
661 |
|
|
662 |
# add_custom_variables adds cvars to an orderitem with no cvars for saving, but |
|
663 |
# they cannot be retrieved via custom_variables until the order/orderitem is |
|
664 |
# saved. Adding empty custom_variables to new orderitem here solves this problem. |
|
665 |
$item ||= SL::DB::OrderItem->new(custom_variables => []); |
|
666 |
$item->assign_attributes(%$attr); |
|
667 |
|
|
668 |
return $item; |
|
669 |
} |
|
670 |
|
|
671 |
sub _new_item { |
|
672 |
my ($record, $attr) = @_; |
|
673 |
|
|
624 | 674 |
my $item = SL::DB::OrderItem->new; |
625 | 675 |
$item->assign_attributes(%$attr); |
626 | 676 |
|
... | ... | |
742 | 792 |
|
743 | 793 |
$db->do_transaction( |
744 | 794 |
sub { |
745 |
$self->order->save(); |
|
795 |
SL::DB::OrderItem->new(id => $_)->delete for @{$self->item_ids_to_delete}; |
|
796 |
$self->order->save(cascade => 1); |
|
746 | 797 |
}) || push(@{$errors}, $db->error); |
747 | 798 |
|
748 | 799 |
return $errors; |
... | ... | |
768 | 819 |
|
769 | 820 |
$self->{current_employee_id} = SL::DB::Manager::Employee->current->id; |
770 | 821 |
|
771 |
foreach my $item (@{$self->order->items}) {
|
|
822 |
foreach my $item (@{$self->order->orderitems}) {
|
|
772 | 823 |
my $price_source = SL::PriceSource->new(record_item => $item, record => $self->order); |
773 | 824 |
$item->active_price_source( $price_source->price_from_source( $item->active_price_source )); |
774 | 825 |
$item->active_discount_source($price_source->discount_from_source($item->active_discount_source)); |
775 |
|
|
776 | 826 |
} |
777 | 827 |
|
778 | 828 |
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.