X-Git-Url: http://wagnertech.de/gitweb/gitweb.cgi/mfinanz.git/blobdiff_plain/91abaf6cbfa5bb429df7fce3748b3d37082551ad..e8889e47af38072dc6fcbb4d97e2fdcc30d948d7:/SL/Controller/Order.pm?ds=sidebyside diff --git a/SL/Controller/Order.pm b/SL/Controller/Order.pm index 5828132b3..5c8685fbb 100644 --- a/SL/Controller/Order.pm +++ b/SL/Controller/Order.pm @@ -34,6 +34,7 @@ use File::Spec; 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) ], ); @@ -42,7 +43,7 @@ use Rose::Object::MakeMethods::Generic __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) ]); @@ -70,6 +71,8 @@ sub action_add { sub action_edit { my ($self) = @_; + $self->_load_order; + $self->_recalc(); $self->_pre_render(); $self->render( 'order/form', @@ -329,6 +332,24 @@ sub action_customer_vendor_changed { $self->js->render(); } +sub action_unit_changed { + my ($self) = @_; + + my $idx = first_index { $_ eq $::form->{item_id} } @{ $::form->{orderitem_ids} }; + 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)); + + $self->_recalc(); + + $self->js + ->run('update_sellprice', $::form->{item_id}, $item->sellprice_as_number); + $self->_js_redisplay_linetotals; + $self->_js_redisplay_amounts_and_taxes; + $self->js->render(); +} + sub action_add_item { my ($self) = @_; @@ -336,7 +357,7 @@ sub action_add_item { 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(); @@ -349,6 +370,8 @@ sub action_add_item { ->val('.add_item_input', '') ->run('row_table_scroll_down') ->run('row_set_keyboard_events_by_id', $item_id) + ->run('set_unit_change_with_oldval_by_id', $item_id) + ->run('renumber_positions') ->on('.recalc', 'change', 'recalc_amounts_and_taxes') ->on('.reformat_number', 'change', 'reformat_number') ->focus('#add_item_parts_id_name'); @@ -388,7 +411,7 @@ sub action_add_multi_items { 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); @@ -400,12 +423,14 @@ sub action_add_multi_items { $self->js ->append('#row_table_id', $row_as_html) - ->run('row_set_keyboard_events_by_id', $item_id); + ->run('row_set_keyboard_events_by_id', $item_id) + ->run('set_unit_change_with_oldval_by_id', $item_id); } $self->js ->run('close_multi_items_dialog') ->run('row_table_scroll_down') + ->run('renumber_positions') ->on('.recalc', 'change', 'recalc_amounts_and_taxes') ->on('.reformat_number', 'change', 'reformat_number') ->focus('#add_item_parts_id_name'); @@ -424,11 +449,34 @@ sub action_recalc_amounts_and_taxes { $self->js->render(); } +sub action_reorder_items { + my ($self) = @_; + + my %sort_keys = ( + partnumber => sub { $_[0]->part->partnumber }, + description => sub { $_[0]->description }, + qty => sub { $_[0]->qty }, + sellprice => sub { $_[0]->sellprice }, + discount => sub { $_[0]->discount }, + ); + + my $method = $sort_keys{$::form->{order_by}}; + my @to_sort = map { { old_pos => $_->position, order_by => $method->($_) } } @{ $self->order->items_sorted }; + if ($::form->{sort_dir}) { + @to_sort = sort { $a->{order_by} cmp $b->{order_by} } @to_sort; + } else { + @to_sort = sort { $b->{order_by} cmp $a->{order_by} } @to_sort; + } + $self->js + ->run('redisplay_items', \@to_sort) + ->render; +} + sub action_price_popup { 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); } @@ -436,7 +484,7 @@ sub action_price_popup { 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); } @@ -496,7 +544,7 @@ sub init_p { } sub init_order { - _make_order(); + $_[0]->_make_order; } sub init_multi_items_models { @@ -583,6 +631,14 @@ sub render_price_dialog { $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) = @_; @@ -593,14 +649,53 @@ sub _make_order { $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); @@ -722,7 +817,8 @@ sub _save { $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; @@ -748,11 +844,10 @@ sub _pre_render { $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) {