commit 96f6aa8d0faf231db82411407e5b0dea3f5698cb
Author: Tamino Steinert <tamino.steinert@tamino.st>
Date:   Mon Feb 27 22:51:15 2023 +0100

    PurchaseInvoice: Auswahl der Warenbuchungsmethode pro Warenzeile
    
    Bei Artikeln(type=parts) kann der Nutzer auswählen welche
    Warenbuchungsmethode dieser haben will.

diff --git a/SL/IR.pm b/SL/IR.pm
index 41fc74381..a45eca06b 100644
--- a/SL/IR.pm
+++ b/SL/IR.pm
@@ -148,7 +148,10 @@ sub _post_invoice {
     $form->{"qty_$i"}  = $form->parse_amount($myconfig, $form->{"qty_$i"});
     $form->{"qty_$i"} *= -1 if $form->{storno};
 
-    if ( $::instance_conf->get_inventory_system eq 'periodic') {
+    if ( ($form->{"tax_chart_type_$i"} eq 'expense')
+      || ($form->{"tax_chart_type_$i"} eq ''
+          && $::instance_conf->get_inventory_system eq 'periodic')
+    ) {
       # inventory account number is overwritten with expense account number, so
       # never book incoming to inventory account but always to expense account
       $form->{"inventory_accno_$i"} = $form->{"expense_accno_$i"}
diff --git a/bin/mozilla/io.pl b/bin/mozilla/io.pl
index 79e5ff988..c0a86392f 100644
--- a/bin/mozilla/io.pl
+++ b/bin/mozilla/io.pl
@@ -173,7 +173,7 @@ sub display_row {
     bin stock_in_out
   );
   my @row2_sort   = qw(
-    expense_chart tax inventory_chart serialnr projectnr reqdate subtotal recurring_billing_mode marge listprice lastcost onhand
+    tax_chart tax serialnr projectnr reqdate subtotal recurring_billing_mode marge listprice lastcost onhand
   );
   # serialnr is important for delivery_orders
   if ($form->{type} eq 'sales_delivery_order') {
@@ -209,9 +209,8 @@ sub display_row {
     lastcost      => {                 value => $locale->text('EK'),                   display => $show_marge, },
     onhand        => {                 value => $locale->text('On Hand'),              display => 1, },
     vendor_partnumber => { width => 8, value => $locale->text('Vendor Part Number'),   display => $is_delivery_order && $is_purchase, },
-    expense_chart => {                 value => $locale->text('Expense Account'),      display => $is_purchase && $is_invoice },
+    tax_chart     => {                 value => "",                                    display => $is_purchase && $is_invoice },
     tax           => {                 value => $locale->text('Tax'),                  display => $is_purchase && $is_invoice },
-    inventory_chart => {               value => "",                                    display => $is_purchase && $is_invoice }, # only disply for type='part'
   );
   my @HEADER = map { $column_def{$_} } @header_sort;
 
@@ -403,19 +402,63 @@ sub display_row {
       $column_data{stock_in_out} =  calculate_stock_in_out($i);
     }
 
-    $column_data{expense_chart} = SL::Presenter::Chart::chart_picker(
-      "expense_chart_id_$i", $form->{"expense_chart_id_$i"},
-      type => "AP_amount", style => "width: 150px") .
-      '<script type="text/javascript">
+    # tax_chart
+    my ($tax_chart_id, $chart_title, $chart_picker);
+    if ($record_item && $record_item->part && ($record_item->part->type eq 'part')) {
+      my $tax_chart_type = $form->{"tax_chart_type_$i"};
+      $tax_chart_type ||=
+        $::instance_conf->get_inventory_system eq 'periodic' ? 'expense'
+                                                             : 'inventory';
+      $tax_chart_id = $form->{"${tax_chart_type}_chart_id_$i"};
+
+      $chart_title = SL::Presenter::Tag::select_tag("tax_chart_type_$i", [
+          {value => 'expense',   title => $locale->text('Expense Account')},
+          {value => 'inventory', title => $locale->text('Inventory Account')},
+        ],
+        value_key => 'value', title_key => 'title',
+        default  => $tax_chart_type,
+        onchange => "kivi.io.update_tax_chart_picker(this.value, $i)",
+      );
+
+      $chart_picker =
+        SL::Presenter::Tag::html_tag('span',
+          SL::Presenter::Chart::chart_picker(
+            "expense_chart_id_$i", $form->{"expense_chart_id_$i"},
+            type => "AP_amount", style => "width: 150px"),
+          id => "expense_chart_span_$i",
+          style => $tax_chart_type eq 'expense' ? '' : 'display:none',
+        )
+        .
+        SL::Presenter::Tag::html_tag('span',
+          SL::Presenter::Chart::chart_picker(
+            "inventory_chart_id_$i", $form->{"inventory_chart_id_$i"},
+            type => "IC", style => "width: 150px"),
+          id => "inventory_chart_span_$i",
+          style => $tax_chart_type eq 'inventory' ? '' : 'display:none',
+        );
+    } else {
+      $tax_chart_id = $form->{"expense_chart_id_$i"};
+      $chart_title = $locale->text('Expense Account');
+      $chart_picker = SL::Presenter::Chart::chart_picker(
+        "expense_chart_id_$i", $form->{"expense_chart_id_$i"},
+        type => "AP_amount", style => "width: 150px");
+    }
+    # change tax dropdown after change
+    my $js_set_on_select_item = '<script type="text/javascript">
       <!--
       $(document).ready(function() {
-        $("#expense_chart_id_' . $i . q'").on("set_item:ChartPicker", function(e, item) {
+        $("#expense_chart_id_' . $i . '").on("set_item:ChartPicker", function(e, item) {
+          kivi.io.update_tax_ids(this);
+        });
+        $("#inventory_chart_id_' . $i . '").on("set_item:ChartPicker", function(e, item) {
           kivi.io.update_tax_ids(this);
         });
       });
       -->
       </script>
-      '; # change tax dropdown after change
+      ';
+    $column_data{tax_chart} = SL::Presenter::Tag::html_tag('span',
+      $chart_title . $chart_picker . $js_set_on_select_item);
 
     my $tax_value_title_sub = sub {
       my $item = shift;
@@ -427,7 +470,7 @@ sub display_row {
 
     my @taxes = ();
     if ($form->{"expense_chart_id_$i"}) {
-      @taxes = IO->get_active_taxes_for_chart($form->{"expense_chart_id_$i"},
+      @taxes = IO->get_active_taxes_for_chart($tax_chart_id,
         $form->{"reqdate_$i"} // $form->{deliverydate} // $form->{transdate});
     }
     # tax_id_ is used in io.js->update_tax_ids
@@ -436,14 +479,6 @@ sub display_row {
       value_title_sub => $tax_value_title_sub,
       style => "width: 100px");
 
-    if ($record_item && $record_item->part && ($record_item->part->type eq 'part')) {
-      $column_data{inventory_chart} =
-      '<b>' . $locale->text('Inventory Account') . '<b> ' .
-      SL::Presenter::Chart::chart_picker(
-        "inventory_chart_id_$i", $form->{"inventory_chart_id_$i"},
-        type => "IC", style => "width: 150px");
-    }
-
     $column_data{serialnr}  = qq|<input name="serialnumber_$i" size="15" value="$form->{"serialnumber_$i"}">|;
     $column_data{projectnr} = NTI($cgi->popup_menu(
       '-name' => "project_id_$i",
@@ -887,7 +922,7 @@ sub remove_emptied_rows {
                 invoice_id converted_from_orderitems_id
                 converted_from_delivery_order_items_id converted_from_invoice_id
                 converted_from_reclamation_items_id recurring_billing_mode
-                expense_chart_id tax_id inventory_chart_id
+                expense_chart_id inventory_chart_id tax_id tax_chart_type
               );
 
   my $ic_cvar_configs = CVar->get_configs(module => 'IC');
diff --git a/js/kivi.io.js b/js/kivi.io.js
index ade3ce9ef..6b780f23a 100644
--- a/js/kivi.io.js
+++ b/js/kivi.io.js
@@ -66,6 +66,16 @@ namespace('kivi.io', function(ns) {
     $('#update_button').click();
   }
 
+  ns.update_tax_chart_picker = function(tax_chart_type, row_i) {
+    $('#expense_chart_span_'   + row_i)[0].style.display = 'none';
+    $('#inventory_chart_span_' + row_i)[0].style.display = 'none';
+
+    let current_chart_picker_span = $('#' + tax_chart_type + '_chart_span_' + row_i)[0];
+    current_chart_picker_span.style.display = 'inline';
+
+    kivi.io.update_tax_ids($('#' + tax_chart_type + '_chart_id_' + row_i)[0]);
+  }
+
   ns.update_tax_ids = function(obj) {
     var row = $(obj).attr('name').replace(/.*_/, '');
 
