Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 5dd5e97b

Von Bernd Bleßmann vor fast 9 Jahren hinzugefügt

  • ID 5dd5e97bc9fe0aee0be2621fe11d48c86be40a5d
  • Vorgänger 2d50590b
  • Nachfolger 26a7b7af

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.

Unterschiede anzeigen:

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