Auftrags-Controller: Preisquellen in oberer Eingabezeile besser berücksichtigen
authorBernd Bleßmann <bernd@kivitendo-premium.de>
Wed, 13 Apr 2022 10:38:07 +0000 (12:38 +0200)
committerBernd Bleßmann <bernd@kivitendo-premium.de>
Wed, 13 Apr 2022 10:38:07 +0000 (12:38 +0200)
Das alte Verhalten war, Preisquellen bei der Übernahme der Eingabezeile in die
Position zu berücksichtigen, wenn das Preisfeld leer war.
Das war nicht ersichtlich. Zudem wurde bei der Auswahl (Picker) eines Artikels
der Artikelpreis ohne Berücksichtigung der Quellen in das Preisfeld oben
eingetragen, so dass man es leer machen musste, um den Preisquellenpreis in die
Position zu übernehmen.

Nun wird nach der Auswahl (Picker) eines Artikels der Preis der Preisquelle
als placeholder in das Preisfeld eingetragen. Ein tooltip zeigt die Quelle an.
Damit bleibt das Feld leer und der Quellenpreis wird für die Position
verwendet.
Die Bearbeiterin sieht den Preis, der verwendet wird, kann ihn aber
auch leicht überschreiben.

Analog gilt das alles für das Rabattfeld.

SL/Controller/Order.pm
js/kivi.Order.js
templates/webpages/order/tabs/_item_input.html

index 0dd06eb..e531312 100644 (file)
@@ -887,6 +887,62 @@ sub action_unit_changed {
   $self->js->render();
 }
 
