+ ->run('kivi.Order.redisplay_items', \@to_sort)
+ ->render;
+}
+
+# show the popup to choose a price/discount source
+sub action_price_popup {
+ my ($self) = @_;
+
+ my $idx = first_index { $_ eq $::form->{item_id} } @{ $::form->{orderitem_ids} };
+ my $item = $self->order->items_sorted->[$idx];
+
+ $self->render_price_dialog($item);
+}
+
+# get the longdescription for an item if the dialog to enter/change the
+# longdescription was opened and the longdescription is empty
+#
+# If this item is new, get the longdescription from Part.
+# Otherwise get it from OrderItem.
+sub action_get_item_longdescription {
+ my $longdescription;
+
+ if ($::form->{item_id}) {
+ $longdescription = SL::DB::OrderItem->new(id => $::form->{item_id})->load->longdescription;
+ } elsif ($::form->{parts_id}) {
+ $longdescription = SL::DB::Part->new(id => $::form->{parts_id})->load->notes;
+ }
+ $_[0]->render(\ $longdescription, { type => 'text' });
+}
+
+# load the second row for one or more items
+#
+# This action gets the html code for all items second rows by rendering a template for
+# the second row and sets the html code via client js.
+sub action_load_second_rows {
+ my ($self) = @_;
+
+ $self->_recalc() if $self->order->is_sales; # for margin calculation
+
+ foreach my $item_id (@{ $::form->{item_ids} }) {
+ my $idx = first_index { $_ eq $item_id } @{ $::form->{orderitem_ids} };
+ my $item = $self->order->items_sorted->[$idx];
+
+ $self->_js_load_second_row($item, $item_id, 0);
+ }
+
+ $self->js->run('kivi.Order.init_row_handlers') if $self->order->is_sales; # for lastcosts change-callback
+
+ $self->js->render();
+}
+
+sub _js_load_second_row {
+ my ($self, $item, $item_id, $do_parse) = @_;
+
+ if ($do_parse) {
+ # Parse values from form (they are formated while rendering (template)).
+ # Workaround to pre-parse number-cvars (parse_custom_variable_values does not parse number values).
+ # This parsing is not necessary at all, if we assure that the second row/cvars are only loaded once.
+ foreach my $var (@{ $item->cvars_by_config }) {
+ $var->unparsed_value($::form->parse_amount(\%::myconfig, $var->{__unparsed_value})) if ($var->config->type eq 'number' && exists($var->{__unparsed_value}));
+ }
+ $item->parse_custom_variable_values;
+ }
+
+ my $row_as_html = $self->p->render('order/tabs/_second_row', ITEM => $item);
+
+ $self->js
+ ->html('.row_entry:has(#item_' . $item_id . ') [name = "second_row"]', $row_as_html)
+ ->data('.row_entry:has(#item_' . $item_id . ') [name = "second_row"]', 'loaded', 1);
+}
+
+sub _js_redisplay_line_values {
+ my ($self) = @_;
+
+ my $is_sales = $self->order->is_sales;
+
+ # sales orders with margins
+ my @data;
+ if ($is_sales) {
+ @data = map {
+ [
+ $::form->format_amount(\%::myconfig, $_->{linetotal}, 2, 0),
+ $::form->format_amount(\%::myconfig, $_->{marge_total}, 2, 0),
+ $::form->format_amount(\%::myconfig, $_->{marge_percent}, 2, 0),
+ ]} @{ $self->order->items_sorted };
+ } else {
+ @data = map {
+ [
+ $::form->format_amount(\%::myconfig, $_->{linetotal}, 2, 0),
+ ]} @{ $self->order->items_sorted };
+ }
+
+ $self->js
+ ->run('kivi.Order.redisplay_line_values', $is_sales, \@data);