commit 295c12050babc963eb5acc22fc66f66325bead98
Author: Tamino Steinert <tamino.steinert@tamino.st>
Date:   Tue Nov 29 18:53:54 2022 +0100

    Controller: DeliveryOrder: stock_dialog um Einlagern erweitert

diff --git a/SL/Controller/DeliveryOrder.pm b/SL/Controller/DeliveryOrder.pm
index bcbbd01e1..1350e2b7c 100644
--- a/SL/Controller/DeliveryOrder.pm
+++ b/SL/Controller/DeliveryOrder.pm
@@ -930,41 +930,10 @@ sub action_stock_in_out_dialog {
 
   $self->merge_stock_data($stock_info, \@contents, $part, $unit);
 
-    my @collection = (
-    { 'description' => 'foo_1', 'id' => '1',
-      'key_1' => [
-        { 'id' => 3, 'description' => "bar_1",
-          'key_2' => [
-            { 'id' => 1, 'value' => "foobar_1", },
-            { 'id' => 2, 'value' => "foobar_2", },
-          ],
-        },
-        { 'id' => 4, 'description' => "bar_2",
-        'key_2' => [],
-        },
-      ],
-    },
-    { 'description' => 'foo_2', 'id' => '2',
-      'key_1' => [
-        { 'id' => 1, 'description' => "bar_1",
-          'key_2' => [
-            { 'id' => 3, 'value' => "foobar_3", },
-            { 'id' => 4, 'value' => "foobar_4", },
-          ],
-        },
-        { 'id' => 2, 'description' => "bar_2",
-          'stock' => [
-            { 'id' => 5, 'value' => "test_5", },
-          ],
-        },
-      ],
-    },
-  );
-
   $self->render("delivery_order/stock_dialog", { layout => 0 },
-    WHCONTENTS => $self->order->delivered ? $stock_info : \@contents,
+    WHCONTENTS => \@contents,
+    STOCK_INFO => $stock_info,
     WAREHOUSES => SL::DB::Manager::Warehouse->get_all(with_objects=> ["bins",]),
-    COLLECTION => \@collection,
     part       => $part,
     do_qty     => $qty,
     do_unit    => $unit->unit,
@@ -975,6 +944,24 @@ sub action_stock_in_out_dialog {
   );
 }
 
+sub action_add_stock_in_line_to_dialog {
+  my ($self) = @_;
+
+  my $do_qty       = _parse_number($::form->{do_qty});
+  my $qty_sum   = $::form->{qty_sum};
+  my $row_count = $::form->{row_count};
+  my $part      = SL::DB::Part->load_cached($::form->{parts_id}) or die "need parts_id";
+
+  my $row_as_html = $self->p->render('delivery_order/stock_dialog/_stock_in_new_row',
+    WAREHOUSES => SL::DB::Manager::Warehouse->get_all(with_objects=> ["bins",]),
+    PART => $part,
+    pos  => $row_count + 1,
+    remaining_qty => $do_qty - $qty_sum,
+  );
+
+  $self->js->append('#stock-in-out-table', $row_as_html)->render();
+}
+
 sub action_update_stock_information {
   my ($self) = @_;
 
diff --git a/js/kivi.DeliveryOrder.js b/js/kivi.DeliveryOrder.js
index 14e74ec41..06299b781 100644
--- a/js/kivi.DeliveryOrder.js
+++ b/js/kivi.DeliveryOrder.js
@@ -109,6 +109,37 @@ namespace('kivi.DeliveryOrder', function(ns) {
     });
   };
 
+  ns.add_stock_in_line_to_dialog = function() {
+    console.log("clicked");
+    console.log($("#parts_id"));
+    console.log($("#parts_id").val());
+    console.log($("#do_qty"));
+    console.log($("#do_qty").val());
+
+    let qty_sum = 0;
+    let row_count = 0;
+    $("#stock-in-out-table tr.listrow").each((i,row) => {
+      let qty = kivi.parse_amount($(row).find(".data-qty").val());
+
+      row_count = row_count + 1;
+      if (qty === 0) return;
+      if (qty === null) return;
+      qty_sum = qty_sum + qty;
+    });
+
+    let data = [];
+    data.push(
+      { name: 'action', value: 'DeliveryOrder/add_stock_in_line_to_dialog' },
+      { name: 'type', value: $("#type").val()},
+      { name: 'qty_sum', value: qty_sum },
+      { name: 'row_count', value: row_count},
+      { name: 'parts_id', value: $("#parts_id").val()},
+      { name: 'do_qty', value:  $("#do_qty").val()},
+    );
+
+    $.post("controller.pl", data, kivi.eval_json_result);
+  };
+
   ns.save_updated_stock = function() {
     // stock information is saved in DOM as a yaml dump.
     // we don't want to do this in javascript so we do a tiny roundtrip to the backend
@@ -118,6 +149,7 @@ namespace('kivi.DeliveryOrder', function(ns) {
       let qty = kivi.parse_amount($(row).find(".data-qty").val());
 
       if (qty === 0) return;
+      if (qty === null) return;
 
       data.push({
         qty:                           qty,
diff --git a/templates/webpages/delivery_order/stock_dialog.html b/templates/webpages/delivery_order/stock_dialog.html
index abb2c70b9..30ea86a08 100644
--- a/templates/webpages/delivery_order/stock_dialog.html
+++ b/templates/webpages/delivery_order/stock_dialog.html
@@ -4,10 +4,6 @@
 [%- USE L %]
 
 <form>
- [%- IF delivered %]
-  [% PROCESS "delivery_order/stock_dialog/_stock_delivered_dialog.html" %]
- [%- ELSE %]
-
  <table>
   <tr>
    <td>[% 'Part Number' | $T8 %]</td>
@@ -23,12 +19,16 @@
   </tr>
  </table>
 
-  [% L.hidden_tag("in_out", in_out) %]
-  [% L.hidden_tag("parts_id", parts_id) %]
-  [% L.hidden_tag("do_qty", do_qty) %]
-  [% L.hidden_tag("do_unit", do_unit) %]
-  [% L.hidden_tag("row", row, class="data-row") %]
-  [% L.hidden_tag("item_id", item_id) %]
+ [% L.hidden_tag("in_out", in_out) %]
+ [% L.hidden_tag("parts_id", part.id) %]
+ [% L.hidden_tag("do_qty", do_qty) %]
+ [% L.hidden_tag("do_unit", do_unit) %]
+ [% L.hidden_tag("row", row, class="data-row") %]
+ [% L.hidden_tag("item_id", item_id) %]
+
+ [%- IF delivered %]
+  [% PROCESS "delivery_order/stock_dialog/_stock_delivered_dialog.html" %]
+ [%- ELSE %]
 
   [%- IF in_out == "in" %]
   <p>
@@ -48,6 +48,10 @@
    </table>
   </p>
 
+  [%- IF in_out == "in" %]
+  [% L.button_tag('kivi.DeliveryOrder.add_stock_in_line_to_dialog()', LxERP.t8('+')) %]
+  [%- END %]
+
   <hr size="3" noshade>
 
   <p>[% L.button_tag('kivi.DeliveryOrder.save_updated_stock()', LxERP.t8('Save')) %]</p>
diff --git a/templates/webpages/delivery_order/stock_dialog/_stock_delivered_dialog.html b/templates/webpages/delivery_order/stock_dialog/_stock_delivered_dialog.html
index f4935cf4f..54281173b 100644
--- a/templates/webpages/delivery_order/stock_dialog/_stock_delivered_dialog.html
+++ b/templates/webpages/delivery_order/stock_dialog/_stock_delivered_dialog.html
@@ -2,99 +2,51 @@
 [%- USE HTML %]
 [%- USE LxERP %]
 [%- USE L %]
- [%- IF delivered %]
- [%- SET RO = ' readonly' %]
- [%- END %]
 
- <table>
-  <tr>
-   <td>[% 'Part Number' | $T8 %]</td>
-   <td>[% part.partnumber | html %]</td>
+[%- UNLESS STOCK_INFO.size %]
+<p>[% 'There are no items in stock.' | $T8 %]</p>
+[%- ELSE %]
+
+<p>
+ <table id="stock-in-out-table">
+  <tr class="listheading">
+   <th>&nbsp;</th>
+   <th>[% 'Warehouse' | $T8 %]</th>
+   <th>[% 'Bin' | $T8 %]</th>
+   <th>[% 'Charge Number' | $T8 %]</th>
+   [% IF INSTANCE_CONF.get_show_bestbefore %]
+   <th>[% 'Best Before' | $T8 %]</th>
+   [% END %]
+   <th align="right">[% 'Qty' | $T8 %]</th>
+   <th align="right">[% 'Unit' | $T8 %]</th>
   </tr>
-  <tr>
-   <td>[% 'Description' | $T8 %]</td>
-   <td>[% part.description | html %]</td>
-  </tr>
-  <tr>
-   <td>[% 'Qty according to delivery order' | $T8 %]</td>
-   <td>[% LxERP.format_amount(do_qty) %] [% do_unit | html %]</td>
-  </tr>
- </table>
-
-  [%- UNLESS WHCONTENTS.size %]
-  <p>[% 'There are no items in stock.' | $T8 %]</p>
-  [%- ELSE %]
-
-  [% L.hidden_tag("in_out", in_out) %]
-  [% L.hidden_tag("parts_id", parts_id) %]
-  [% L.hidden_tag("do_qty", do_qty) %]
-  [% L.hidden_tag("do_unit", do_unit) %]
-  [% L.hidden_tag("row", row, class="data-row") %]
-  [% L.hidden_tag("item_id", item_id) %]
-
-  <p>
-   <table id="stock-in-out-table">
-    <tr class="listheading">
-     <th>&nbsp;</th>
-     <th>[% 'Warehouse' | $T8 %]</th>
-     <th>[% 'Bin' | $T8 %]</th>
-     <th>[% 'Charge Number' | $T8 %]</th>
-     [% IF INSTANCE_CONF.get_show_bestbefore %]
-     <th>[% 'Best Before' | $T8 %]</th>
-     [% END %]
-     [%- UNLESS delivered %]
-     <th align="right">[% 'Available qty' | $T8 %]</th>
-     [%- END %]
-     <th align="right">[% 'Qty' | $T8 %]</th>
-     <th align="right">[% 'Unit' | $T8 %]</th>
-    </tr>
-
-    [%- FOREACH row = WHCONTENTS %]
-    <tr [% IF row.stock_error %] class="error"[% ELSE %]class="listrow"[% END %]>
-     <td>[% loop.count %]</td>
-     <td>[% row.warehousedescription | html %]</td>
-     <td>[% row.bindescription | html %]</td>
-     <td>[% row.chargenumber | html %]</td>
-     [% IF INSTANCE_CONF.get_show_bestbefore %]
-     <td>[% row.bestbefore | html %]</td>
-     [% END %]
-
-     [%- IF delivered %]
-
-     <td>[% LxERP.format_amount(row.stock_qty) | html %]</td>
-     <td>
-      [% row.stock_unit | html %]
-      [% L.hidden_tag("unit", row.stock_unit, class="data-unit") %]
-     </td>
-
-     [%- ELSE %]
-
-     <td>[% row.available_qty | html %]</td>
-     <td>
-      [% L.input_tag("qty", row.stock_qty                              ? LxERP.format_amount(row.stock_qty)
-                          : (WHCONTENTS.size == 1) && (!row.stock_qty) ? LxERP.format_amount(do_qty)
-                          : "", class="numeric data-qty", size="12") %]</td>
-     <td>[% L.select_tag("unit_" _ loop.count, part.unit_obj.convertible_units, value_key="name", default=row.stock_unit, class="data-unit") %]</td>
-
-     [%- END %]
-     <td style="display:none">
-      [% L.hidden_tag("warehouse_id", row.warehouse_id, class="data-warehouse-id") %]
-      [% L.hidden_tag("bin_id", row.bin_id, class="data-bin-id") %]
-      [% L.hidden_tag("chargenumber", row.chargenumber, class="data-chargenumber") %]
-      [% L.hidden_tag("delivery_order_items_stock_id", row.delivery_order_items_stock_id, class="data-stock-id") %]
-      [% L.hidden_tag("bestbefore", row.bestbefore, class="data-bestbefore") IF INSTANCE_CONF.get_show_bestbefore %]
-     </td>
-    </tr>
-
-    [%- END %]
-   </table>
-  </p>
-
-  <hr size="3" noshade>
-
-  <p>[% L.button_tag('kivi.DeliveryOrder.save_updated_stock()', LxERP.t8('Save')) IF !delivered %]</p>
 
+  [%- FOREACH row = STOCK_INFO %]
+  <tr [% IF row.stock_error %] class="error"[% ELSE %]class="listrow"[% END %]>
+   <td>[% loop.count %]</td>
+   <td>[% row.warehousedescription | html %]</td>
+   <td>[% row.bindescription | html %]</td>
+   <td>[% row.chargenumber | html %]</td>
+   [% IF INSTANCE_CONF.get_show_bestbefore %]
+   <td>[% row.bestbefore | html %]</td>
+   [% END %]
+
+   <td>[% LxERP.format_amount(row.stock_qty) | html %]</td>
+   <td>
+    [% row.stock_unit | html %]
+    [% L.hidden_tag("unit", row.stock_unit, class="data-unit") %]
+   </td>
+
+   <td style="display:none">
+    [% L.hidden_tag("warehouse_id", row.warehouse_id, class="data-warehouse-id") %]
+    [% L.hidden_tag("bin_id", row.bin_id, class="data-bin-id") %]
+    [% L.hidden_tag("chargenumber", row.chargenumber, class="data-chargenumber") %]
+    [% L.hidden_tag("delivery_order_items_stock_id", row.delivery_order_items_stock_id, class="data-stock-id") %]
+    [% L.hidden_tag("bestbefore", row.bestbefore, class="data-bestbefore") IF INSTANCE_CONF.get_show_bestbefore %]
+   </td>
+  </tr>
   [%- END %]
- </form>
-
-
+ </table>
+</p>
+<hr size="3" noshade>
+[%- END %]
diff --git a/templates/webpages/delivery_order/stock_dialog/_stock_in_new_row.html b/templates/webpages/delivery_order/stock_dialog/_stock_in_new_row.html
new file mode 100644
index 000000000..168308ca7
--- /dev/null
+++ b/templates/webpages/delivery_order/stock_dialog/_stock_in_new_row.html
@@ -0,0 +1,33 @@
+[%- USE L %]
+[%- USE LxERP %]
+[% # L.dump( PART ) %] [% # L.dump( pos ) %] [% # L.dump( remaining_qty ) %]
+<tr class="listrow" >
+ [% L.multi_level_select_tag(
+      "new_wh_bin_" _ pos, WAREHOUSES, 2, surround_tag="td",
+      level_1={
+        name="warehouse_id",
+        value_key="id",
+        title_key="description",
+        default=PART.warehouse_id,
+        class="data-warehouse-id",
+      },
+      level_2={
+        object_key="bins",
+        name="bin_id",
+        value_key="id",
+        title_key="description",
+        default=PART.bin_id,
+        class="data-bin-id",
+      },
+    ) %]
+
+ <td>[% L.input_tag("chargenumber", "", class="numeric data-chargenumber", size="12") %]</td>
+ [%- IF INSTANCE_CONF.get_show_bestbefore %]
+ <td>[% L.date_tag('bestbefore', "", class="data-bestbefore") %]</td>
+ [%- END %]
+ <td>[% L.input_tag("qty", LxERP.format_amount(remaining_qty) , class="numeric data-qty", size="12") %]</td>
+ <td>[% L.select_tag("unit", PART.unit_obj.convertible_units, value_key="name", default=PART.unit, class="data-unit") %]</td>
+ <td style="display:none">
+  [% L.hidden_tag("delivery_order_items_stock_id", '', class="data-stock-id") %]
+ </td>
+</tr>
diff --git a/templates/webpages/delivery_order/stock_dialog/_stock_in_row.html b/templates/webpages/delivery_order/stock_dialog/_stock_in_row.html
new file mode 100644
index 000000000..bb3773a50
--- /dev/null
+++ b/templates/webpages/delivery_order/stock_dialog/_stock_in_row.html
@@ -0,0 +1,34 @@
+[%- USE L %]
+[%- USE LxERP %]
+[% # L.dump( PART ) %] [% # L.dump( pos ) %] [% # L.dump( ROW ) %]
+<tr class="listrow" >
+ [% L.multi_level_select_tag(
+      # name has to be unique
+      "wh_bin_" _ pos, WAREHOUSES, 2, surround_tag="td",
+      level_1={
+        name="warehouse_id",
+        value_key="id",
+        title_key="description",
+        default=ROW.warehouse_id,
+        class="data-warehouse-id",
+      },
+      level_2={
+        object_key="bins",
+        name="bin_id",
+        value_key="id",
+        title_key="description",
+        default=ROW.bin_id,
+        class="data-bin-id",
+      },
+    ) %]
+
+ <td>[% L.input_tag("chargenumber", ROW.chargenumber, class="numeric data-chargenumber", size="12") %]</td>
+ [%- IF INSTANCE_CONF.get_show_bestbefore %]
+ <td>[% L.date_tag("bestbefore", ROW.bestbefore, class="data-bestbefore") %]</td>
+ [%- END %]
+ <td>[% L.input_tag("qty", LxERP.format_amount(ROW.qty), class="numeric data-qty", size="12") %]</td>
+ <td>[% L.select_tag("unit", PART.unit_obj.convertible_units, value_key="name", default=ROW.stock_unit, class="data-unit") %]</td>
+ <td style="display:none">
+  [% L.hidden_tag("delivery_order_items_stock_id", ROW.delivery_order_items_stock_id, class="data-stock-id") %]
+ </td>
+</tr>
diff --git a/templates/webpages/delivery_order/stock_dialog/_stock_in_table.html b/templates/webpages/delivery_order/stock_dialog/_stock_in_table.html
index 02c95e350..9e906f346 100644
--- a/templates/webpages/delivery_order/stock_dialog/_stock_in_table.html
+++ b/templates/webpages/delivery_order/stock_dialog/_stock_in_table.html
@@ -1,60 +1,18 @@
 <tr class="listheading">
  <th>[% 'Warehouse' | $T8 %]</th>
  <th>[% 'Bin' | $T8 %]</th>
+ <th>[% 'Charge Number' | $T8 %]</th>
+ [% IF INSTANCE_CONF.get_show_bestbefore %]
+ <th>[% 'Best Before' | $T8 %]</th>
+ [% END %]
  <th align="right">[% 'Qty' | $T8 %]</th>
  <th align="right">[% 'Unit' | $T8 %]</th>
 </tr>
 
-<tr>
- [% L.multi_level_select_tag(
-      "test_tag", WAREHOUSES, 2, surround_tag="td",
-      level_1={
-        name="warehouse.id",
-        value_key="id",
-        title_key="description",
-      },
-      level_2={
-        object_key="bins",
-        name="bin.id",
-        value_key="id",
-        title_key="description",
-      },
-    ) %]
+[%- FOREACH row = STOCK_INFO %]
+[%- PROCESS delivery_order/stock_dialog/_stock_in_row.html PART=part ROW=row pos=loop.count %]
+[%- END %]
 
- <td>
-  [% L.input_tag("qty", LxERP.format_amount(do_qty), class="numeric data-qty", size="12") %]</td>
- <td>[% L.select_tag("unit_" _ loop.count, part.unit_obj.convertible_units, value_key="name", default=row.stock_unit, class="data-unit") %]</td>
-
- <td style="display:none">
-  [% L.hidden_tag("warehouse_id", row.warehouse_id, class="data-warehouse-id") %]
-  [% L.hidden_tag("bin_id", row.bin_id, class="data-bin-id") %]
-  [% L.hidden_tag("chargenumber", row.chargenumber, class="data-chargenumber") %]
-  [% L.hidden_tag("delivery_order_items_stock_id", row.delivery_order_items_stock_id, class="data-stock-id") %]
-  [% L.hidden_tag("bestbefore", row.bestbefore, class="data-bestbefore") IF INSTANCE_CONF.get_show_bestbefore %]
- </td>
-</tr>
-<tr>
-  [% L.multi_level_select_tag("multi_select_foo_bar_foobar", COLLECTION, 3,
-      surround_tag="td",
-      level_1={
-        name="foo.id",
-        value_key="id",
-        title_key="description",
-        default="2",
-      },
-      level_2={
-        object_key="key_1",
-        name="bar.id",
-        value_key="id",
-        title_key="description",
-        default="1",
-      },
-      level_3={
-        object_key="key_2",
-        name="foobar.id",
-        value_key="id",
-        title_key="value",
-        default="4",
-      },
-    ) %]
-</tr>
+[%- UNLESS STOCK_INFO.size %]
+[%- PROCESS delivery_order/stock_dialog/_stock_in_new_row.html PART=part remaining_qty=do_qty pos=0 %]
+[% END %]
diff --git a/templates/webpages/delivery_order/stock_dialog/_stock_info_table.html b/templates/webpages/delivery_order/stock_dialog/_stock_info_table.html
index e24e8d95c..ce32a93b2 100644
--- a/templates/webpages/delivery_order/stock_dialog/_stock_info_table.html
+++ b/templates/webpages/delivery_order/stock_dialog/_stock_info_table.html
@@ -10,7 +10,7 @@
 </tr>
 
 [%- FOREACH row = WHCONTENTS %]
-<tr [% IF row.stock_error %] class="error"[% ELSE %]class="listrow"[% END %]>
+<tr [% IF row.stock_error %] class="error" [% END %]>
  <td>[% loop.count %]</td>
  <td>[% row.warehousedescription | html %]</td>
  <td>[% row.bindescription | html %]</td>
diff --git a/templates/webpages/delivery_order/stock_dialog/_stock_out_table.html b/templates/webpages/delivery_order/stock_dialog/_stock_out_table.html
index f4935cf4f..a2e2342af 100644
--- a/templates/webpages/delivery_order/stock_dialog/_stock_out_table.html
+++ b/templates/webpages/delivery_order/stock_dialog/_stock_out_table.html
@@ -2,99 +2,43 @@
 [%- USE HTML %]
 [%- USE LxERP %]
 [%- USE L %]
- [%- IF delivered %]
- [%- SET RO = ' readonly' %]
- [%- END %]
-
- <table>
-  <tr>
-   <td>[% 'Part Number' | $T8 %]</td>
-   <td>[% part.partnumber | html %]</td>
-  </tr>
-  <tr>
-   <td>[% 'Description' | $T8 %]</td>
-   <td>[% part.description | html %]</td>
-  </tr>
-  <tr>
-   <td>[% 'Qty according to delivery order' | $T8 %]</td>
-   <td>[% LxERP.format_amount(do_qty) %] [% do_unit | html %]</td>
-  </tr>
- </table>
-
-  [%- UNLESS WHCONTENTS.size %]
-  <p>[% 'There are no items in stock.' | $T8 %]</p>
-  [%- ELSE %]
-
-  [% L.hidden_tag("in_out", in_out) %]
-  [% L.hidden_tag("parts_id", parts_id) %]
-  [% L.hidden_tag("do_qty", do_qty) %]
-  [% L.hidden_tag("do_unit", do_unit) %]
-  [% L.hidden_tag("row", row, class="data-row") %]
-  [% L.hidden_tag("item_id", item_id) %]
-
-  <p>
-   <table id="stock-in-out-table">
-    <tr class="listheading">
-     <th>&nbsp;</th>
-     <th>[% 'Warehouse' | $T8 %]</th>
-     <th>[% 'Bin' | $T8 %]</th>
-     <th>[% 'Charge Number' | $T8 %]</th>
-     [% IF INSTANCE_CONF.get_show_bestbefore %]
-     <th>[% 'Best Before' | $T8 %]</th>
-     [% END %]
-     [%- UNLESS delivered %]
-     <th align="right">[% 'Available qty' | $T8 %]</th>
-     [%- END %]
-     <th align="right">[% 'Qty' | $T8 %]</th>
-     <th align="right">[% 'Unit' | $T8 %]</th>
-    </tr>
-
-    [%- FOREACH row = WHCONTENTS %]
-    <tr [% IF row.stock_error %] class="error"[% ELSE %]class="listrow"[% END %]>
-     <td>[% loop.count %]</td>
-     <td>[% row.warehousedescription | html %]</td>
-     <td>[% row.bindescription | html %]</td>
-     <td>[% row.chargenumber | html %]</td>
-     [% IF INSTANCE_CONF.get_show_bestbefore %]
-     <td>[% row.bestbefore | html %]</td>
-     [% END %]
-
-     [%- IF delivered %]
-
-     <td>[% LxERP.format_amount(row.stock_qty) | html %]</td>
-     <td>
-      [% row.stock_unit | html %]
-      [% L.hidden_tag("unit", row.stock_unit, class="data-unit") %]
-     </td>
-
-     [%- ELSE %]
-
-     <td>[% row.available_qty | html %]</td>
-     <td>
-      [% L.input_tag("qty", row.stock_qty                              ? LxERP.format_amount(row.stock_qty)
-                          : (WHCONTENTS.size == 1) && (!row.stock_qty) ? LxERP.format_amount(do_qty)
-                          : "", class="numeric data-qty", size="12") %]</td>
-     <td>[% L.select_tag("unit_" _ loop.count, part.unit_obj.convertible_units, value_key="name", default=row.stock_unit, class="data-unit") %]</td>
-
-     [%- END %]
-     <td style="display:none">
-      [% L.hidden_tag("warehouse_id", row.warehouse_id, class="data-warehouse-id") %]
-      [% L.hidden_tag("bin_id", row.bin_id, class="data-bin-id") %]
-      [% L.hidden_tag("chargenumber", row.chargenumber, class="data-chargenumber") %]
-      [% L.hidden_tag("delivery_order_items_stock_id", row.delivery_order_items_stock_id, class="data-stock-id") %]
-      [% L.hidden_tag("bestbefore", row.bestbefore, class="data-bestbefore") IF INSTANCE_CONF.get_show_bestbefore %]
-     </td>
-    </tr>
-
-    [%- END %]
-   </table>
-  </p>
-
-  <hr size="3" noshade>
-
-  <p>[% L.button_tag('kivi.DeliveryOrder.save_updated_stock()', LxERP.t8('Save')) IF !delivered %]</p>
-
-  [%- END %]
- </form>
-
 
+<tr class="listheading">
+ <th>&nbsp;</th>
+ <th>[% 'Warehouse' | $T8 %]</th>
+ <th>[% 'Bin' | $T8 %]</th>
+ <th>[% 'Charge Number' | $T8 %]</th>
+ [% IF INSTANCE_CONF.get_show_bestbefore %]
+ <th>[% 'Best Before' | $T8 %]</th>
+ [% END %]
+ <th align="right">[% 'Available qty' | $T8 %]</th>
+ <th align="right">[% 'Qty' | $T8 %]</th>
+ <th align="right">[% 'Unit' | $T8 %]</th>
+</tr>
+
+[%- FOREACH row = WHCONTENTS %]
+<tr [% IF row.stock_error %] class="error"[% ELSE %]class="listrow"[% END %]>
+ <td>[% loop.count %]</td>
+ <td>[% row.warehousedescription | html %]</td>
+ <td>[% row.bindescription | html %]</td>
+ <td>[% row.chargenumber | html %]</td>
+ [% IF INSTANCE_CONF.get_show_bestbefore %]
+ <td>[% row.bestbefore | html %]</td>
+ [% END %]
+
+ <td>[% row.available_qty | html %]</td>
+ <td>
+  [% L.input_tag("qty", row.stock_qty                              ? LxERP.format_amount(row.stock_qty)
+                      : (WHCONTENTS.size == 1) && (!row.stock_qty) ? LxERP.format_amount(do_qty)
+                      : "", class="numeric data-qty", size="12") %]</td>
+ <td>[% L.select_tag("unit_" _ loop.count, part.unit_obj.convertible_units, value_key="name", default=row.stock_unit, class="data-unit") %]</td>
+
+ <td style="display:none">
+  [% L.hidden_tag("warehouse_id", row.warehouse_id, class="data-warehouse-id") %]
+  [% L.hidden_tag("bin_id", row.bin_id, class="data-bin-id") %]
+  [% L.hidden_tag("chargenumber", row.chargenumber, class="data-chargenumber") %]
+  [% L.hidden_tag("delivery_order_items_stock_id", row.delivery_order_items_stock_id, class="data-stock-id") %]
+  [% L.hidden_tag("bestbefore", row.bestbefore, class="data-bestbefore") IF INSTANCE_CONF.get_show_bestbefore %]
+ </td>
+</tr>
+[%- END %]