+# update item input row when a part ist picked
+sub action_update_item_input_row {
+  my ($self) = @_;
+
+  delete $::form->{add_item}->{$_} for qw(create_part_type sellprice_as_number discount_as_percent);
+
+  my $form_attr = $::form->{add_item};
+
+  return unless $form_attr->{parts_id};
+
+  my $record       = $self->order;
+  my $item         = SL::DB::OrderItem->new(%$form_attr);
+  my $part         = SL::DB::Part->new(id => $::form->{add_item}->{parts_id})->load;
+  my $price_source = SL::PriceSource->new(record_item => $item, record => $record);
+
+  $item->unit($part->unit);
+
+  my $price_src;
+  if ( $part->is_assortment ) {
+    # add assortment items with price 0, as the components carry the price
+    $price_src = $price_source->price_from_source("");
+    $price_src->price(0);
+  } elsif (defined $item->sellprice) {
+    $price_src = $price_source->price_from_source("");
+    $price_src->price($item->sellprice);
+  } else {
+    $price_src = $price_source->best_price
+               ? $price_source->best_price
+               : $price_source->price_from_source("");
+    $price_src->price($::form->round_amount($price_src->price / $record->exchangerate, 5)) if $record->exchangerate;
+    $price_src->price(0) if !$price_source->best_price;
+  }
+
+  my $discount_src;
+  if (defined $item->discount) {
+    $discount_src = $price_source->discount_from_source("");
+    $discount_src->discount($item->discount);
+  } else {
+    $discount_src = $price_source->best_discount
+                  ? $price_source->best_discount
+                  : $price_source->discount_from_source("");
+    $discount_src->discount(0) if !$price_source->best_discount;
+  }
+
+  $self->js
+    ->val     ('#add_item_unit',                $item->unit)
+    ->val     ('#add_item_description',         $part->description)
+    ->val     ('#add_item_sellprice_as_number', '')
+    ->attr    ('#add_item_sellprice_as_number', 'placeholder', $price_src->price_as_number)
+    ->attr    ('#add_item_sellprice_as_number', 'title',       $price_src->source_description)
+    ->val     ('#add_item_discount_as_percent', '')
+    ->attr    ('#add_item_discount_as_percent', 'placeholder', $discount_src->discount_as_percent)
+    ->attr    ('#add_item_discount_as_percent', 'title',       $discount_src->source_description)
+    ->render;
+}
+
 # add an item row for a new item entered in the input row
 sub action_add_item {
   my ($self) = @_;
@@ -954,6 +1010,8 @@ sub action_add_item {
 
   $self->js
     ->val('.add_item_input', '')
+    ->attr('.add_item_input', 'placeholder', '')
+    ->attr('.add_item_input', 'title', '')
     ->run('kivi.Order.init_row_handlers')
     ->run('kivi.Order.renumber_positions')
     ->focus('#add_item_parts_id_name');
@@ -2711,21 +2769,10 @@ java script functions
 
 =item *
 
-Customer discount is not displayed as a valid discount in price source popup
-(this might be a bug in price sources)
-
-(I cannot reproduce this (Bernd))
-
-=item *
-
 No indication that <shift>-up/down expands/collapses second row.
 
 =item *
 
-Inline creation of parts is not currently supported
-
-=item *
-
 Table header is not sticky in the scrolling area.
 
 =item *
@@ -2748,10 +2795,6 @@ How to expand/collapse second row. Now it can be done clicking the icon or
 
 =item *
 
-Possibility to select PriceSources in input row?
-
-=item *
-
 This controller uses a (changed) copy of the template for the PriceSource
 dialog. Maybe there could be used one code source.
 
index 05cea60..b82358b 100644 (file)
@@ -474,6 +474,15 @@ namespace('kivi.Order', function(ns) {
     return insert_before_item_id;
   };
 
+  ns.update_item_input_row = function() {
+    if (!ns.check_cv()) return;
+
+    var data = $('#order_form').serializeArray();
+    data.push({ name: 'action', value: 'Order/update_item_input_row' });
+
+    $.post("controller.pl", data, kivi.eval_json_result);
+  };
+
   ns.add_item = function() {
     if ($('#add_item_parts_id').val() === '') return;
     if (!ns.check_cv()) return;
@@ -902,13 +911,9 @@ $(function() {
   $('#order_transdate_as_date').change(kivi.Order.update_exchangerate);
   $('#order_exchangerate_as_null_number').change(kivi.Order.exchangerate_changed);
 
-  if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
-    $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
-  } else {
-    $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
-  }
-  $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
-  $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
+  $('#add_item_parts_id').on('set_item:PartPicker', function() {
+    kivi.Order.update_item_input_row();
+  });
 
   $('.add_item_input').keydown(function(event) {
     if (event.keyCode == 13) {
index 1b1bf60..8f75b6f 100644 (file)
@@ -29,7 +29,6 @@
           [%- SET PARAM_KEY = SELF.cv == "customer" ? 'with_customer_partnumber' : 'with_makemodel' -%]
           [%- SET PARAM_VAL = SELF.search_cvpartnumber -%]
           [% P.part.picker('add_item.parts_id', SELF.created_part, style='width: 300px', class="add_item_input",
-                            fat_set_item=1,
                             multiple_pos_input=1,
                             action={set_multi_items='kivi.Order.add_multi_items'},
                             classification_id=SELF.part_picker_classification_ids.as_list.join(','),
           [% L.input_tag('add_item.qty_as_number', '', size = 5, class="add_item_input numeric") %]
           [% L.hidden_tag('add_item.unit', SELF.created_part.unit, class="add_item_input") %]
         </td>
-        [%- SET price = LxERP.format_amount(((SELF.type == 'sales_quotation' || SELF.type == 'sales_order') ? SELF.created_part.sellprice : SELF.created_part.lastcost), -2) -%]
-        <td>[% L.input_tag('add_item.sellprice_as_number', price, size = 10, class="add_item_input numeric") %]</td>
-        <td>[% L.input_tag('add_item.discount_as_percent', '', size = 5, class="add_item_input numeric") %]</td>
+        [%- SET price = '' %]
+        [%- IF SELF.created_part %]
+          [%- SET price = LxERP.format_amount(((SELF.type == 'sales_quotation' || SELF.type == 'sales_order') ? SELF.created_part.sellprice : SELF.created_part.lastcost), -2) -%]
+        [%- END %]
+        <td>[% L.input_tag('add_item.sellprice_as_number', price, size = 10, class="add_item_input numeric tooltipster-html") %]</td>
+        <td>[% L.input_tag('add_item.discount_as_percent', '', size = 5, class="add_item_input numeric tooltipster-html") %]</td>
         <td>[% L.button_tag('kivi.Order.add_item()', LxERP.t8('Add part')) %]</td>
       </tr>
     </tbody>