Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 5dd5e97b

Von Bernd Bleßmann vor etwa 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
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