Lagerverwaltung implementiert.
authorMoritz Bunkus <m.bunkus@linet-services.de>
Fri, 18 Jan 2008 14:13:35 +0000 (14:13 +0000)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Fri, 18 Jan 2008 14:13:35 +0000 (14:13 +0000)
74 files changed:
SL/AM.pm
SL/Auth.pm
SL/IC.pm
SL/IR.pm
SL/IS.pm
SL/LICENSES.pm
SL/OE.pm
SL/WH.pm [new file with mode: 0644]
bin/mozilla/am.pl
bin/mozilla/common.pl
bin/mozilla/wh.pl [new file with mode: 0644]
js/part_selection.js [new file with mode: 0644]
locale/de/admin
locale/de/all
locale/de/am
locale/de/amcvar
locale/de/amtemplates
locale/de/ap
locale/de/ar
locale/de/arap
locale/de/bp
locale/de/ca
locale/de/common
locale/de/cp
locale/de/ct
locale/de/datev
locale/de/dn
locale/de/drafts
locale/de/fu
locale/de/gl
locale/de/ic
locale/de/io
locale/de/ir
locale/de/is
locale/de/licenses
locale/de/login
locale/de/menu
locale/de/menuXML
locale/de/menunew
locale/de/menuv3
locale/de/oe
locale/de/pe
locale/de/rc
locale/de/reportgenerator
locale/de/rp
locale/de/todo
locale/de/ustva
locale/de/wh [new file with mode: 0644]
menu.ini
sql/Pg-upgrade2/warehouse.sql [new file with mode: 0644]
templates/webpages/am/confirm_delete_warehouse_de.html [new file with mode: 0644]
templates/webpages/am/confirm_delete_warehouse_master.html [new file with mode: 0644]
templates/webpages/am/edit_warehouse_de.html [new file with mode: 0644]
templates/webpages/am/edit_warehouse_master.html [new file with mode: 0644]
templates/webpages/am/list_warehouses_de.html [new file with mode: 0644]
templates/webpages/am/list_warehouses_master.html [new file with mode: 0644]
templates/webpages/generic/part_selection_de.html [new file with mode: 0644]
templates/webpages/generic/part_selection_master.html [new file with mode: 0644]
templates/webpages/generic/select_part_de.html [new file with mode: 0644]
templates/webpages/generic/select_part_master.html [new file with mode: 0644]
templates/webpages/ic/form_header_de.html
templates/webpages/wh/journal_filter_de.html [new file with mode: 0644]
templates/webpages/wh/journal_filter_master.html [new file with mode: 0644]
templates/webpages/wh/removal_parts_selection_de.html [new file with mode: 0644]
templates/webpages/wh/removal_parts_selection_master.html [new file with mode: 0644]
templates/webpages/wh/report_filter_de.html [new file with mode: 0644]
templates/webpages/wh/report_filter_master.html [new file with mode: 0644]
templates/webpages/wh/transfer_parts_selection_de.html [new file with mode: 0644]
templates/webpages/wh/transfer_parts_selection_master.html [new file with mode: 0644]
templates/webpages/wh/warehouse_selection_de.html [new file with mode: 0644]
templates/webpages/wh/warehouse_selection_master.html [new file with mode: 0644]
templates/webpages/wh/warehouse_selection_stock_de.html [new file with mode: 0644]
templates/webpages/wh/warehouse_selection_stock_master.html [new file with mode: 0644]
wh.pl [new symlink]

index f788813..97e5896 100644 (file)
--- a/SL/AM.pm
+++ b/SL/AM.pm
@@ -2407,5 +2407,154 @@ sub delete_price_factor {
   $main::lxdebug->leave_sub();
 }
 
+sub save_warehouse {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->get_standard_dbh($myconfig);
+
+  my ($query, @values, $sth);
+
+  if (!$form->{id}) {
+    $query        = qq|SELECT nextval('id')|;
+    ($form->{id}) = selectrow_query($form, $dbh, $query);
+
+    $query        = qq|INSERT INTO warehouse (id, sortkey) VALUES (?, (SELECT COALESCE(MAX(sortkey), 0) + 1 FROM warehouse))|;
+    do_query($form, $dbh, $query, $form->{id});
+  }
+
+  do_query($form, $dbh, qq|UPDATE warehouse SET description = ?, invalid = ? WHERE id = ?|,
+           $form->{description}, $form->{invalid} ? 't' : 'f', conv_i($form->{id}));
+
+  if (0 < $form->{number_of_new_bins}) {
+    $query = qq|INSERT INTO bin (warehouse_id, description) VALUES (?, ?)|;
+    $sth   = prepare_query($form, $dbh, $query);
+
+    foreach my $i (1..$form->{number_of_new_bins}) {
+      do_statement($form, $sth, $query, conv_i($form->{id}), "$form->{prefix}${i}");
+    }
+
+    $sth->finish();
+  }
+
+  $dbh->commit();
+
+  $main::lxdebug->leave_sub();
+}
+
+sub save_bins {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->get_standard_dbh($myconfig);
+
+  my ($query, @values, $commit_necessary, $sth);
+
+  @values = map { $form->{"id_${_}"} } grep { $form->{"delete_${_}"} } (1..$form->{rowcount});
+
+  if (@values) {
+    $query = qq|DELETE FROM bin WHERE id IN (| . join(', ', ('?') x scalar(@values)) . qq|)|;
+    do_query($form, $dbh, $query, @values);
+
+    $commit_necessary = 1;
+  }
+
+  $query = qq|UPDATE bin SET description = ? WHERE id = ?|;
+  $sth   = prepare_query($form, $dbh, $query);
+
+  foreach my $row (1..$form->{rowcount}) {
+    next if ($form->{"delete_${row}"});
+
+    do_statement($form, $sth, $query, $form->{"description_${row}"}, conv_i($form->{"id_${row}"}));
+
+    $commit_necessary = 1;
+  }
+
+  $sth->finish();
+
+  $dbh->commit() if ($commit_necessary);
+
+  $main::lxdebug->leave_sub();
+}
+
+sub delete_warehouse {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->get_standard_dbh($myconfig);
+
+  my $id      = conv_i($form->{id});
+  my $query   = qq|SELECT i.bin_id FROM inventory i WHERE i.bin_id IN (SELECT b.id FROM bin b WHERE b.warehouse_id = ?) LIMIT 1|;
+  my ($count) = selectrow_query($form, $dbh, $query, $id);
+
+  if ($count) {
+    $main::lxdebug->leave_sub();
+    return 0;
+  }
+
+  do_query($form, $dbh, qq|DELETE FROM warehouse_access WHERE warehouse_id = ?|, conv_i($form->{id}));
+  do_query($form, $dbh, qq|DELETE FROM bin              WHERE warehouse_id = ?|, conv_i($form->{id}));
+  do_query($form, $dbh, qq|DELETE FROM warehouse        WHERE id           = ?|, conv_i($form->{id}));
+
+  $dbh->commit();
+
+  $main::lxdebug->leave_sub();
+
+  return 1;
+}
+
+sub get_all_warehouses {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->get_standard_dbh($myconfig);
+
+  my $query = qq|SELECT w.id, w.description, w.invalid
+                 FROM warehouse w
+                 ORDER BY w.sortkey|;
+
+  $form->{WAREHOUSES} = selectall_hashref_query($form, $dbh, $query);
+
+  $main::lxdebug->leave_sub();
+}
+
+sub get_warehouse {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->get_standard_dbh($myconfig);
+
+  my $id    = conv_i($form->{id});
+  my $query = qq|SELECT w.description, w.invalid
+                 FROM warehouse w
+                 WHERE w.id = ?|;
+
+  my $ref   = selectfirst_hashref_query($form, $dbh, $query, $id, $id);
+
+  map { $form->{$_} = $ref->{$_} } keys %{ $ref };
+
+  $query = qq|SELECT b.*, EXISTS
+                (SELECT i.warehouse_id
+                 FROM inventory i
+                 WHERE i.bin_id = b.id
+                 LIMIT 1)
+                AS in_use
+              FROM bin b
+              WHERE b.warehouse_id = ?|;
+
+  $form->{BINS} = selectall_hashref_query($form, $dbh, $query, conv_i($form->{id}));
+
+  $main::lxdebug->leave_sub();
+}
 
 1;
index 98f1994..8ac2293 100644 (file)
@@ -636,6 +636,9 @@ sub all_rights_full {
     ["purchase_order_edit",            $locale->text("Create and edit purchase orders")],
     ["purchase_delivery_order_edit",   $locale->text("Create and edit purchase delivery orders")],
     ["vendor_invoice_edit",            $locale->text("Create and edit vendor invoices")],
+    ["--warehouse_management",         $locale->text("Warehouse management")],
+    ["warehouse_contents",             $locale->text("View warehouse content")],
+    ["warehouse_management",           $locale->text("Warehouse management")],
     ["--general_ledger_cash",          $locale->text("General ledger and cash")],
     ["general_ledger",                 $locale->text("Transactions, AR transactions, AP transactions")],
     ["datev_export",                   $locale->text("DATEV Export")],
index a05c85e..704c213 100644 (file)
--- a/SL/IC.pm
+++ b/SL/IC.pm
@@ -325,14 +325,8 @@ sub save {
     }
 
     if ($form->{item} eq 'assembly') {
-      if ($form->{onhand} != 0) {
-        &adjust_inventory($dbh, $form, $form->{id}, $form->{onhand} * -1);
-      }
-
       # delete assembly records
       do_query($form, $dbh, qq|DELETE FROM assembly WHERE id = ?|, conv_i($form->{id}));
-
-      $form->{onhand} += $form->{stock};
     }
 
     # delete tax records
@@ -352,7 +346,6 @@ sub save {
     do_query($form, $dbh, qq|INSERT INTO parts (id, partnumber) VALUES (?, '')|, $form->{id});
 
     $form->{orphaned} = 1;
-    $form->{onhand} = $form->{stock} if $form->{item} eq 'assembly';
     if ($form->{partnumber} eq "" && $form->{"item"} eq "service") {
       $form->{partnumber} = $form->update_defaults($myconfig, "servicenumber");
     }
@@ -532,11 +525,6 @@ sub save {
       }
     }
 
-    # adjust onhand for the parts
-    if ($form->{onhand} != 0) {
-      &adjust_inventory($dbh, $form, $form->{id}, $form->{onhand});
-    }
-
     @a = localtime;
     $a[5] += 1900;
     $a[4]++;
@@ -544,13 +532,6 @@ sub save {
 
     $form->get_employee($dbh);
 
-    # add inventory record
-    $query =
-      qq|INSERT INTO inventory (warehouse_id, parts_id, qty, shippingdate, employee_id)
-         VALUES (0, ?, ?, '$shippingdate', ?)|;
-    @values = (conv_i($form->{id}), $form->{stock}, conv_i($form->{employee_id}));
-    do_query($form, $dbh, $query, @values);
-
   }
 
   #set expense_accno=inventory_accno if they are different => bilanz
@@ -650,67 +631,6 @@ sub retrieve_assemblies {
   $main::lxdebug->leave_sub();
 }
 
-sub restock_assemblies {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-
-  # connect to database
-  my $dbh = $form->dbconnect_noauto($myconfig);
-
-  for my $i (1 .. $form->{rowcount}) {
-
-    $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
-
-    if ($form->{"qty_$i"} != 0) {
-      &adjust_inventory($dbh, $form, $form->{"id_$i"}, $form->{"qty_$i"});
-    }
-
-  }
-
-  my $rc = $dbh->commit;
-  $dbh->disconnect;
-
-  $main::lxdebug->leave_sub();
-
-  return $rc;
-}
-
-sub adjust_inventory {
-  $main::lxdebug->enter_sub();
-
-  my ($dbh, $form, $id, $qty) = @_;
-
-  my $query =
-    qq|SELECT p.id, p.inventory_accno_id, p.assembly, a.qty
-       FROM parts p, assembly a
-       WHERE (a.parts_id = p.id) AND (a.id = ?)|;
-  my $sth = prepare_execute_query($form, $dbh, $query, conv_i($id));
-
-  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
-
-    my $allocate = $qty * $ref->{qty};
-
-    # is it a service item, then loop
-    $ref->{inventory_accno_id} *= 1;
-    next if (($ref->{inventory_accno_id} == 0) && !$ref->{assembly});
-
-    # adjust parts onhand
-    $form->update_balance($dbh, "parts", "onhand",
-                          qq|id = $ref->{id}|,
-                          $allocate * -1);
-  }
-
-  $sth->finish;
-
-  # update assembly
-  my $rc = $form->update_balance($dbh, "parts", "onhand", qq|id = ?|, $qty, $id);
-
-  $main::lxdebug->leave_sub();
-
-  return $rc;
-}
-
 sub delete {
   $main::lxdebug->enter_sub();
 
@@ -1014,6 +934,8 @@ sub all_parts {
 
   $form->{parts} = selectall_hashref_query($form, $dbh, $query, @bind_vars);
 
+  map { $_->{onhand} *= 1 } @{ $form->{parts} };
+
 ##  my $where = qq|1 = 1|;
 ##  my (@values, $var, $flds, $group, $limit);
 ##
index 8fa92e6..30f49fd 100644 (file)
--- a/SL/IR.pm
+++ b/SL/IR.pm
@@ -178,8 +178,6 @@ sub post_invoice {
       @values = ($form->{"sellprice_$i"}, conv_i($form->{"id_$i"}));
       do_query($form, $dbh, $query, @values);
 
-      $form->update_balance($dbh, "parts", "onhand", qq|id = ?|, $baseqty, $form->{"id_$i"}) if !$form->{shipped};
-
       # check if we sold the item already and
       # make an entry for the expense and inventory
       $query =
@@ -572,9 +570,6 @@ sub reverse_invoice {
 
     next unless $ref->{inventory_accno_id};
 
-    # update onhand
-    $form->update_balance($dbh, "parts", "onhand", qq|id = $ref->{parts_id}|, $ref->{qty});
-
     # if $ref->{allocated} > 0 than we sold that many items
     next if ($ref->{allocated} <= 0);
 
@@ -1057,6 +1052,8 @@ sub retrieve_item {
     $stw->finish();
     chop $ref->{taxaccounts};
 
+    $ref->{onhand} *= 1;
+
     push @{ $form->{item_list} }, $ref;
 
   }
index 367c861..77d11d1 100644 (file)
--- a/SL/IS.pm
+++ b/SL/IS.pm
@@ -645,32 +645,10 @@ sub post_invoice {
 
       if ($form->{"inventory_accno_$i"} || $form->{"assembly_$i"}) {
 
-        # adjust parts onhand quantity
-
         if ($form->{"assembly_$i"}) {
-
-          # do not update if assembly consists of all services
-          $query =
-            qq|SELECT sum(p.inventory_accno_id)
-               FROM parts p
-               JOIN assembly a ON (a.parts_id = p.id)
-               WHERE a.id = ?|;
-          $sth = prepare_execute_query($form, $dbh, $query, conv_i($form->{"id_$i"}));
-
-          if ($sth->fetchrow_array) {
-            $form->update_balance($dbh, "parts", "onhand", qq|id = ?|,
-                                  $baseqty * -1, $form->{"id_$i"})
-              unless $form->{shipped};
-          }
-          $sth->finish;
-
           # record assembly item as allocated
           &process_assembly($dbh, $form, $form->{"id_$i"}, $baseqty);
         } else {
-          $form->update_balance($dbh, "parts", "onhand", qq|id = ?|,
-                                $baseqty * -1, $form->{"id_$i"})
-            unless $form->{shipped};
-
           $allocated = &cogs($dbh, $form, $form->{"id_$i"}, $baseqty, $basefactor, $i);
         }
       }
@@ -1236,18 +1214,7 @@ sub reverse_invoice {
 
   while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
 
-    if ($ref->{inventory_accno_id} || $ref->{assembly}) {
-
-      # if the invoice item is not an assemblyitem adjust parts onhand
-      if (!$ref->{assemblyitem}) {
-
-        # adjust onhand in parts table
-        $form->update_balance($dbh, "parts", "onhand", qq|id = $ref->{parts_id}|, $ref->{qty});
-      }
-
-      # loop if it is an assembly
-      next if ($ref->{assembly});
-
+    if ($ref->{inventory_accno_id}) {
       # de-allocated purchases
       $query =
         qq|SELECT i.id, i.trans_id, i.allocated
@@ -1825,6 +1792,8 @@ sub retrieve_item {
       }
     }
 
+    $ref->{onhand} *= 1;
+
     push @{ $form->{item_list} }, $ref;
 
     if ($form->{lizenzen}) {
index 7d5f4ba..8f9c025 100644 (file)
@@ -68,11 +68,6 @@ sub save_license {
   $sth->execute || $form->dberror($query);
   $sth->finish();
 
-  if ($form->{own_product}) {
-    $form->update_balance($dbh, "parts", "onhand", qq|id = ?|,
-                          1, $form->{parts_id});
-  }
-
   $dbh->disconnect();
 
   $main::lxdebug->leave_sub();
index 2574afa..f9d5dab 100644 (file)
--- a/SL/OE.pm
+++ b/SL/OE.pm
@@ -242,8 +242,6 @@ sub save {
 
   if ($form->{id}) {
 
-    &adj_onhand($dbh, $form, $ml) if $form->{type} =~ /_order$/;
-
     $query = qq|DELETE FROM orderitems WHERE trans_id = ?|;
     do_query($form, $dbh, $query, $form->{id});
 
@@ -382,7 +380,7 @@ sub save {
       }
       $query .= qq|?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
                    (SELECT factor FROM price_factors WHERE id = ?), ?)|;
-        push(@values,
+      push(@values,
            conv_i($form->{id}), conv_i($form->{"id_$i"}),
            $form->{"description_$i"}, $form->{"longdescription_$i"},
            $form->{"qty_$i"}, $baseqty,
@@ -476,12 +474,6 @@ sub save {
     }
   }
 
-  if ($form->{type} =~ /_order$/) {
-
-    # adjust onhand
-    &adj_onhand($dbh, $form, $ml * -1);
-  }
-
   $form->{saved_xyznumber} = $form->{$form->{type} =~ /_quotation$/ ?
                                        "quonumber" : "ordnumber"};
 
@@ -556,25 +548,9 @@ sub delete {
   }
   $sth->finish;
 
-  $query = qq|SELECT o.parts_id, o.ship FROM orderitems o | .
-           qq|WHERE o.trans_id = ?|;
-  @values = (conv_i($form->{id}));
-  $sth = $dbh->prepare($query);
-  $sth->execute(@values) || $self->dberror($query);
-
-  while (my ($id, $ship) = $sth->fetchrow_array) {
-    $form->update_balance($dbh, "parts", "onhand", qq|id = $id|, $ship * -1);
-  }
-  $sth->finish;
-
   # delete-values
   @values = (conv_i($form->{id}));
 
-  # delete inventory
-  $query = qq|DELETE FROM inventory | .
-           qq|WHERE oe_id = ?|;
-  do_query($form, $dbh, $query, @values);
-
   # delete status entries
   $query = qq|DELETE FROM status | .
            qq|WHERE trans_id = ?|;
@@ -1153,63 +1129,4 @@ sub project_description {
   return $value;
 }
 
-sub adj_onhand {
-  $main::lxdebug->enter_sub();
-
-  my ($dbh, $form, $ml) = @_;
-
-  my $all_units = $form->{all_units};
-
-  my $query =
-    qq|SELECT oi.parts_id, oi.ship, oi.unit, p.inventory_accno_id, p.assembly | .
-    qq|   FROM orderitems oi | .
-    qq|   JOIN parts p ON (p.id = oi.parts_id) | .
-    qq|   WHERE oi.trans_id = ?|;
-  my @values = ($form->{id});
-  my $sth = $dbh->prepare($query);
-  $sth->execute(@values) || $form->dberror($query);
-
-  $query =
-    qq|SELECT sum(p.inventory_accno_id) | .
-    qq|FROM parts p | .
-    qq|JOIN assembly a ON (a.parts_id = p.id) | .
-    qq|WHERE a.id = ?|;
-  my $ath = $dbh->prepare($query) || $form->dberror($query);
-
-  my $ispa;
-
-  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
-    if ($ref->{inventory_accno_id} || $ref->{assembly}) {
-
-      # do not update if assembly consists of all services
-      if ($ref->{assembly}) {
-        $ath->execute($ref->{parts_id}) || $form->dberror($query);
-
-        ($ispa) = $sth->fetchrow_array;
-        $ath->finish;
-
-        next unless $ispa;
-
-      }
-
-      # get item baseunit
-      $query = qq|SELECT unit FROM parts WHERE id = ?|;
-      my ($item_unit) = selectrow_query($form, $dbh, $query, $ref->{parts_id});
-
-      my $basefactor = 1;
-      if (defined($all_units->{$item_unit}->{factor}) && (($all_units->{$item_unit}->{factor} * 1) != 0)) {
-        $basefactor = $all_units->{$ref->{unit}}->{factor} / $all_units->{$item_unit}->{factor};
-      }
-      my $baseqty = $ref->{ship} * $basefactor;
-
-      # adjust onhand in parts table
-      $form->update_balance($dbh, "parts", "onhand", qq|id = $ref->{parts_id}|, $baseqty * $ml);
-    }
-  }
-
-  $sth->finish;
-
-  $main::lxdebug->leave_sub();
-}
-
 1;
diff --git a/SL/WH.pm b/SL/WH.pm
new file mode 100644 (file)
index 0000000..00220f2
--- /dev/null
+++ b/SL/WH.pm
@@ -0,0 +1,600 @@
+#====================================================================
+# LX-Office ERP
+# Copyright (C) 2004
+# Based on SQL-Ledger Version 2.1.9
+# Web http://www.lx-office.org
+#
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 1999-2003
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+#  Warehouse module
+#
+#======================================================================
+
+package WH;
+
+use SL::AM;
+use SL::DBUtils;
+use SL::Form;
+
+sub transfer {
+  $main::lxdebug->enter_sub();
+
+  my $self = shift;
+
+  if (!@_) {
+    $main::lxdebug->leave_sub();
+    return;
+  }
+
+  my $myconfig = \%main::myconfig;
+  my $form     = $main::form;
+
+  my $dbh      = $form->get_standard_dbh($myconfig);
+
+  my $units    = AM->retrieve_units($myconfig, $form);
+
+  my $query    = qq|SELECT * FROM transfer_type|;
+  my $sth      = prepare_execute_query($form, $dbh, $query);
+
+  my %transfer_types;
+
+  while (my $ref = $sth->fetchrow_hashref()) {
+    $transfer_types{$ref->{direction}} ||= { };
+    $transfer_types{$ref->{direction}}->{$ref->{description}} = $ref->{id};
+  }
+
+  my @part_ids  = map { $_->{parts_id} } @_;
+  my %partunits = selectall_as_map($form, $dbh, qq|SELECT id, unit FROM parts WHERE id IN (| . join(', ', map { '?' } @part_ids ) . qq|)|, 'id', 'unit', @part_ids);
+
+  my ($now)     = selectrow_query($form, $dbh, qq|SELECT current_date|);
+
+  $query = qq|INSERT INTO inventory (warehouse_id, bin_id, parts_id, chargenumber, oe_id, orderitems_id, shippingdate,
+                                     employee_id, project_id, trans_id, trans_type_id, comment, qty)
+              VALUES (?, ?, ?, ?, ?, ?, ?, (SELECT id FROM employee WHERE login = ?), ?, ?, ?, ?, ?)|;
+
+  $sth   = prepare_query($form, $dbh, $query);
+
+  my @directions = (undef, 'out', 'in', 'transfer');
+
+  while (@_) {
+    my $transfer   = shift;
+    my ($trans_id) = selectrow_query($form, $dbh, qq|SELECT nextval('id')|);
+
+    my ($direction, @values) = (0);
+
+    $direction |= 1 if ($transfer->{src_warehouse_id} && $transfer->{src_bin_id});
+    $direction |= 2 if ($transfer->{dst_warehouse_id} && $transfer->{dst_bin_id});
+
+    push @values, conv_i($transfer->{parts_id}), "$transfer->{chargenumber}", conv_i($transfer->{oe_id}), conv_i($transfer->{orderitems_id});
+    push @values, $transfer->{shippingdate} eq 'current_date' ? $now : conv_date($transfer->{shippingdate}), $form->{login}, conv_i($transfer->{project_id}), $trans_id;
+
+    if ($transfer->{transfer_type_id}) {
+      push @values, $transfer->{transfer_type_id};
+    } else {
+      push @values, $transfer_types{$directions[$direction]}->{$transfer->{transfer_type}};
+    }
+
+    push @values, "$transfer->{comment}";
+
+    $qty = $transfer->{qty};
+
+    if ($transfer->{unit}) {
+      my $partunit = $partunits{$transfer->{parts_id}};
+
+      $qty *= $units->{$transfer->{unit}}->{factor};
+      $qty /= $units->{$partunit}->{factor} || 1 if ($partunit);
+    }
+
+    if ($direction & 1) {
+      do_statement($form, $sth, $query, conv_i($transfer->{src_warehouse_id}), conv_i($transfer->{src_bin_id}), @values, $qty * -1);
+    }
+
+    if ($direction & 2) {
+      do_statement($form, $sth, $query, conv_i($transfer->{dst_warehouse_id}), conv_i($transfer->{dst_bin_id}), @values, $qty);
+    }
+  }
+
+  $sth->finish();
+
+  $dbh->commit();
+
+  $main::lxdebug->leave_sub();
+}
+
+sub get_warehouse_journal {
+  $main::lxdebug->enter_sub();
+
+  my $self      = shift;
+  my %filter    = @_;
+
+  my $myconfig  = \%main::myconfig;
+  my $form      = $main::form;
+
+  my $all_units = AM->retrieve_units($myconfig, $form);
+
+  # connect to database
+  my $dbh = $form->get_standard_dbh($myconfig);
+
+  # filters
+  my (@filter_ary, @filter_vars, $joins);
+
+  if ($filter{warehouse_id} ne '') {
+    push @filter_ary, "w1.id = ? OR w2.id = ?";
+    push @filter_vars, $filter{warehouse_id}, $filter{warehouse_id};
+  }
+
+  if ($filter{bin_id} ne '') {
+    push @filter_ary, "b1.id = ? OR b2.id = ?";
+    push @filter_vars, $filter{bin_id}, $filter{bin_id};
+  }
+
+  if ($filter{partnumber}) {
+    push @filter_ary, "p.partnumber ILIKE ?";
+    push @filter_vars, '%' . $filter{partnumber} . '%';
+  }
+
+  if ($filter{description}) {
+    push @filter_ary, "(p.description ILIKE ?)";
+    push @filter_vars, '%' . $filter{description} . '%';
+  }
+
+  if ($filter{chargenumber}) {
+    push @filter_ary, "w1.chargenumber ILIKE ?";
+    push @filter_vars, '%' . $filter{chargenumber} . '%';
+  }
+
+  if ($form->{fromdate}) {
+    push @filter_ary, "?::DATE <= i1.itime::DATE";
+    push @filter_vars, $form->{fromdate};
+  }
+
+  if ($form->{todate}) {
+    push @filter_ary, "?::DATE >= i1.itime::DATE";
+    push @filter_vars, $form->{todate};
+  }
+
+  if ($form->{l_employee}) {
+    $joins .= "";
+  }
+
+  # prepare qty comparison for later filtering
+  my ($f_qty_op, $f_qty, $f_qty_base_unit);
+  if ($filter{qty_op} && defined($filter{qty}) && $filter{qty_unit} && $all_units->{$filter{qty_unit}}) {
+    $f_qty_op        = $filter{qty_op};
+    $f_qty           = $filter{qty} * $all_units->{$filter{qty_unit}}->{factor};
+    $f_qty_base_unit = $all_units->{$filter{qty_unit}}->{base_unit};
+  }
+
+  map { $_ = "(${_})"; } @filter_ary;
+
+  # if of a property number or description is requested,
+  # automatically check the matching id too.
+  map { $form->{"l_${_}id"} = "Y" if ($form->{"l_${_}description"} || $form->{"l_${_}number"}); } qw(warehouse bin);
+
+  # customize shown entry for not available fields.
+  $filter{na} = '-' unless $filter{na};
+
+  # make order, search in $filter and $form
+  $form->{sort}   = $filter{sort}             unless $form->{sort};
+  $form->{order}  = ($form->{sort} = 'itime') unless $form->{sort};
+  $form->{sort}   = 'itime'                   if     $form->{sort} eq "date";
+  $form->{order}  = $filter{order}            unless $form->{order};
+  $form->{sort}  .= (($form->{order}) ? " DESC" : " ASC");
+
+  my $where_clause = join(" AND ", @filter_ary) . " AND " if (@filter_ary);
+
+  $select_tokens{'trans'} = {
+     "parts_id"             => "i1.parts_id",
+     "qty"                  => "ABS(SUM(i1.qty))",
+     "partnumber"           => "p.partnumber",
+     "partdescription"      => "p.description",
+     "bindescription"       => "b.description",
+     "chargenumber"         => "i1.chargenumber",
+     "warehousedescription" => "w.description",
+     "partunit"             => "p.unit",
+     "bin_from"             => "b1.description",
+     "bin_to"               => "b2.description",
+     "warehouse_from"       => "w1.description",
+     "warehouse_to"         => "w2.description",
+     "comment"              => "i1.comment",
+     "trans_type"           => "tt.description",
+     "trans_id"             => "i1.trans_id",
+     "date"                 => "i1.itime::DATE",
+     "itime"                => "i1.itime",
+     "employee"             => "e.name",
+     "projectnumber"        => "COALESCE(pr.projectnumber, '$filter{na}')",
+     };
+
+  $select_tokens{'out'} = {
+     "bin_to"               => "'$filter{na}'",
+     "warehouse_to"         => "'$filter{na}'",
+     };
+
+  $select_tokens{'in'} = {
+     "bin_from"             => "'$filter{na}'",
+     "warehouse_from"       => "'$filter{na}'",
+     };
+
+  # build the select clauses.
+  # take all the requested ones from the first hash and overwrite them from the out/in hashes if present.
+  for my $i ('trans', 'out', 'in') {
+    $select{$i} = join ', ', map { +/l_/; ($select_tokens{$i}{"$'"} || $select_tokens{'trans'}{"$'"}) . " AS r_$'" }
+          ( grep( { !/qty$/ and /l_/ and $form->{$_} eq 'Y' } keys %$form), qw(l_parts_id l_qty l_partunit l_itime) );
+  }
+
+  my $group_clause = join ", ", map { +/^l_/; "r_$'" }
+        ( grep( { !/qty$/ and /l_/ and $form->{$_} eq 'Y' } keys %$form), qw(l_parts_id l_partunit l_itime) );
+
+  my $query =
+  qq|SELECT DISTINCT $select{trans}
+    FROM inventory i1
+    LEFT JOIN inventory i2 ON i1.trans_id = i2.trans_id
+    LEFT JOIN parts p ON i1.parts_id = p.id
+    LEFT JOIN bin b1 ON i1.bin_id = b1.id
+    LEFT JOIN bin b2 ON i2.bin_id = b2.id
+    LEFT JOIN warehouse w1 ON i1.warehouse_id = w1.id
+    LEFT JOIN warehouse w2 ON i2.warehouse_id = w2.id
+    LEFT JOIN transfer_type tt ON i1.trans_type_id = tt.id
+    LEFT JOIN project pr ON i1.project_id = pr.id
+    LEFT JOIN employee e ON i1.employee_id = e.id
+    WHERE $where_clause i2.qty = -i1.qty AND i2.qty > 0 AND
+          i1.trans_id IN ( SELECT i.trans_id FROM inventory i GROUP BY i.trans_id HAVING COUNT(i.trans_id) = 2 )
+    GROUP BY $group_clause
+
+    UNION
+
+    SELECT DISTINCT $select{out}
+    FROM inventory i1
+    LEFT JOIN inventory i2 ON i1.trans_id = i2.trans_id
+    LEFT JOIN parts p ON i1.parts_id = p.id
+    LEFT JOIN bin b1 ON i1.bin_id = b1.id
+    LEFT JOIN bin b2 ON i2.bin_id = b2.id
+    LEFT JOIN warehouse w1 ON i1.warehouse_id = w1.id
+    LEFT JOIN warehouse w2 ON i2.warehouse_id = w2.id
+    LEFT JOIN transfer_type tt ON i1.trans_type_id = tt.id
+    LEFT JOIN project pr ON i1.project_id = pr.id
+    LEFT JOIN employee e ON i1.employee_id = e.id
+    WHERE $where_clause i1.qty < 0 AND
+          i1.trans_id IN ( SELECT i.trans_id FROM inventory i GROUP BY i.trans_id HAVING COUNT(i.trans_id) = 1 )
+    GROUP BY $group_clause
+
+    UNION
+
+    SELECT DISTINCT $select{in}
+    FROM inventory i1
+    LEFT JOIN inventory i2 ON i1.trans_id = i2.trans_id
+    LEFT JOIN parts p ON i1.parts_id = p.id
+    LEFT JOIN bin b1 ON i1.bin_id = b1.id
+    LEFT JOIN bin b2 ON i2.bin_id = b2.id
+    LEFT JOIN warehouse w1 ON i1.warehouse_id = w1.id
+    LEFT JOIN warehouse w2 ON i2.warehouse_id = w2.id
+    LEFT JOIN transfer_type tt ON i1.trans_type_id = tt.id
+    LEFT JOIN project pr ON i1.project_id = pr.id
+    LEFT JOIN employee e ON i1.employee_id = e.id
+    WHERE $where_clause i1.qty > 0 AND
+          i1.trans_id IN ( SELECT i.trans_id FROM inventory i GROUP BY i.trans_id HAVING COUNT(i.trans_id) = 1 )
+    GROUP BY $group_clause
+    ORDER BY r_$form->{sort}|;
+
+  my $sth = prepare_execute_query($form, $dbh, $query, @filter_vars, @filter_vars, @filter_vars);
+
+  my @contents = ();
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    map { /^r_/; $ref->{"$'"} = $ref->{$_} } keys %$ref;
+    my $qty = $ref->{"qty"} * 1;
+
+    next unless ($qty > 0);
+
+    if ($f_qty_op) {
+      my $part_unit = $all_units->{$ref->{"partunit"}};
+      next unless ($part_unit && ($part_unit->{"base_unit"} eq $f_qty_base_unit));
+      $qty *= $part_unit->{"factor"};
+      next if (('=' eq $f_qty_op) && ($qty != $f_qty));
+      next if (('>=' eq $f_qty_op) && ($qty < $f_qty));
+      next if (('<=' eq $f_qty_op) && ($qty > $f_qty));
+    }
+
+    push @contents, $ref;
+  }
+
+  $sth->finish();
+
+  $main::lxdebug->leave_sub();
+
+  return @contents;
+}
+
+#
+# This sub is the primary function to retrieve information about items in warehouses.
+# $filter is a hashref and supports the following keys:
+#  - warehouse_id - will return matches with this warehouse_id only
+#  - partnumber   - will return only matches where the given string is a substring of the partnumber
+#  - partsid      - will return matches with this parts_id only
+#  - description  - will return only matches where the given string is a substring of the description
+#  - chargenumber - will return only matches where the given string is a substring of the chargenumber
+#  - charge_ids   - must be an arrayref. will return contents with these ids only
+#  - expires_in   - will only return matches that expire within the given number of days
+#                   will also add a column named 'has_expired' containing if the match has already expired or not
+#  - hazardous    - will return matches with the flag hazardous only
+#  - oil          - will return matches with the flag oil only
+#  - qty, qty_op  - quantity filter (more info to come)
+#  - sort, order_by - sorting (more to come)
+#  - reservation  - will provide an extra column containing the amount reserved of this match
+# note: reservation flag turns off warehouse_* or bin_* information. both together don't make sense, since reserved info is stored separately
+#
+sub get_warehouse_report {
+  $main::lxdebug->enter_sub();
+
+  my $self      = shift;
+  my %filter    = @_;
+
+  my $myconfig  = \%main::myconfig;
+  my $form      = $main::form;
+
+  my $all_units = AM->retrieve_units($myconfig, $form);
+
+  # connect to database
+  my $dbh = $form->get_standard_dbh($myconfig);
+
+  # filters
+  my (@filter_ary, @filter_vars, @wh_bin_filter_ary, @wh_bin_filter_vars, $columns, $group_by);
+
+  delete $form->{include_empty_bins} unless ($form->{l_warehousedescription} || $form->{l_bindescription});
+
+  if ($filter{warehouse_id}) {
+    push @wh_bin_filter_ary,  "w.id = ?";
+    push @wh_bin_filter_vars, $filter{warehouse_id};
+  }
+
+  if ($filter{bin_id}) {
+    push @wh_bin_filter_ary,  "b.id = ?";
+    push @wh_bin_filter_vars, $filter{bin_id};
+  }
+
+  push @filter_ary,  @wh_bin_filter_ary;
+  push @filter_vars, @wh_bin_filter_vars;
+
+  if ($filter{partnumber}) {
+    push @filter_ary,  "p.partnumber ILIKE ?";
+    push @filter_vars, '%' . $filter{partnumber} . '%';
+  }
+
+  if ($filter{description}) {
+    push @filter_ary,  "p.description ILIKE ?";
+    push @filter_vars, '%' . $filter{description} . '%';
+  }
+
+  if ($filter{partsid}) {
+    push @filter_ary,  "p.id = ?";
+    push @filter_vars, $filter{partsid};
+  }
+
+  if ($filter{chargenumber}) {
+    push @filter_ary,  "i.chargenumber ILIKE ?";
+    push @filter_vars, '%' . $filter{chargenumber} . '%';
+  }
+
+  # prepare qty comparison for later filtering
+  my ($f_qty_op, $f_qty, $f_qty_base_unit);
+
+  if ($filter{qty_op} && defined $filter{qty} && $filter{qty_unit} && $all_units->{$filter{qty_unit}}) {
+    $f_qty_op        = $filter{qty_op};
+    $f_qty           = $filter{qty} * $all_units->{$filter{qty_unit}}->{factor};
+    $f_qty_base_unit = $all_units->{$filter{qty_unit}}->{base_unit};
+  }
+
+  map { $_ = "(${_})"; } @filter_ary;
+
+  # if of a property number or description is requested,
+  # automatically check the matching id too.
+  map { $form->{"l_${_}id"} = "Y" if ($form->{"l_${_}description"} || $form->{"l_${_}number"}); } qw(warehouse bin);
+
+  # make order, search in $filter and $form
+  $form->{sort}  =  $filter{sort}  unless $form->{sort};
+  $form->{sort}  =  "parts_id"     unless $form->{sort};
+  $form->{order} =  $filter{order} unless $form->{order};
+  $form->{sort}  =~ s/ASC|DESC//; # kill stuff left in from previous queries
+  my $orderby    =  $form->{sort};
+  $form->{sort} .=  (($form->{order}) ? " DESC" : " ASC");
+
+  my $where_clause = join " AND ", ("1=1", @filter_ary);
+
+  my %select_tokens = (
+     "parts_id"              => "i.parts_id",
+     "qty"                  => "SUM(i.qty)",
+     "warehouseid"          => "i.warehouse_id",
+     "partnumber"           => "p.partnumber",
+     "partdescription"      => "p.description",
+     "bindescription"       => "b.description",
+     "binid"                => "b.id",
+     "chargenumber"         => "i.chargenumber",
+     "chargeid"             => "c.id",
+     "warehousedescription" => "w.description",
+     "partunit"             => "p.unit",
+  );
+  my $select_clause = join ', ', map { +/l_/; "$select_tokens{$'} AS $'" }
+        ( grep( { !/qty/ and /l_/ and $form->{$_} eq 'Y' } keys %$form),
+          qw(l_parts_id l_qty l_partunit) );
+
+  my $group_clause = join ", ", map { +/^l_/; "$'" }
+        ( grep( { !/qty/ and /l_/ and $form->{$_} eq 'Y' } keys %$form),
+          qw(l_parts_id l_partunit) );
+
+  my $query =
+    qq|SELECT $select_clause
+      $columns
+      FROM inventory i
+      LEFT JOIN parts     p ON i.parts_id     = p.id
+      LEFT JOIN bin       b ON i.bin_id       = b.id
+      LEFT JOIN warehouse w ON i.warehouse_id = w.id
+      WHERE $where_clause
+      GROUP BY $group_clause $group_by
+      ORDER BY $form->{sort}|;
+
+  my $sth = prepare_execute_query($form, $dbh, $query, @filter_vars);
+
+  my (%non_empty_bins, @all_fields, @contents);
+
+  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+    $ref->{qty} *= 1;
+    my $qty      = $ref->{qty};
+
+    next unless ($qty > 0);
+
+    if ($f_qty_op) {
+      my $part_unit = $all_units->{$ref->{partunit}};
+      next if (!$part_unit || ($part_unit->{base_unit} ne $f_qty_base_unit));
+      $qty *= $part_unit->{factor};
+      next if (('='  eq $f_qty_op) && ($qty != $f_qty));
+      next if (('>=' eq $f_qty_op) && ($qty <  $f_qty));
+      next if (('<=' eq $f_qty_op) && ($qty >  $f_qty));
+    }
+
+    if ($form->{include_empty_bins}) {
+      $non_empty_bins{$ref->{binid}} = 1;
+      @all_fields                    = keys %{ $ref } unless (@all_fields);
+    }
+
+    push @contents, $ref;
+  }
+
+  $sth->finish();
+
+  if ($form->{include_empty_bins}) {
+    $query =
+      qq|SELECT
+           w.id AS warehouseid, w.description AS warehousedescription,
+           b.id AS binid, b.description AS bindescription
+         FROM bin b
+         LEFT JOIN warehouse w ON (b.warehouse_id = w.id)|;
+
+    @filter_ary  = @wh_bin_filter_ary;
+    @filter_vars = @wh_bin_filter_vars;
+
+    my @non_empty_bin_ids = keys %non_empty_bins;
+    if (@non_empty_bin_ids) {
+      push @filter_ary,  qq|NOT b.id IN (| . join(', ', map { '?' } @non_empty_bin_ids) . qq|)|;
+      push @filter_vars, @non_empty_bin_ids;
+    }
+
+    $query .= qq| WHERE | . join(' AND ', map { "($_)" } @filter_ary) if (@filter_ary);
+
+    $sth    = prepare_execute_query($form, $dbh, $query, @filter_vars);
+
+    while ($ref = $sth->fetchrow_hashref()) {
+      map { $ref->{$_} ||= "" } @all_fields;
+      push @contents, $ref;
+    }
+    $sth->finish();
+
+    if (grep { $orderby eq $_ } qw(bindescription warehousedescription)) {
+      @contents = sort { ($a->{$orderby} cmp $b->{$orderby}) * (($form->{order}) ? 1 : -1) } @contents;
+    }
+  }
+
+  $main::lxdebug->leave_sub();
+
+  return @contents;
+}
+
+sub convert_qty_op {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $qty_op) = @_;
+
+  if (!$qty_op || ($qty_op eq "dontcare")) {
+    $main::lxdebug->leave_sub();
+    return undef;
+  }
+
+  if ($qty_op eq "atleast") {
+    $qty_op = '>=';
+  } elsif ($qty_op eq "atmost") {
+    $qty_op = '<=';
+  } else {
+    $qty_op = '=';
+  }
+
+  $main::lxdebug->leave_sub();
+
+  return $qty_op;
+}
+
+sub retrieve_transfer_types {
+  $main::lxdebug->enter_sub();
+
+  my $self      = shift;
+  my $direction = shift;
+
+  my $myconfig  = \%main::myconfig;
+  my $form      = $main::form;
+
+  my $dbh       = $form->get_standard_dbh($myconfig);
+
+  my $types     = selectall_hashref_query($form, $dbh, qq|SELECT * FROM transfer_type WHERE direction = ? ORDER BY sortkey|, $direction);
+
+  $main::lxdebug->leave_sub();
+
+  return $types;
+}
+
+sub get_basic_bin_info {
+  $main::lxdebug->enter_sub();
+
+  my $self     = shift;
+  my %params   = @_;
+
+  Common::check_params(\%params, qw(id));
+
+  my $myconfig = \%main::myconfig;
+  my $form     = $main::form;
+
+  my $dbh      = $params{dbh} || $form->get_standard_dbh();
+
+  my @ids      = 'ARRAY' eq ref $params{id} ? @{ $params{id} } : ($params{id});
+
+  my $query    =
+    qq|SELECT b.id AS bin_id, b.description AS bin_description,
+         w.id AS warehouse_id, w.description AS warehouse_description
+       FROM bin b
+       LEFT JOIN warehouse w ON (b.warehouse_id = w.id)
+       WHERE b.id IN (| . join(', ', ('?') x scalar(@ids)) . qq|)|;
+
+  my $result = selectall_hashref_query($form, $dbh, $query, map { conv_i($_) } @ids);
+
+  if ('' eq ref $params{id}) {
+    $result = $result->[0] || { };
+    $main::lxdebug->leave_sub();
+
+    return $result;
+  }
+
+  $main::lxdebug->leave_sub();
+
+  return map { $_->{bin_id} => $_ } @{ $result };
+}
+
+
+1;
index 9f7d8f5..8cce020 100644 (file)
@@ -3136,3 +3136,131 @@ sub swap_price_factors {
   $lxdebug->leave_sub();
 }
 
+sub add_warehouse {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  $form->{title}      = $locale->text('Add Warehouse');
+  $form->{callback} ||= build_std_url('action=add_warehouse');
+  $form->{fokus}      = 'description';
+
+  $form->header();
+  print $form->parse_html_template('am/edit_warehouse');
+
+  $lxdebug->leave_sub();
+}
+
+sub edit_warehouse {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  AM->get_warehouse(\%myconfig, $form);
+
+  $form->get_lists('employees' => 'EMPLOYEES');
+
+  $form->{title}      = $locale->text('Edit Warehouse');
+  $form->{callback} ||= build_std_url('action=list_warehouses');
+  $form->{fokus}      = 'description';
+
+  $form->header();
+  print $form->parse_html_template('am/edit_warehouse');
+
+  $lxdebug->leave_sub();
+}
+
+sub list_warehouses {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  AM->get_all_warehouses(\%myconfig, $form);
+
+  my $previous;
+  foreach my $current (@{ $form->{WAREHOUSES} }) {
+    if ($previous) {
+      $previous->{next_id}    = $current->{id};
+      $current->{previous_id} = $previous->{id};
+    }
+
+    $previous = $current;
+  }
+
+  $form->{callback} = build_std_url('action=list_warehouses');
+  $form->{title}    = $locale->text('Warehouses');
+  $form->{url_base} = build_std_url('callback');
+
+  $form->header();
+  print $form->parse_html_template('am/list_warehouses');
+
+  $lxdebug->leave_sub();
+}
+
+sub save_warehouse {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  $form->isblank("description", $locale->text('Description missing!'));
+
+  $form->{number_of_new_bins} = $form->parse_amount(\%myconfig, $form->{number_of_new_bins});
+
+  AM->save_warehouse(\%myconfig, $form);
+
+  $form->{callback} .= '&saved_message=' . E($locale->text('Warehouse saved.')) if ($form->{callback});
+
+  $form->redirect($locale->text('Warehouse saved.'));
+
+  $lxdebug->leave_sub();
+}
+
+sub swap_warehouses {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  AM->swap_sortkeys(\%myconfig, $form, 'warehouse');
+  list_warehouses();
+
+  $lxdebug->leave_sub();
+}
+
+sub delete_warehouse {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  if (!$form->{confirmed}) {
+    $form->{title} = $locale->text('Confirmation');
+
+    $form->header();
+    print $form->parse_html_template('am/confirm_delete_warehouse');
+    exit 0;
+  }
+
+  if (AM->delete_warehouse(\%myconfig, $form)) {
+    $form->{callback} .= '&saved_message=' . E($locale->text('Warehouse deleted.')) if ($form->{callback});
+    $form->redirect($locale->text('Warehouse deleted.'));
+
+  } else {
+    $form->error($locale->text('The warehouse could not be deleted because it has already been used.'));
+  }
+
+  $lxdebug->leave_sub();
+}
+
+sub save_bin {
+  $lxdebug->enter_sub();
+
+  $auth->assert('config');
+
+  AM->save_bins(\%myconfig, $form);
+
+  $form->{callback} .= '&saved_message=' . E($locale->text('Bins saved.')) if ($form->{callback});
+
+  $form->redirect($locale->text('Bins saved.'));
+
+  $lxdebug->leave_sub();
+}
+
index 6ed951c..f54ffef 100644 (file)
@@ -47,6 +47,126 @@ sub build_std_url {
 
 # -------------------------------------------------------------------------
 
+sub select_part {
+  $lxdebug->enter_sub();
+
+  my ($callback_sub, @parts) = @_;
+
+  my $remap_parts_id = 0;
+  if (defined($parts[0]->{parts_id}) && !defined($parts[0]->{id})) {
+    $remap_parts_id = 1;
+    map { $_->{id} = $_->{parts_id}; } @parts;
+  }
+
+  my $remap_partnumber = 0;
+  if (defined($parts[0]->{partnumber}) && !defined($parts[0]->{number})) {
+    $remap_partnumber = 1;
+    map { $_->{number} = $_->{partnumber}; } @parts;
+  }
+
+  my $has_charge = 0;
+  if (defined($parts[0]->{chargenumber})) {
+    $has_charge = 1;
+    map { $_->{has_charge} = 1; } @parts;
+  }
+
+  my $old_form = save_form();
+
+  $form->header();
+  print $form->parse_html_template("generic/select_part",
+                                   { "PARTS"            => \@parts,
+                                     "old_form"         => $old_form,
+                                     "title"            => $locale->text("Select a part"),
+                                     "nextsub"          => "select_part_internal",
+                                     "callback_sub"     => $callback_sub,
+                                     "has_charge"       => $has_charge,
+                                     "remap_parts_id"   => $remap_parts_id,
+                                     "remap_partnumber" => $remap_partnumber });
+
+  $lxdebug->leave_sub();
+}
+
+sub select_part_internal {
+  $lxdebug->enter_sub();
+
+  my ($new_item, $callback_sub);
+
+  my $re = "^new_.*_" . $form->{selection};
+
+  foreach (grep /$re/, keys %{ $form }) {
+    my $new_key           =  $_;
+    $new_key              =~ s/^new_//;
+    $new_key              =~ s/_\d+$//;
+    $new_item->{$new_key} =  $form->{$_};
+  }
+
+  if ($form->{remap_parts_id}) {
+    $new_item->{parts_id} = $new_item->{id};
+    delete $new_item->{id};
+  }
+
+  if ($form->{remap_partnumber}) {
+    $new_item->{partnumber} = $new_item->{number};
+    delete $new_item->{number};
+  }
+
+  my $callback_sub = $form->{callback_sub};
+
+  restore_form($form->{old_form});
+
+  call_sub($callback_sub, $new_item);
+
+  $lxdebug->leave_sub();
+}
+
+sub part_selection_internal {
+  $lxdebug->enter_sub();
+
+  $order_by  = "description";
+  $order_by  = $form->{"order_by"} if (defined($form->{"order_by"}));
+  $order_dir = 1;
+  $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"}));
+
+  %options   = map { $_ => 1 } split m/:/, $form->{options};
+
+  map { $form->{$_} = 1 if ($options{$_}) } qw(no_services no_assemblies stockable);
+
+  $parts = Common->retrieve_parts(\%myconfig, $form, $order_by, $order_dir);
+
+  if (0 == scalar(@{$parts})) {
+    $form->show_generic_information($locale->text("No part was found matching the search parameters."));
+  } elsif (1 == scalar(@{$parts})) {
+    $onload = "part_selected('1')";
+  }
+
+  map { $parts->[$_]->{selected} = $_ ? 0 : 1; } (0..$#{$parts});
+
+  my $callback = build_std_url('action=part_selection_internal', qw(partnumber description input_partnumber input_description input_partsid),
+                               grep({ /^[fl]_/ } keys %{ $form }));
+
+  my @header_sort  = qw(partnumber description);
+  my %header_title = ( "partnumber"  => $locale->text("Part Number"),
+                       "description" => $locale->text("Part description"),
+                       );
+
+  my @header =
+    map(+{ "column_title" => $header_title{$_},
+           "column"       => $_,
+           "callback"     => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir),
+         },
+        @header_sort);
+
+  $form->{title} = $locale->text("Select a part");
+  $form->header();
+  print $form->parse_html_template("generic/part_selection", { "HEADER" => \@header,
+                                                               "PARTS"  => $parts,
+                                                               "onload" => $onload });
+
+  $lxdebug->leave_sub();
+}
+
+# -------------------------------------------------------------------------
+
 sub delivery_customer_selection {
   $lxdebug->enter_sub();
 
diff --git a/bin/mozilla/wh.pl b/bin/mozilla/wh.pl
new file mode 100644 (file)
index 0000000..68dcdbf
--- /dev/null
@@ -0,0 +1,771 @@
+#=====================================================================
+# LX-Office ERP
+# Copyright (C) 2004
+# Based on SQL-Ledger Version 2.1.9
+# Web http://www.lx-office.org
+#############################################################################
+# SQL-Ledger, Accounting
+# Copyright (c) 1998-2002
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#######################################################################
+#
+# warehouse and packinglist
+#
+#######################################################################
+
+use List::Util qw(min max first);
+use POSIX qw(strftime);
+
+use SL::Form;
+use SL::User;
+
+use SL::AM;
+use SL::CT;
+use SL::IC;
+use SL::WH;
+use SL::OE;
+use SL::ReportGenerator;
+
+use Data::Dumper;
+
+require "bin/mozilla/common.pl";
+require "bin/mozilla/reportgenerator.pl";
+
+# parserhappy(R):
+
+# contents of the "transfer_type" table:
+#  $locale->text('back')
+#  $locale->text('correction')
+#  $locale->text('disposed')
+#  $locale->text('found')
+#  $locale->text('missing')
+#  $locale->text('stock')
+#  $locale->text('transfer')
+#  $locale->text('used')
+#  $locale->text('return_material')
+#  $locale->text('release_material')
+
+# --------------------------------------------------------------------
+# Transfer
+# --------------------------------------------------------------------
+
+sub transfer_warehouse_selection {
+  $lxdebug->enter_sub();
+
+  $auth->assert('warehouse_management');
+
+  $form->get_lists('warehouses' => { 'key'    => 'WAREHOUSES',
+                                     'bins'   => 'BINS', });
+
+  show_no_warehouses_error() if (!scalar @{ $form->{WAREHOUSES} });
+
+  my $units      = AM->retrieve_units(\%myconfig, $form, 'dimension');
+  $form->{UNITS} = AM->unit_select_data($units, $form->{unit}, 0, $form->{partunit});
+
+  if (scalar @{ $form->{WAREHOUSES} }) {
+    $form->{warehouse_id} ||= $form->{WAREHOUSES}->[0]->{id};
+    $form->{bin_id}       ||= $form->{WAREHOUSES}->[0]->{BINS}->[0]->{id};
+  }
+
+  my $content;
+
+  $form->{jsscript} = 1;
+
+  if ($form->{trans_type} eq 'removal') {
+    $form->{nextsub} = "removal_parts_selection";
+    $form->{title}   = $locale->text('Removal from Warehouse');
+    $content         = $form->parse_html_template('wh/warehouse_selection');
+
+  } elsif ($form->{trans_type} eq 'stock') {
+    $form->{title} = $locale->text('Stock');
+    $content       = $form->parse_html_template('wh/warehouse_selection_stock');
+
+  } elsif (!$form->{trans_type} || ($form->{trans_type} eq 'transfer')) {
+    $form->{nextsub} = "transfer_parts_selection";
+    $form->{title}   = $locale->text('Transfer');
+    $content         = $form->parse_html_template('wh/warehouse_selection');
+
+  }
+
+  $form->header();
+  print $content;
+
+  $lxdebug->leave_sub();
+}
+
+sub transfer_parts_selection {
+  $lxdebug->enter_sub();
+
+  $auth->assert('warehouse_management');
+
+  transfer_or_removal_prepare_contents('direction' => 'transfer');
+
+  $form->{title} = $locale->text('Transfer');
+  $form->header();
+  print $form->parse_html_template("wh/transfer_parts_selection");
+
+  $lxdebug->leave_sub();
+}
+
+sub transfer_or_removal_prepare_contents {
+  $lxdebug->enter_sub();
+
+  $auth->assert('warehouse_management');
+
+  my %args = @_;
+
+  $form->get_lists('warehouses' => { 'key'    => 'WAREHOUSES',
+                                     'bins'   => 'BINS', });
+
+  my $warehouse_idx = get_warehouse_idx($form->{warehouse_id});
+  $form->show_generic_error($locale->text("The selected warehouse does not exist.")) if (-1 == $warehouse_idx);
+
+  my $warehouse = $form->{WAREHOUSES}->[$warehouse_idx];
+
+  $form->{initial_warehouse_idx} = $warehouse_idx;
+  $form->{warehouse_description} = $warehouse->{description};
+  $warehouse->{selected}         = 1;
+
+  $form->show_generic_error($locale->text("The source warehouse does not contain any bins.")) if (0 == scalar @{ $warehouse->{BINS} });
+
+  map { $form->{"l_$_"} = 'Y' } qw(parts_id qty warehouseid binid partnumber partdescription bindescription chargenumber partunit);
+
+  $form->{sort} = 'bindescription';
+  my @contents  = WH->get_warehouse_report("warehouse_id" => $form->{warehouse_id},
+                                           "bin_id"       => $form->{bin_id},
+                                           "chargenumber" => $form->{chargenumber},
+                                           "partnumber"   => $form->{partnumber},
+                                           "description"  => $form->{description});
+
+  $form->show_generic_error($locale->text("The selected warehouse is empty.")) if (0 == scalar(@contents));
+
+  my $all_units = AM->retrieve_units(\%myconfig, $form, 'dimension');
+
+  foreach (@contents) {
+    $_->{qty} = $form->format_amount_units('amount'     => $_->{qty},
+                                           'part_unit'  => $_->{partunit},
+                                           'conv_units' => 'convertible');
+    my $this_unit = $_->{partunit};
+
+    if ($all_units->{$_->{partunit}} && ($all_units->{g}->{base_unit} eq $all_units->{$_->{partunit}}->{base_unit})) {
+      $this_unit = "kg";
+    }
+
+    $_->{UNITS} = AM->unit_select_data($all_units, $this_unit, 0, $_->{partunit});
+  }
+
+  my $transfer_types = WH->retrieve_transfer_types($args{direction});
+  map { $_->{description} = $locale->text($_->{description}) } @{ $transfer_types };
+
+  $form->{CONTENTS}       = \@contents;
+  $form->{TRANSFER_TYPES} = $transfer_types;
+
+  $lxdebug->leave_sub();
+}
+
+
+sub transfer_parts {
+  $lxdebug->enter_sub();
+
+  $auth->assert('warehouse_management');
+
+  $form->get_lists('warehouses' => { 'key' => 'WAREHOUSES', 'bins' => 'BINS' });
+
+  my $warehouse_idx = get_warehouse_idx($form->{warehouse_id});
+  $form->show_generic_error($locale->text("The selected warehouse does not exist.")) if (-1 == $warehouse_idx);
+
+  my $warehouse = $form->{WAREHOUSES}->[$warehouse_idx];
+
+  $form->show_generic_error($locale->text("The source warehouse does not contain any bins.")) if (0 == scalar @{ $warehouse->{BINS} });
+
+  map { $form->{"l_$_"} = 'Y' } qw(parts_id qty warehouseid binid partnumber partdescription bindescription chargenumber partunit);
+
+  $form->{sort} = 'bindescription';
+  my @contents  = WH->get_warehouse_report("warehouse_id" => $form->{warehouse_id});
+  my $all_units = AM->retrieve_units(\%myconfig, $form, 'dimension');
+
+  my @transfers;
+
+  foreach my $row (1 .. $form->{rowcount}) {
+    $form->{"qty_$row"} =~ s/^\s*//;
+    $form->{"qty_$row"} =~ s/\s*$//;
+    next if (!$form->{"qty_$row"});
+
+    my $bin_idx = get_bin_idx($warehouse_idx, $form->{"src_bin_id_$row"});
+    $form->show_generic_error($locale->text("The selected bin does not exist.")) if (-1 == $bin_idx);
+    my $bin     = $warehouse->{BINS}->[$bin_idx];
+
+    my $orig_qty = $form->{"qty_$row"} . " " . $form->{"unit_$row"};
+
+    my $transfer = {
+      'src_warehouse_id' => $form->{warehouse_id},
+      'transfer_type_id' => $form->{transfer_type_id},
+    };
+
+    map { $transfer->{$_} = $form->{"${_}_${row}"} } qw(src_bin_id chargenumber parts_id qty dst_warehouse_id dst_bin_id);
+
+    my $entry;
+
+    foreach (@contents) {
+      if (($_->{binid} == $transfer->{src_bin_id}) && ($_->{parts_id} == $transfer->{parts_id}) && ($_->{chargenumber} eq $transfer->{chargenumber})) {
+        $entry = $_;
+        last;
+      }
+    }
+
+    if (!$entry) {
+      $form->error($locale->text("There is not enough left of '#1' in bin '#2' for the removal of #3.",
+                                 $form->{"partdescription_$row"}, $bin->{description}, $orig_qty));
+    }
+
+    $transfer->{qty}  = $form->parse_amount(\%myconfig, $transfer->{qty}) * $all_units->{$form->{"unit_$row"}}->{factor};
+    $transfer->{qty} /= $all_units->{$entry->{partunit}}->{factor} || 1;
+
+    if (($entry->{qty} < $transfer->{qty}) || (0 >= $transfer->{qty})) {
+      $form->error($locale->text("There is not enough left of '#1' in bin '#2' for the removal of #3.",
+                                 $form->{"partdescription_$row"}, $bin->{description}, $orig_qty));
+    }
+
+    $transfer->{comment} = $form->{comment};
+
+    push @transfers, $transfer;
+
+    $entry->{qty} -= $transfer->{qty};
+  }
+
+  if (!scalar @transfers) {
+    $form->show_generic_information($locale->text('Nothing has been selected for transfer.'));
+    exit 0;
+  }
+
+  WH->transfer(@transfers);
+
+  $form->{trans_type}    = 'transfer';
+  $form->{saved_message} = $locale->text('The parts have been transferred.');
+
+  transfer_warehouse_selection();
+
+  $lxdebug->leave_sub();
+}
+
+# --------------------------------------------------------------------
+# Transfer: stock
+# --------------------------------------------------------------------
+
+sub transfer_stock_update_part {
+  $lxdebug->enter_sub();
+
+  $form->{trans_type} = 'stock';
+  $form->{qty}        = $form->parse_amount(\%myconfig, $form->{qty});
+
+  if (!$form->{partnumber} && !$form->{description}) {
+    delete @{$form}{qw(parts_id partunit)};
+    transfer_warehouse_selection();
+
+  } elsif (($form->{partnumber} && ($form->{partnumber} ne $form->{old_partnumber})) || $form->{description}) {
+
+    $form->{no_services}   = 1;
+    $form->{no_assemblies} = 1;
+    $form->{stockable}     = 1;
+
+    my $parts = Common->retrieve_parts(\%myconfig, $form, 'description', 1);
+
+    if (scalar @{ $parts } == 1) {
+      @{$form}{qw(parts_id partnumber description)} = @{$parts->[0]}{qw(id partnumber description)};
+      transfer_stock_get_partunit();
+      transfer_warehouse_selection();
+
+    } else {
+      select_part('transfer_stock_part_selected', @{ $parts });
+    }
+
+  } else {
+    transfer_stock_get_partunit();
+    transfer_warehouse_selection();
+  }
+
+  $lxdebug->leave_sub();
+}
+
+sub transfer_stock_part_selected {
+  $lxdebug->enter_sub();
+
+  my $part = shift;
+
+  @{$form}{qw(parts_id partnumber description)} = @{$part}{qw(id partnumber description)};
+
+  transfer_stock_get_partunit();
+  transfer_warehouse_selection();
+
+  $lxdebug->leave_sub();
+}
+
+sub transfer_stock_get_partunit {
+  $lxdebug->enter_sub();
+
+  if ($form->{parts_id}) {
+    my $part_info     = IC->get_basic_part_info('id' => $form->{parts_id});
+    $form->{partunit} = $part_info->{unit};
+  }
+
+  $lxdebug->leave_sub();
+}
+
+sub transfer_stock {
+  $lxdebug->enter_sub();
+
+  $form->{qty} = $form->parse_amount(\%myconfig, $form->{qty});
+
+  if ($form->{qty} <= 0) {
+    $form->show_generic_error($locale->text('Invalid quantity.'), 'back_button' => 1);
+  }
+
+  if (!$form->{warehouse_id} || !$form->{bin_id}) {
+    $form->error($locale->text('The warehouse or the bin is missing.'));
+  }
+
+  my $transfer = {
+    'transfer_type'    => 'stock',
+    'dst_warehouse_id' => $form->{warehouse_id},
+    'dst_bin_id'       => $form->{bin_id},
+    'chargenumber'     => $form->{chargenumber},
+    'parts_id'         => $form->{parts_id},
+    'qty'              => $form->{qty},
+    'unit'             => $form->{unit},
+    'comment'          => $form->{comment},
+  };
+
+  WH->transfer($transfer);
+
+  delete @{$form}{qw(parts_id partnumber description qty unit chargenumber comment)};
+
+  $form->{saved_message} = $locale->text('The parts have been stocked.');
+  $form->{trans_type}    = 'stock';
+
+  transfer_warehouse_selection();
+
+  $lxdebug->leave_sub();
+}
+
+# --------------------------------------------------------------------
+# Transfer: removal
+# --------------------------------------------------------------------
+
+sub removal_parts_selection {
+  $lxdebug->enter_sub();
+
+  $auth->assert('warehouse_management');
+
+  transfer_or_removal_prepare_contents('direction' => 'out');
+
+  $form->{title} = $locale->text('Removal');
+  $form->header();
+  print $form->parse_html_template("wh/removal_parts_selection");
+
+  $lxdebug->leave_sub();
+}
+
+sub remove_parts {
+  $lxdebug->enter_sub();
+
+  $auth->assert('warehouse_management');
+
+  $form->get_lists('warehouses' => { 'key'    => 'WAREHOUSES',
+                                     'bins'   => 'BINS', });
+
+  my $warehouse_idx = get_warehouse_idx($form->{warehouse_id});
+  $form->show_generic_error($locale->text("The selected warehouse does not exist.")) if (-1 == $warehouse_idx);
+
+  my $warehouse = $form->{WAREHOUSES}->[$warehouse_idx];
+
+  $form->show_generic_error($locale->text("The warehouse does not contain any bins.")) if (0 == scalar @{ $warehouse->{BINS} });
+
+  map { $form->{"l_$_"} = 'Y' } qw(parts_id qty warehouseid binid partnumber partdescription bindescription chargenumber partunit);
+
+  $form->{sort} = 'bindescription';
+  my @contents  = WH->get_warehouse_report("warehouse_id" => $form->{warehouse_id});
+  my $all_units = AM->retrieve_units(\%myconfig, $form, 'dimension');
+
+  my @transfers;
+
+  foreach my $row (1 .. $form->{rowcount}) {
+    $form->{"qty_$row"} =~ s/^\s*//;
+    $form->{"qty_$row"} =~ s/\s*$//;
+    next if (!$form->{"qty_$row"});
+
+    my $bin_idx = get_bin_idx($warehouse_idx, $form->{"src_bin_id_$row"});
+    $form->show_generic_error($locale->text("The selected bin does not exist.")) if (-1 == $bin_idx);
+    my $bin     = $warehouse->{BINS}->[$bin_idx];
+
+    my $orig_qty = $form->{"qty_$row"} . " " . $form->{"unit_$row"};
+
+    my $transfer = {
+      'src_warehouse_id' => $form->{warehouse_id},
+      'transfer_type_id' => $form->{transfer_type_id},
+    };
+
+    map { $transfer->{$_} = $form->{"${_}_${row}"} } qw(src_bin_id chargenumber parts_id qty);
+
+    my $entry;
+
+    foreach (@contents) {
+      if (($_->{binid} == $transfer->{src_bin_id}) && ($_->{parts_id} == $transfer->{parts_id}) && ($_->{chargenumber} eq $transfer->{chargenumber})) {
+        $entry = $_;
+        last;
+      }
+    }
+
+    if (!$entry) {
+      $form->error($locale->text("There is not enough left of '#1' in bin '#2' for the removal of #3.",
+                                 $form->{"partdescription_$row"}, $bin->{description}, $orig_qty));
+    }
+
+    $transfer->{qty}  = $form->parse_amount(\%myconfig, $transfer->{qty}) * $all_units->{$form->{"unit_$row"}}->{factor};
+    $transfer->{qty} /= $all_units->{$entry->{partunit}}->{factor} || 1;
+
+    if (($entry->{qty} < $transfer->{qty}) || (0 >= $transfer->{qty})) {
+      $form->error($locale->text("There is not enough left of '#1' in bin '#2' for the removal of #3.",
+                                 $form->{"partdescription_$row"}, $bin->{description}, $orig_qty));
+    }
+
+    $transfer->{comment} = $form->{comment};
+
+    push @transfers, $transfer;
+
+    $entry->{qty} -= $transfer->{qty};
+  }
+
+  if (!scalar @transfers) {
+    $form->show_generic_information($locale->text('Nothing has been selected for removal.'));
+    exit 0;
+  }
+
+  WH->transfer(@transfers);
+
+  $form->{trans_type}    = 'removal';
+  $form->{saved_message} = $locale->text('The parts have been removed.');
+
+  transfer_warehouse_selection();
+
+  $lxdebug->leave_sub();
+}
+
+# --------------------------------------------------------------------
+# Journal
+# --------------------------------------------------------------------
+
+sub journal {
+  $lxdebug->enter_sub();
+
+  $auth->assert('warehouse_management');
+
+  $form->get_lists('warehouses' => { 'key'  => 'WAREHOUSES',
+                                     'bins' => 'BINS', });
+
+  show_no_warehouses_error() if (!scalar @{ $form->{WAREHOUSES} });
+
+  $form->{jsscript} = 1;
+
+  $form->header();
+  print $form->parse_html_template("wh/journal_filter", { "UNITS" => AM->unit_select_data(AM->retrieve_units(\%myconfig, $form)) });
+
+  $lxdebug->leave_sub();
+}
+
+sub generate_journal {
+  $lxdebug->enter_sub();
+
+  $auth->assert('warehouse_management');
+
+  $form->{title}   = $locale->text("WHJournal");
+  $form->{sort}  ||= 'date';
+
+  my %filter;
+  my @columns = qw(trans_id date warehouse_from bin_from warehouse_to bin_to partnumber partdescription chargenumber trans_type comment qty employee projectnumber);
+
+  # filter stuff
+  map { $filter{$_} = $form->{$_} if ($form->{$_}) } qw(warehouse_id bin_id partnumber description chargenumber);
+
+  $filter{qty_op} = WH->convert_qty_op($form->{qty_op});
+  if ($filter{qty_op}) {
+    $form->isblank(qty,      $locale->text('Quantity missing.'));
+    $form->isblank(qty_unit, $locale->text('Unit missing.'));
+
+    $filter{qty}      = $form->{qty};
+    $filter{qty_unit} = $form->{qty_unit};
+  }
+  # /filter stuff
+
+  my $report = SL::ReportGenerator->new(\%myconfig, $form);
+
+  my @hidden_variables = map { "l_${_}" } @columns;
+  push @hidden_variables, qw(warehouse_id bin_id partnumber description chargenumber qty_op qty qty_unit fromdate todate);
+
+  my %column_defs = (
+    'date'            => { 'text' => $locale->text('Date'), },
+    'trans_id'        => { 'text' => $locale->text('Trans Id'), },
+    'trans_type'      => { 'text' => $locale->text('Trans Type'), },
+    'comment'         => { 'text' => $locale->text('Comment'), },
+    'warehouse_from'  => { 'text' => $locale->text('Warehouse From'), },
+    'warehouse_to'    => { 'text' => $locale->text('Warehouse To'), },
+    'bin_from'        => { 'text' => $locale->text('Bin From'), },
+    'bin_to'          => { 'text' => $locale->text('Bin To'), },
+    'partnumber'      => { 'text' => $locale->text('Part Number'), },
+    'partdescription' => { 'text' => $locale->text('Description'), },
+    'chargenumber'    => { 'text' => $locale->text('Charge Number'), },
+    'qty'             => { 'text' => $locale->text('Qty'), },
+    'employee'        => { 'text' => $locale->text('Employee'), },
+    'projectnumber'   => { 'text' => $locale->text('Project Number'), },
+  );
+
+  my $href = build_std_url('action=generate_journal', grep { $form->{$_} } @hidden_variables);
+  map { $column_defs{$_}->{link} = $href . "&sort=${_}&order=" . Q($_ eq $form->{sort} ? 1 - $form->{order} : $form->{order}) } @columns;
+
+  my %column_alignment = map { $_ => 'right' } qw(qty);
+
+  map { $column_defs{$_}->{visible} = $form->{"l_${_}"} ? 1 : 0 } @columns;
+
+  $report->set_columns(%column_defs);
+  $report->set_column_order(@columns);
+
+  $report->set_export_options('generate_journal', @hidden_variables);
+
+  $report->set_sort_indicator($form->{sort}, $form->{order});
+
+  $report->set_options('output_format'        => 'HTML',
+                       'title'                => $form->{title},
+                       'attachment_basename'  => strftime('warehouse_journal_%Y%m%d', localtime time));
+  $report->set_options_from_form();
+
+  my $all_units = AM->retrieve_units(\%myconfig, $form);
+  my @contents  = WH->get_warehouse_journal(%filter);
+
+  foreach $entry (@contents) {
+    $entry->{qty}        = $form->format_amount_units('amount'     => $entry->{qty},
+                                                      'part_unit'  => $entry->{partunit},
+                                                      'conv_units' => 'convertible');
+    $entry->{trans_type} = $locale->text($entry->{trans_type});
+
+    my $row = { };
+
+    foreach my $column (@columns) {
+      next if ($column eq 'trans_type');
+
+      $row->{$column} = {
+        'data'  => $entry->{$column},
+        'align' => $column_alignment{$column},
+      };
+    }
+
+    $row->{trans_type} = {
+      'raw_data' => $entry->{trans_type},
+      'align'    => $column_alignment{trans_type},
+    };
+
+    $report->add_data($row);
+  }
+
+  $report->generate_with_headers();
+
+  $lxdebug->leave_sub();
+}
+
+# --------------------------------------------------------------------
+# Report
+# --------------------------------------------------------------------
+
+sub report {
+  $lxdebug->enter_sub();
+
+  $auth->assert('warehouse_content | warehouse_management');
+
+  $form->get_lists('warehouses' => { 'key'    => 'WAREHOUSES',
+                                     'bins'   => 'BINS', });
+
+  show_no_warehouses_error() if (!scalar @{ $form->{WAREHOUSES} });
+
+  $form->{onload} .= "fokus('partnumber');";
+  $form->{title}   = $locale->text("Report about wareouse contents");
+
+  $form->header();
+  print $form->parse_html_template("wh/report_filter",
+                                   { "nextsub"    => "generate_report",
+                                     "WAREHOUSES" => $form->{WAREHOUSES},
+                                     "UNITS"      => AM->unit_select_data(AM->retrieve_units(\%myconfig, $form)) });
+
+  $lxdebug->leave_sub();
+}
+
+sub generate_report {
+  $lxdebug->enter_sub();
+
+  $auth->assert('warehouse_content | warehouse_management');
+
+  $form->{title}   = $locale->text("Report about wareouse contents");
+  $form->{sort}  ||= 'partnumber';
+  my $sort_col     = $form->{sort};
+
+  my %filter;
+  my @columns = qw(warehousedescription bindescription partnumber partdescription chargenumber qty);
+
+  # filter stuff
+  map { $filter{$_} = $form->{$_} if ($form->{$_}) } qw(warehouse_id bin_id partnumber description chargenumber);
+
+  $filter{qty_op} = WH->convert_qty_op($form->{qty_op});
+  if ($filter{qty_op}) {
+    $form->isblank(qty,      $locale->text('Quantity missing.'));
+    $form->isblank(qty_unit, $locale->text('Unit missing.'));
+
+    $filter{qty}      = $form->{qty};
+    $filter{qty_unit} = $form->{qty_unit};
+  }
+  # /filter stuff
+
+  $form->{subtotal} = '' if (!first { $_ eq $sort_col } qw(partnumber partdescription));
+
+  my $report = SL::ReportGenerator->new(\%myconfig, $form);
+
+  my @hidden_variables = map { "l_${_}" } @columns;
+  push @hidden_variables, qw(warehouse_id bin_id partnumber description chargenumber qty_op qty qty_unit l_warehousedescription l_bindescription);
+  push @hidden_variables, qw(include_empty_bins subtotal);
+
+  my %column_defs = (
+    'warehousedescription' => { 'text' => $locale->text('Warehouse'), },
+    'bindescription'       => { 'text' => $locale->text('Bin'), },
+    'partnumber'           => { 'text' => $locale->text('Part Number'), },
+    'partdescription'      => { 'text' => $locale->text('Description'), },
+    'chargenumber'         => { 'text' => $locale->text('Charge Number'), },
+    'qty'                  => { 'text' => $locale->text('Qty'), },
+  );
+
+  my $href = build_std_url('action=generate_report', grep { $form->{$_} } @hidden_variables);
+  map { $column_defs{$_}->{link} = $href . "&sort=${_}&order=" . Q($_ eq $sort_col ? 1 - $form->{order} : $form->{order}) } @columns;
+
+  my %column_alignment = map { $_ => 'right' } qw(qty);
+
+  map { $column_defs{$_}->{visible} = $form->{"l_${_}"} ? 1 : 0 } @columns;
+
+  $report->set_columns(%column_defs);
+  $report->set_column_order(@columns);
+
+  $report->set_export_options('generate_report', @hidden_variables);
+
+  $report->set_sort_indicator($sort_col, $form->{order});
+
+  $report->set_options('output_format'        => 'HTML',
+                       'title'                => $form->{title},
+                       'attachment_basename'  => strftime('warehouse_report_%Y%m%d', localtime time));
+  $report->set_options_from_form();
+
+  my $all_units = AM->retrieve_units(\%myconfig, $form);
+  my @contents  = WH->get_warehouse_report(%filter);
+
+  my $subtotal  = 0;
+  my $idx       = 0;
+
+  foreach $entry (@contents) {
+    $subtotal     += $entry->{qty};
+    $entry->{qty}  = $form->format_amount_units('amount'     => $entry->{qty},
+                                                'part_unit'  => $entry->{partunit},
+                                                'conv_units' => 'convertible');
+
+    $row_set = [ { map { $_ => { 'data' => $entry->{$_}, 'align' => $column_alignment{$_} } } @columns } ];
+
+    if (($form->{subtotal} eq 'Y')
+        && (($idx == (scalar @contents - 1))
+            || ($entry->{$sort_col} ne $contents[$idx + 1]->{$sort_col}))) {
+
+      my $row = { map { $_ => { 'data' => '', 'class' => 'listsubtotal', 'align' => $column_alignment{$_}, } } @columns };
+      $row->{qty}->{data} = $form->format_amount_units('amount'     => $subtotal,
+                                                       'part_unit'  => $entry->{partunit},
+                                                       'conv_units' => 'convertible');
+      $subtotal = 0;
+
+      push @{ $row_set }, $row;
+    }
+
+    $report->add_data($row_set);
+
+    $idx++;
+  }
+
+  $report->generate_with_headers();
+
+  $lxdebug->leave_sub();
+}
+
+# --------------------------------------------------------------------
+# Utility functions
+# --------------------------------------------------------------------
+
+sub show_no_warehouses_error {
+  $lxdebug->enter_sub();
+
+  my $msg = $locale->text('No warehouse has been created yet.') . ' ';
+
+  if ($auth->check_right($form->{login}, 'config')) {
+    $msg .= $locale->text('You can create warehouses and bins via the menu "System -> Warehouses".');
+  } else {
+    $msg .= $locale->text('Please ask your administrator to create warehouses and bins.');
+  }
+
+  $form->show_generic_error($msg);
+
+  $lxdebug->leave_sub();
+}
+
+sub get_warehouse_idx {
+  my ($warehouse_id) = @_;
+
+  for (my $i = 0; $i < scalar @{$form->{WAREHOUSES}}; $i++) {
+    return $i if ($form->{WAREHOUSES}->[$i]->{id} == $warehouse_id);
+  }
+
+  return -1;
+}
+
+sub get_bin_idx {
+  my ($warehouse_index, $bin_id) = @_;
+
+  my $warehouse = $form->{WAREHOUSES}->[$warehouse_index];
+
+  return -1 if (!$warehouse);
+
+  for (my $i = 0; $i < scalar @{ $warehouse->{BINS} }; $i++) {
+    return $i if ($warehouse->{BINS}->[$i]->{id} == $bin_id);
+  }
+
+  return -1;
+}
+
+sub update {
+  call_sub($form->{update_nextsub} || $form->{nextsub});
+}
+
+sub continue {
+  call_sub($form->{continue_nextsub} || $form->{nextsub});
+}
+
+sub stock {
+  call_sub($form->{stock_nextsub} || $form->{nextsub});
+}
+
+1;
diff --git a/js/part_selection.js b/js/part_selection.js
new file mode 100644 (file)
index 0000000..8113e8b
--- /dev/null
@@ -0,0 +1,41 @@
+function part_selection_window(input_partnumber, input_description, input_partsid, allow_creation, formname, options) {
+  var width                   = allow_creation ? 1000 : 800;
+  var parm                    = centerParms(width,500) + ",width=" + width + ",height=500,status=yes,scrollbars=yes";
+  var partnumber              = document.getElementsByName(input_partnumber)[0].value;
+  var description             = document.getElementsByName(input_description)[0].value;
+  var action_on_part_selected = document.getElementsByName("action_on_part_selected")[0];
+  var form                    = (formname == undefined) ? document.forms[0] : document.getElementsByName(formname)[0];
+  var filter                  = document.getElementsByName(input_partnumber + "_filter")[0];
+  var input_partnotes         = "";
+
+  if (input_partnumber.match(/_\d+$/)) {
+    input_partnotes = input_partnumber;
+    input_partnotes = input_partnotes.replace(/partnumber/, "partnotes");
+    if (input_partnotes == input_partnumber)
+      input_partnoes = "";
+  }
+
+  if (filter)
+    filter = filter.value;
+  else
+    filter = "";
+
+  if (!options)
+    options = "";
+
+  url = "common.pl?" +
+    "action=part_selection_internal&" +
+    "partnumber="              + escape_more(partnumber)        + "&" +
+    "description="             + escape_more(description)       + "&" +
+    "input_partnumber="        + escape_more(input_partnumber)  + "&" +
+    "input_description="       + escape_more(input_description) + "&" +
+    "input_partsid="           + escape_more(input_partsid)     + "&" +
+    "input_partnotes="         + escape_more(input_partnotes)   + "&" +
+    "filter="                  + escape_more(filter)            + "&" +
+    "options="                 + escape_more(options)           + "&" +
+    "allow_creation="          + (allow_creation ? "1" : "0")   + "&" +
+    "action_on_part_selected=" + (null == action_on_part_selected ? "" : action_on_part_selected.value);
+  //alert(url);
+  window.open(url, "_new_part_selection", parm);
+}
+
index 5f98884..45cc5ac 100644 (file)
@@ -92,6 +92,7 @@ $self->{texts} = {
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No group has been selected, or the group does not exist anymore.' => 'Es wurde keine Gruppe ausgew&auml;hlt, oder die Gruppe wurde in der Zwischenzeit gel&ouml;scht.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No user has been selected.'  => 'Es wurde kein Benutzer ausgew&auml;hlt.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Nothing to delete!'          => 'Es konnte nichts gelöscht werden!',
@@ -101,6 +102,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
   'Proforma Invoice'            => 'Proformarechnung',
@@ -115,6 +118,7 @@ $self->{texts} = {
   'SCREENED'                    => 'Angezeigt',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Storno Invoice'              => 'Stornorechnung',
   'Storno Packing List'         => 'Stornolieferschein',
@@ -154,6 +158,8 @@ $self->{texts} = {
   'Value'                       => 'Wert',
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'bin_list'                    => 'Lagerliste',
@@ -227,6 +233,7 @@ $self->{subs} = {
   'mark_as_paid_common'         => 'mark_as_paid_common',
   'migrate_users'               => 'migrate_users',
   'no'                          => 'no',
+  'part_selection_internal'     => 'part_selection_internal',
   'pg_database_administration'  => 'pg_database_administration',
   'reformat_numbers'            => 'reformat_numbers',
   'remove_from_group'           => 'remove_from_group',
@@ -237,6 +244,8 @@ $self->{subs} = {
   'save_group'                  => 'save_group',
   'save_group_membership'       => 'save_group_membership',
   'save_user'                   => 'save_user',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
@@ -260,6 +269,7 @@ $self->{subs} = {
   'system_sperren'              => 'lock_system',
   'anmeldung'                   => 'login',
   'abmeldung'                   => 'logout',
+  'neue_ware'                   => 'new_part',
   'nein'                        => 'no',
   'datenbankadministration'     => 'pg_database_administration',
   'aus_gruppe_entfernen'        => 'remove_from_group',
index 8da9b53..ad0e204 100644 (file)
@@ -132,6 +132,7 @@ $self->{texts} = {
   'Add User'                    => 'Benutzer erfassen',
   'Add Vendor'                  => 'Lieferant erfassen',
   'Add Vendor Invoice'          => 'Einkaufsrechnung erfassen',
+  'Add Warehouse'               => 'Lager erfassen',
   'Add a new group'             => 'Neue Gruppe erfassen',
   'Add and edit %s'             => '%s hinzuf&uuml;gen und bearbeiten',
   'Add custom variable'         => 'Benutzerdefinierte Variable erfassen',
@@ -151,6 +152,7 @@ $self->{texts} = {
   'All reports'                 => 'Alle Berichte (Konten&uuml;bersicht, Saldenbilanz, GuV, BWA, Bilanz, Projektbuchungen)',
   'Allow access'                => 'Zugriff erlauben',
   'Allow the following users access to my follow-ups:' => 'Erlaube den folgenden Benutzern Zugriff auf meine Wiedervorlagen:',
+  'Alternatively you can create a new part which will then be selected.' => 'Sie k&ouml;nnen auch einen neuen Artikel anlegen, der dann automatisch ausgew&auml;hlt wird.',
   'Alternatively you can skip this step and create groups yourself.' => 'Alternativ k&ouml;nnen Sie diesen Schritt &uuml;berspringen und selber Gruppen anlegen.',
   'Amended Advance Turnover Tax Return' => 'Berichtigte Anmeldung',
   'Amended Advance Turnover Tax Return (Nr. 10)' => 'Ist dies eine berichtigte Anmeldung? (Nr. 10/Zeile 15 Steuererklärung)',
@@ -178,7 +180,9 @@ aktualisieren wollen?',
   'Assign new units'            => 'Neue Einheiten zuweisen',
   'Assign units'                => 'Einheiten zuweisen',
   'Assume Tax Consultant Data in Tax Computation?' => 'Beraterdaten in UStVA Ã¼bernehmen?',
+  'At least'                    => 'Mindestens',
   'At least one Perl module that Lx-Office ERP requires for running is not installed on your system.' => 'Mindestes ein Perl-Modul, das Lx-Office ERP zur Ausf&uuml;hrung ben&ouml;tigt, ist auf Ihrem System nicht installiert.',
+  'At most'                     => 'H&ouml;chstens',
   'Attach PDF:'                 => 'PDF anhängen',
   'Attachment'                  => 'als Anhang',
   'Attachment name'             => 'Name des Anhangs',
@@ -190,6 +194,7 @@ aktualisieren wollen?',
   'Authentification tables creation' => 'Anlegen der Tabellen zur Benutzerauthentifizierung',
   'Auto Send?'                  => 'Auto. Versand?',
   'Automatically created invoice for fee and interest for dunning %s' => 'Automatisch erzeugte Rechnung für Gebühren und Zinsen zu Mahnung %s',
+  'Available qty'               => 'Lagerbestand',
   'BOM'                         => 'Stückliste',
   'BWA'                         => 'BWA',
   'Back'                        => 'Zurück',
@@ -214,8 +219,12 @@ aktualisieren wollen?',
   'Bilanz'                      => 'Bilanz',
   'Billing Address'             => 'Rechnungsadresse',
   'Bin'                         => 'Lagerplatz',
+  'Bin From'                    => 'Quelllagerplatz',
   'Bin List'                    => 'Lagerliste',
+  'Bin To'                      => 'Ziellagerplatz',
   'Binding to the LDAP server as "#1" failed. Please check config/authentication.pl.' => 'Die Anmeldung am LDAP-Server als "#1" schlug fehl. Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/authentication.pl.',
+  'Bins saved.'                 => 'Lagerpl&auml;tze gespeichert.',
+  'Bins that have been used in the past cannot be deleted anymore. For these bins there\'s no checkbox in the &quot;Delete&quot; column.' => 'Lagerpl&auml;tze, die bereits benutzt wurden, k&ouml;nnen nicht mehr gel&ouml;scht werden. Deswegen fehlt bei ihnen die Checkbox in der Spalte &quot;L&ouml;schen&quot;.',
   'Birthday'                    => 'Geburtstag',
   'Bis'                         => 'bis',
   'Bis Konto: '                 => 'bis Konto: ',
@@ -272,6 +281,8 @@ aktualisieren wollen?',
   'Cash'                        => 'Zahlungsverkehr',
   'Cc'                          => 'Cc',
   'Change Lx-Office installation settings (all menu entries beneath \'System\')' => 'Ver&auml;ndern der Lx-Office-Installationseinstellungen (Men&uuml;punkte unterhalb von \'System\')',
+  'Charge Number'               => 'Chargennummer',
+  'Charge number'               => 'Chargennummer',
   'Chart Type'                  => 'Kontentyp',
   'Chart of Accounts'           => 'Kontenübersicht',
   'Chart of accounts'           => 'Kontenrahmen',
@@ -433,6 +444,9 @@ aktualisieren wollen?',
   Ã¶ffnet einzelne Kontendetails)',
   'Description missing!'        => 'Beschreibung fehlt.',
   'Description must not be empty!' => 'Beschreibung darf nicht leer sein',
+  'Destination bin'             => 'Ziellagerplatz',
+  'Destination warehouse'       => 'Ziellager',
+  'Destination warehouse and bin' => 'Ziellager und -lagerplatz',
   'Difference'                  => 'Differenz',
   'Dimension unit'              => 'Ma&szlig;einheit',
   'Dimension units'             => 'Ma&szlig;einheiten',
@@ -442,6 +456,7 @@ aktualisieren wollen?',
   'Display file'                => 'Datei anzeigen',
   'Display options'             => 'Anzeigeoptionen',
   'Do you really want to delete this group:' => 'Wollen Sie wirklich diese Gruppe l&ouml;schen:',
+  'Do you really want to delete this warehouse?' => 'Wollen Sie dieses Lager wirklich l&ouml;schen?',
   'Do you want Lx-Office to create a group for access to all functions?' => 'Wollen Sie, dass Lx-Office eine Gruppe mit Zugriff auf alle Funktionen anlegt?',
   'Do you want to <b>limit</b> your search?' => 'Wollen Sie Ihre Suche <b>spezialisieren</b>?',
   'Do you want to carry this shipping address over to the new purchase order so that the vendor can deliver the goods directly to your customer?' => 'Wollen Sie diese Lieferadresse in den neuen Lieferantenauftrag &uuml;bernehmen, damit der H&auml;ndler die Waren direkt an Ihren Kunden liefern kann?',
@@ -494,6 +509,7 @@ aktualisieren wollen?',
   'Edit Accounts Payables Transaction' => 'Kreditorenbuchung bearbeiten',
   'Edit Accounts Receivables Transaction' => 'Debitorenbuchung bearbeiten',
   'Edit Assembly'               => 'Erzeugnis bearbeiten',
+  'Edit Bins'                   => 'Lagerpl&auml;tze bearbeiten',
   'Edit Buchungsgruppe'         => 'Buchungsgruppe bearbeiten',
   'Edit Business'               => 'Kunden-/Lieferantentyp bearbeiten',
   'Edit Credit Note'            => 'Gutschrift bearbeiten',
@@ -525,6 +541,7 @@ aktualisieren wollen?',
   'Edit User'                   => 'Benutzerdaten bearbeiten',
   'Edit Vendor'                 => 'Lieferant editieren',
   'Edit Vendor Invoice'         => 'Einkaufsrechnung bearbeiten',
+  'Edit Warehouse'              => 'Lager bearbeiten',
   'Edit and delete a group'     => 'Gruppen bearbeiten und l&ouml;schen',
   'Edit custom variable'        => 'Benutzerdefinierte Variable bearbeiten',
   'Edit file'                   => 'Datei bearbeiten',
@@ -554,6 +571,7 @@ aktualisieren wollen?',
   'Ertrag'                      => 'Ertrag',
   'Ertrag prozentual'           => 'Ertrag prozentual',
   'Escape character'            => 'Escape-Zeichen',
+  'Exact'                       => 'Genau',
   'Exch'                        => 'Wechselkurs.',
   'Exchangerate'                => 'Wechselkurs',
   'Exchangerate Difference'     => 'Wechselkursunterschied',
@@ -586,6 +604,7 @@ aktualisieren wollen?',
   'Fee'                         => 'Gebühr',
   'File'                        => 'Datei',
   'Files created by Lx-Office\'s &quot;Backup Dataset&quot; function are such files.' => 'Dateien, die von Lx-Office\' Funktion &quot;Datenbank sichern&quot; erstellt wurden, erf&uuml;llen diese Kriterien.',
+  'Filter'                      => 'Filter',
   'Finish'                      => 'Abschlie&szlig;en',
   'Folgekonto'                  => 'Folgekonto',
   'Follow-Up'                   => 'Wiedervorlage',
@@ -609,6 +628,7 @@ aktualisieren wollen?',
   'Free-form text'              => 'Textzeile',
   'Fristsetzung'                => 'Fristsetzung',
   'From'                        => 'Von',
+  'From Date'                   => 'Von',
   'Full Access'                 => 'Vollzugriff',
   'Full access to all functions' => 'Vollzugriff auf alle Funktionen',
   'GL Transaction'              => 'Dialogbuchung',
@@ -637,6 +657,7 @@ aktualisieren wollen?',
   'History Search Engine'       => 'Historien Suchmaschine',
   'Homepage'                    => 'Homepage',
   'Host'                        => 'Datenbankcomputer',
+  'However, you can create a new part which will then be selected.' => 'Sie k&ouml;nnen jedoch einen neuen Artikel anlegen, der dann automatisch ausgew&auml;hlt wird.',
   'I'                           => 'I',
   'ID'                          => 'Buchungsnummer',
   'ID-Nummer'                   => 'ID-Nummer (intern)',
@@ -646,6 +667,7 @@ aktualisieren wollen?',
   'If the automatic creation of invoices for fees and interest is switched on for a dunning level then the following accounts will be used for the invoice.' => 'Wenn das automatische Erstellen einer Rechnung &uuml;ber Mahngeb&uuml;hren und Zinsen f&uuml;r ein Mahnlevel aktiviert ist, so werden die folgenden Konten f&uuml;r die Rechnung benutzt.',
   'If the database user listed above does not have the right to create a database then enter the name and password of the superuser below:' => 'Falls der oben genannte Datenbankbenutzer nicht die Berechtigung zum Anlegen neuer Datenbanken hat, so k&ouml;nnen Sie hier den Namen und das Passwort des Datenbankadministratoraccounts angeben:',
   'If you chose to let Lx-Office do the migration then Lx-Office will also remove the old member file after creating a backup copy of it in the directory &quot;[% HTML.escape(backupdir) %]&quot;.' => 'Falls Sie sich entscheiden, Lx-Office die Migration durchf&uuml;hren zu lassen, so wird Lx-Office ein Backup der alten Dateien im Verzeichnis &quot;[% HTML.escape(backupdir) %]&quot; erstellen und die Dateien anschlie&szlig;end l&ouml;schen.',
+  'If you enter values for the part number and / or part description then only those bins containing parts whose part number or part description match your input will be shown.' => 'Wenn Sie f&uuml;r die Artikelnummer und / oder die Beschreibung etwas eingeben, so werden nur die Lagerpl&auml;tze angezeigt, in denen Waren eingelagert sind, die Ihre Suchbegriffe enthalten.',
   'If you see this message, you most likely just setup your LX-Office and haven\'t added any entry types. If this is the case, the option is accessible for administrators in the System menu.' => 'Wenn Sie diese Meldung sehen haben Sie wahrscheinlich ein frisches LX-Office Setup und noch keine Buchungsgruppen eingerichtet. Ein Administrator kann dies im Systemmen&uuml; erledigen.',
   'If you want to change any of these parameters then press the &quot;Back&quot; button, edit the file &quot;config/authentication.pl&quot; and login into the admin module again.' => 'Wenn Sie einen der Parameter &auml;ndern wollen, so dr&uuml;cken Sie auf den &quot;Zur&uuml;ck&quot;-Button, bearbeiten Sie die Datei &quot;config/authentication.pl&quot;, und melden Sie sich erneut im Administrationsbereich an.',
   'If you want to delete such a dataset you have to edit the user(s) that are using the dataset in question and have them use another dataset.' => 'Wenn Sie eine solche Datenbank l&ouml;schen wollen, so m&uuml;ssen Sie zuerst die Benutzer bearbeiten, die die fragliche Datenbank benutzen, und sie so &auml;ndern, dass sie eine andere Datenbank benutzen.',
@@ -658,6 +680,7 @@ aktualisieren wollen?',
   'Inactive'                    => 'Inaktiv',
   'Include Exchangerate Difference' => 'Wechselkursunterschied einbeziehen',
   'Include column headings'     => 'Spalten&uuml;berschriften erzeugen',
+  'Include empty bins'          => 'Leere Lagerpl&auml;tze anzeigen',
   'Include in Report'           => 'In Bericht aufnehmen',
   'Include in drop-down menus'  => 'In Aufklappmenü aufnehmen',
   'Includeable in reports'      => 'In Berichten anzeigbar',
@@ -678,7 +701,9 @@ aktualisieren wollen?',
   'Introduction of Buchungsgruppen' => 'Einf&uuml;hrung von Buchungsgruppen',
   'Introduction of units'       => 'Einf&uuml;hrung von Einheiten',
   'Inv. Duedate'                => 'Rg. Fälligkeit',
+  'Invalid'                     => 'Ung&uuml;ltig',
   'Invalid follow-up ID.'       => 'Ung&uuml;ltige Wiedervorlage-ID.',
+  'Invalid quantity.'           => 'Die Mengenangabe ist ung&uuml;ltig.',
   'Invdate'                     => 'Rechnungsdatum',
   'Invdate from'                => 'Rechnungen von',
   'Inventory'                   => 'Inventar',
@@ -754,6 +779,7 @@ aktualisieren wollen?',
   'Licensed to'                 => 'Lizensiert für',
   'Licenses'                    => 'Lizenzen',
   'Lieferungen'                 => 'Lieferungen',
+  'Limit part selection'        => 'Artikelauswahl eingrenzen',
   'Line Total'                  => 'Zeilensumme',
   'Line endings'                => 'Zeilenumbr&uuml;che',
   'List Accounting Groups'      => 'Buchungsgruppen anzeigen',
@@ -771,6 +797,7 @@ aktualisieren wollen?',
   'List Printer'                => 'Drucker anzeigen',
   'List Tax'                    => 'Bearbeiten',
   'List Transactions'           => 'Buchungsliste',
+  'List Warehouses'             => 'Lager anzeigen',
   'List of custom variables'    => 'Liste der benutzerdefinierten Variablen',
   'Load draft'                  => 'Entwurf laden',
   'Local Tax Office Preferences' => 'Angaben zum Finanzamt',
@@ -856,6 +883,7 @@ aktualisieren wollen?',
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No action defined.'          => 'Keine Aktion definiert.',
   'No backup file has been uploaded.' => 'Es wurde keine Sicherungsdatei hochgeladen.',
+  'No bins have been added to this warehouse yet.' => 'Es wurden zu diesem Lager noch keine Lagerpl&auml;tze angelegt.',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No data was found.'          => 'Es wurden keine Daten gefunden.',
   'No databases have been found on this server.' => 'Auf diesem Server wurden keine Datenbanken gefunden.',
@@ -866,9 +894,11 @@ aktualisieren wollen?',
   'No groups have been added yet.' => 'Es wurden noch keine Gruppen angelegt.',
   'No licenses were found that match the search criteria.' => 'Es wurden keine Lizenzen gefunden, auf die die Suchkriterien zutreffen.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No unknown units where found.' => 'Es wurden keine unbekannten Einheiten gefunden.',
   'No user has been selected.'  => 'Es wurde kein Benutzer ausgew&auml;hlt.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
+  'No warehouse has been created yet.' => 'Es wurde noch kein Lager angelegt.',
   'No.'                         => 'Position',
   'Non-taxable Purchases'       => 'Nicht zu versteuernde Einkäufe',
   'Non-taxable Sales'           => 'Nicht zu versteuernde Verkäufe',
@@ -879,6 +909,8 @@ aktualisieren wollen?',
   'Not obsolete'                => 'Gültig',
   'Note'                        => 'Hinweis',
   'Notes'                       => 'Bemerkungen',
+  'Nothing has been selected for removal.' => 'Es wurde nichts f&uuml;r eine Entnahme ausgew&auml;hlt.',
+  'Nothing has been selected for transfer.' => 'Es wurde nichts zum Umlagern ausgew&auml;hlt.',
   'Nothing selected!'           => 'Es wurde nichts ausgewählt!',
   'Nothing to delete!'          => 'Es konnte nichts gelöscht werden!',
   'Nov'                         => 'Nov',
@@ -887,7 +919,9 @@ aktualisieren wollen?',
   'Number'                      => 'Nummer',
   'Number Format'               => 'Zahlenformat',
   'Number missing in Row'       => 'Nummer fehlt in Zeile',
+  'Number of bins'              => 'Anzahl Lagerpl&auml;tze',
   'Number of copies'            => 'Anzahl Kopien',
+  'Number of new bins'          => 'Anzahl neuer Lagerpl&auml;tze',
   'Number pages'                => 'Seiten nummerieren',
   'Number variables: \'PRECISION=n\' forces numbers to be shown with exactly n decimal places.' => 'Zahlenvariablen: Mit \'PRECISION=n\' erzwingt man, dass Zahlen mit n Nachkommastellen formatiert werden.',
   'OBE-Export erfolgreich!'     => 'OBE-Export erfolgreich!',
@@ -904,6 +938,7 @@ aktualisieren wollen?',
   'Open'                        => 'Offen',
   'OpenDocument/OASIS'          => 'OpenDocument/OASIS',
   'Openings'                    => 'Öffnungszeiten',
+  'Optional comment'            => 'Optionaler Kommentar',
   'Options'                     => 'Optionen',
   'Order'                       => 'Auftrag',
   'Order Date'                  => 'Auftragsdatum',
@@ -942,6 +977,7 @@ aktualisieren wollen?',
   'Part Description missing!'   => 'Artikelbezeichnung fehlt!',
   'Part Number'                 => 'Artikelnummer',
   'Part Number missing!'        => 'Artikelnummer fehlt!',
+  'Part description'            => 'Artikelbeschreibung',
   'Partnumber must not be set to empty!' => 'Die Artikelnummer darf nicht auf leer ge&auml;ndert werden.',
   'Partnumber not unique!'      => 'Artikelnummer bereits vorhanden!',
   'Parts'                       => 'Waren',
@@ -960,11 +996,13 @@ aktualisieren wollen?',
   'Payments'                    => 'Zahlungsausgänge',
   'Period'                      => 'Zeitraum',
   'Personal settings'           => 'Pers&ouml;nliche Einstellungen',
+  'Personal warehouse of'       => 'Personenlager von',
   'Pg Database Administration'  => 'Datenbankadministration',
   'Phone'                       => 'Telefon',
   'Phone1'                      => 'Telefon 1 ',
   'Phone2'                      => 'Telefon 2',
   'Pick List'                   => 'Sammelliste',
+  'Please ask your administrator to create warehouses and bins.' => 'Bitten Sie Ihren Administrator, dass er Lager und Lagerpl&auml;tze anlegt.',
   'Please enter a license key.' => 'Bitte geben Sie einen Lizenzschlüssel an.',
   'Please enter a number of licenses.' => 'Bitte geben Sie die Anzahl Lizenzschlüssel an.',
   'Please enter the name of the database that will be used as the template for the new database:' => 'Bitte geben Sie den Namen der Datenbank an, die als Vorlage f&uuml;r die neue Datenbank benutzt wird:',
@@ -977,6 +1015,7 @@ aktualisieren wollen?',
   'Please insert your longdescription below' => 'Bitte den Langtext eingeben',
   'Please install the below listed modules or ask your system administrator to.' => 'Bitte installieren Sie die unten aufgef&uuml;hrten Module, oder bitten Sie Ihren Administrator darum.',
   'Please select a customer from the list below.' => 'Bitte einen Endkunden aus der Liste auswählen',
+  'Please select a part from the list below.' => 'Bitte w&auml;hlen Sie einen Artikel aus der Liste aus.',
   'Please select a vendor from the list below.' => 'Bitte einen Händler aus der Liste auswählen',
   'Please select the chart of accounts this installation is using from the list below.' => 'Bitte w&auml;hlen Sie den Kontenrahmen aus, der bei dieser Installation verwendet wird.',
   'Please select the database you want to backup' => 'Bitte w&auml;hlen Sie die zu sichernde Datenbank gefunden',
@@ -990,6 +1029,7 @@ aktualisieren wollen?',
   'Posustva_coa'                => 'USTVA Kennz.',
   'Preferences'                 => 'Benutzereinstellungen',
   'Preferences saved!'          => 'Einstellungen gespeichert!',
+  'Prefix for the new bins\' names' => 'Namenspr&auml;fix f&uuml;r die neuen Lagerpl&auml;tze',
   'Preis'                       => 'Preis',
   'Preisgruppe'                 => 'Preisgruppe',
   'Preisklasse'                 => 'Preisgruppe',
@@ -1041,7 +1081,9 @@ aktualisieren wollen?',
   'Purchase Order'              => 'Lieferantenauftrag',
   'Purchase Orders'             => 'Lieferantenaufträge',
   'Qty'                         => 'Menge',
+  'Qty in stock'                => 'Lagerbestand',
   'Quantity'                    => 'Menge',
+  'Quantity missing.'           => 'Die Mengenangabe fehlt.',
   'Quartal'                     => 'Quartal',
   'Quarter'                     => 'Quartal',
   'Quarterly'                   => 'quartalsweise',
@@ -1072,7 +1114,11 @@ aktualisieren wollen?',
   'Reference'                   => 'Referenz',
   'Reference missing!'          => 'Referenz fehlt!',
   'Remaining'                   => 'Rest',
-  'Remove'                      => 'entfernen',
+  'Removal'                     => 'Entnahme',
+  'Removal from Warehouse'      => 'Lagerentnahme',
+  'Removal from warehouse'      => 'Entnahme aus Lager',
+  'Removal qty'                 => 'Entnahmemenge',
+  'Remove'                      => 'Entfernen',
   'Remove Draft'                => 'Entwurf l&ouml;schen',
   'Remove draft when posting'   => 'Entwurf beim Buchen l&ouml;schen',
   'Remove from group'           => 'Aus Gruppe entfernen',
@@ -1080,6 +1126,8 @@ aktualisieren wollen?',
   'Removing marked entries from queue ...' => 'Markierte Einträge werden von der Warteschlange entfernt ...',
   'Rename the group'            => 'Gruppe umbenennen',
   'Report Positions'            => 'Berichte',
+  'Report about wareouse contents' => 'Bericht &uuml;ber eingelagerte Waren',
+  'Report about wareouse transactions' => 'Bericht &uuml;ber Lagerbewegungen',
   'Report and misc. Preferences' => 'Sonstige Einstellungen',
   'Report for'                  => 'Bericht für',
   'Reports'                     => 'Berichte',
@@ -1129,6 +1177,7 @@ aktualisieren wollen?',
   'Select'                      => 'auswählen',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a period'             => 'Bitte Zeitraum auswählen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select all'                  => 'Alle auswählen',
@@ -1138,6 +1187,8 @@ aktualisieren wollen?',
   'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
   'Select the chart of accounts in use' => 'Benutzten Kontenrahmen ausw&auml;hlen',
   'Select the checkboxes that match users to the groups they should belong to.' => 'W&auml;hlen Sie diejenigen Checkboxen aus, die die Benutzer zu den gew&uuml;schten Gruppen zuordnen.',
+  'Select type of removal'      => 'Grund der Entnahme ausw&auml;hlen',
+  'Select type of transfer'     => 'Grund der Umlagerung ausw&auml;hlen',
   'Selection'                   => 'Auswahlbox',
   'Selection fields: The option field must contain the available options for the selection. Options are separated by \'##\', for example \'Early##Normal##Late\'.' => 'Auswahlboxen: Das Optionenfeld muss die f&uuml;r die Auswahl verf&uuml;gbaren Eintr&auml;ge enthalten. Die Eintr&auml;ge werden mit \'##\' voneinander getrennt. Beispiel: \'Fr&uuml;h##Normal##Sp&auml;t\'.',
   'Sell Price'                  => 'Verkaufspreis',
@@ -1180,6 +1231,7 @@ aktualisieren wollen?',
   'Skonto Terms'                => 'Zahlungsziel Skonto',
   'Sold'                        => 'Verkauft',
   'Source'                      => 'Beleg',
+  'Source bin'                  => 'Quelllagerplatz',
   'Spoolfile'                   => 'Druckdatei',
   'Start Dunning Process'       => 'Mahnprozess starten',
   'Startdate_coa'               => 'Gültig ab',
@@ -1192,7 +1244,7 @@ aktualisieren wollen?',
   'Step 3 of 3: Assemblies'     => 'Schritt 3 von 3: Erzeugnisse',
   'Step 3 of 3: Default units'  => 'Schritt 3 von 3: Standardeinheiten',
   'Steuersatz'                  => 'Steuersatz',
-  'Stock'                       => 'einlagern',
+  'Stock'                       => 'Einlagern',
   'Storno'                      => 'Storno',
   'Storno (one letter abbreviation)' => 'S',
   'Storno Invoice'              => 'Stornorechnung',
@@ -1311,6 +1363,9 @@ aktualisieren wollen?',
   'The name must only consist of letters, numbers and underscores and start with a letter.' => 'Der Name darf nur aus Buchstaben (keine Umlaute), Ziffern und Unterstrichen bestehen und muss mit einem Buchstaben beginnen.',
   'The old file containing the user information is still present (&quot;[% HTML.escape(memberfile) %]&quot;). Do you want to migrate these users into the database? If not then you will not be able to log in with any of the users present in the old file. ' => 'Die alte Datei mit den Benutzerdaten existiert in dieser Installation noch immer (&quot;[% HTML.escape(memberfile) %]&quot;). Wollen Sie diese Benutzer in die neue Authentifizierungsdatenbank migrieren lassen? Falls nicht, so werden Sie sich nicht mehr mit den Benutzerdaten aus der alten Mitgliedsdatei anmelden k&ouml;nnen.',
   'The option field is empty.'  => 'Das Optionsfeld ist leer.',
+  'The parts have been removed.' => 'Die Waren wurden aus dem Lager entnommen.',
+  'The parts have been stocked.' => 'Die Artikel wurden eingelagert.',
+  'The parts have been transferred.' => 'Die Waren wurden umgelagert.',
   'The pg_dump process could not be started.' => 'Der pg_dump-Prozess konnte nicht gestartet werden.',
   'The pg_restore process could not be started.' => 'Der pg_restore-Prozess konnte nicht gestartet werden.',
   'The preferred one is to install packages provided by your operating system distribution (e.g. Debian or RPM packages).' => 'Die bevorzugte Art, ein Perl-Modul zu installieren, ist durch Installation eines von Ihrem Betriebssystem zur Verf&uuml;gung gestellten Paketes (z.B. Debian-Pakete oder RPM).',
@@ -1318,7 +1373,11 @@ aktualisieren wollen?',
   'The restoration process has started. Here\'s the output of the &quot;pg_restore&quot; command:' => 'Der Wiederherstellungsprozess wurde gestartet. Hier ist die Ausgabe des &quot;pg_restore&quot;-Programmes:',
   'The restoration process is complete. Please review &quot;pg_restore&quot;\'s output to find out if the restoration was successful.' => 'Die Wiederherstellung ist abgeschlossen. Bitte sehen Sie sich die Ausgabe von &quot;pg_restore&quot; an, um festzustellen, ob die Wiederherstellung erfolgreich war.',
   'The second way is to use Perl\'s CPAN module and let it download and install the module for you.' => 'Die zweite Variante besteht darin, Perls CPAN-Modul zu benutzen und es das Modul f&uuml;r Sie installieren zu lassen.',
+  'The selected bin does not exist.' => 'Der ausgew&auml;hlte Lagerplatz existiert nicht.',
+  'The selected warehouse does not exist.' => 'Das ausgew&auml;hlte Lager existiert nicht.',
+  'The selected warehouse is empty.' => 'Das ausgew&auml;hlte Lager ist leer.',
   'The session is invalid or has expired.' => 'Die Session ist ung&uuml;ltig oder abgelaufen.',
+  'The source warehouse does not contain any bins.' => 'Das Quelllager enth&auml;lt keine Lagerpl&auml;tze.',
   'The subject is missing.'     => 'Der Betreff fehlt.',
   'The tables for user management and authentication do not exist. They will be created in the next step in the following database:' => 'Die Tabellen zum Speichern der Benutzerdaten und zur Benutzerauthentifizierung wurden nicht gefunden. Sie werden in der folgenden Datenbank angelegt:',
   'The tabulator character'     => 'Das Tabulator-Symbol',
@@ -1332,11 +1391,15 @@ aktualisieren wollen?',
   'The user is a member in the following group(s):' => 'Der Benutzer ist Mitglied in den folgenden Gruppen:',
   'The user migration process is complete.' => 'Der Prozess der Benutzerdatenmigration ist abgeschlossen.',
   'The variable name must only consist of letters, numbers and underscores. It must begin with a letter. Example: send_christmas_present' => 'Der Variablenname darf nur aus Zeichen (keine Umlaute), Ziffern und Unterstrichen bestehen. Er muss mit einem Buchstaben beginnen. Beispiel: weihnachtsgruss_verschicken',
+  'The warehouse could not be deleted because it has already been used.' => 'Das Lager konnte nicht gel&ouml;scht werden, da es bereits in Benutzung war.',
+  'The warehouse does not contain any bins.' => 'Das Lager enth&auml;lt keine Lagerpl&auml;tze.',
+  'The warehouse or the bin is missing.' => 'Das Lager oder der Lagerplatz fehlen.',
   'There are #1 unfinished follow-ups of which #2 are due.' => 'Es gibt #1 Wiedervorlage(n), von denen #2 f&auml;llig ist/sind.',
   'There are four tax zones.'   => 'Es gibt vier Steuerzonen.',
   'There are no items on your TODO list at the moment.' => 'Ihre Aufgabenliste enth&auml;lt momentan keine Eintr&auml;ge.',
   'There are still entries in the database for which no unit has been assigned.' => 'Es gibt noch Eintr&auml;ge in der Datenbank, f&uuml;r die keine Einheit zugeordnet ist.',
   'There are usually three ways to install Perl modules.' => 'Es gibt normalerweise drei Arten, ein Perlmodul zu installieren.',
+  'There is not enough left of \'#1\' in bin \'#2\' for the removal of #3.' => 'In Lagerplatz \'#2\' ist nicht genug von \'#1\' vorhanden, um #3 zu entnehmen.',
   'There is nothing to do in this step.' => 'In diesem Schritt gibt es nichts mehr zu tun.',
   'Therefore there\'s no need to create the same article more than once if it is sold or bought in/from another tax zone.' => 'Deswegen muss man den gleichen Artikel nicht mehr mehrmals anlegen, wenn er in verschiedenen Steuerzonen gehandelt werden soll.',
   'These units can be based on other units so that Lx-Office can convert prices when the user switches from one unit to another.' => 'Diese Einheiten k&ouml;nnen auf anderen Einheiten basieren, sodass Lx-Office Preise umrechnen kann, wenn der Benutzer von einer Einheit zu einer anderen Wechselt.',
@@ -1353,6 +1416,7 @@ aktualisieren wollen?',
   'To'                          => 'An',
   'To (email)'                  => 'An',
   'To (time)'                   => 'Bis',
+  'To Date'                     => 'Bis',
   'To add a user to a group edit a name, change the login name and save. A new user with the same variables will then be saved under the new login name.' => 'Um einer Gruppe einen neuen Benutzer hinzuzuf&uuml;gen, &auml;ndern und speichern Sie am einfachsten einen bestehen den Zugriffsnamen. Unter dem neuen Namen wird dann ein Benutzer mit denselben Einstellungen angelegt.',
   'Top'                         => 'Oben',
   'Top (CSS)'                   => 'Oben (mit CSS)',
@@ -1363,6 +1427,8 @@ aktualisieren wollen?',
   'Total'                       => 'Summe',
   'Total Fees'                  => 'Kumulierte Gebühren',
   'Trade Discount'              => 'Rabatt',
+  'Trans Id'                    => 'Trans-ID',
+  'Trans Type'                  => 'Trasfertyp',
   'Transaction %d cancelled.'   => 'Buchung %d erfolgreich storniert.',
   'Transaction Date missing!'   => 'Buchungsdatum fehlt!',
   'Transaction deleted!'        => 'Buchung gelöscht!',
@@ -1372,6 +1438,10 @@ aktualisieren wollen?',
   'Transaction reversal enforced for all dates' => 'Fehleintragungen müssen für jeden Zeitraum mit einer Kontraeintragung ausgebessert werden',
   'Transaction reversal enforced up to' => 'Fehleintragungen können bis zu dem angegebenen Zeitraum nur mit einer Kontraeintragung ausgebessert werden!',
   'Transactions, AR transactions, AP transactions' => 'Dialogbuchen, Debitorenrechnungen, Kreditorenrechnungen',
+  'Transfer'                    => 'Umlagern',
+  'Transfer Quantity'           => 'Umlagermenge',
+  'Transfer from warehouse'     => 'Quelllager',
+  'Transfer qty'                => 'Umlagermenge',
   'Translation (%s)'            => '&Uuml;bersetzung (%s)',
   'Trial Balance'               => 'Saldenbilanz',
   'Trying to call a sub without a name' => 'Es wurde versucht, eine Unterfunktion ohne Namen aufzurufen.',
@@ -1392,6 +1462,7 @@ aktualisieren wollen?',
   'Unbalanced Ledger'           => 'Bilanzfehler',
   'Unfinished follow-ups'       => 'Nicht erledigte Wiedervorlagen',
   'Unit'                        => 'Einheit',
+  'Unit missing.'               => 'Die Einheit fehlt.',
   'Unit of measure'             => 'Maßeinheit',
   'Units'                       => 'Einheiten',
   'Unknown Category'            => 'Unbekannte Kategorie',
@@ -1438,8 +1509,18 @@ aktualisieren wollen?',
   'Verrechnungseinheit'         => 'Verrechnungseinheit',
   'Version'                     => 'Version',
   'View License'                => 'Lizenz ansehen',
+  'View warehouse content'      => 'Lagerbestand ansehen',
   'Von Konto: '                 => 'von Konto: ',
   'WEBDAV access'               => 'WEBDAV-Zugriff',
+  'WHJournal'                   => 'Lagerbuchungen',
+  'Warehouse'                   => 'Lager',
+  'Warehouse From'              => 'Quelllager',
+  'Warehouse To'                => 'Ziellager',
+  'Warehouse content'           => 'Lagerbestand',
+  'Warehouse deleted.'          => 'Lager gel&ouml;scht.',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
+  'Warehouse saved.'            => 'Lager gespeichert.',
+  'Warehouses'                  => 'L&auml;ger',
   'Warnings during template upgrade' => 'Warnungen bei Aktualisierung der Dokumentenvorlagen',
   'Weight'                      => 'Gewicht',
   'What type of item is this?'  => 'Was ist dieser Artikel?',
@@ -1462,6 +1543,7 @@ aktualisieren wollen?',
   'You are logged out!'         => 'Auf Wiedersehen!',
   'You can also create new units now.' => 'Sie k&ouml;nnen jetzt auch neue Einheiten anlegen.',
   'You can create a missing dataset by going back and chosing &quot;Create Dataset&quot;.' => 'Sie k&ouml;nnen eine fehlende Datenbank erstellen, indem Sie jetzt zu&uuml;ck gehen und den Punkt &quot;Datenbank anlegen&quot; w&auml;hlen.',
+  'You can create warehouses and bins via the menu "System -> Warehouses".' => 'Sie k&ouml;nnen Lager und Lagerpl&auml;tze &uuml;ber das Men&uuml; "System -> Lager" anlegen.',
   'You can only delete datasets that are not in use.' => 'Sie k&ouml;nnen nur Datenbanken l&ouml;schen, die momentan nicht in Benutzung sind.',
   'You can use the following strings in the long description and all translations. They will be replaced by their actual values by Lx-Office before they\'re output.' => 'Sie k&ouml;nnen im Langtext und allen Ãœbersetzungen die folgenden Variablen benutzen, die vor der Ausgabe von Lx-Office automatisch ersetzt werden:',
   'You cannot continue before all required modules are installed.' => 'Sie k&ouml;nnen nicht fortfahren, bevor alle ben&ouml;tigten Pakete installiert sind.',
@@ -1505,6 +1587,7 @@ aktualisieren wollen?',
   'config/authentication.pl: Missing parameters in "DB_config". Required parameters are "host", "db" and "user".' => 'config/authentication.pl: Fehlende Parameter in "DB_config". Ben&ouml;tigte Parameter sind "host", "db" und "user".',
   'config/authentication.pl: Missing parameters in "LDAP_config". Required parameters are "host", "attribute" and "base_dn".' => 'config/authentication.pl: Fehlende Parameter in "LDAP_config". Ben&ouml;tigt werden "host", "attribute" und "base_dn".',
   'continue'                    => 'weiter',
+  'correction'                  => 'Korrektur',
   'customer'                    => 'Kunde',
   'customer_list'               => 'kundenliste',
   'customernumber not unique!'  => 'Die Kundennummer ist schon vergeben',
@@ -1512,6 +1595,7 @@ aktualisieren wollen?',
   'delete'                      => 'Löschen',
   'deliverydate'                => 'Lieferdatum',
   'dimension units'             => 'Ma&szlig;einheiten',
+  'disposed'                    => 'Entsorgung',
   'done'                        => 'erledigt',
   'down'                        => 'runter',
   'drucken'                     => 'drucken',
@@ -1523,6 +1607,7 @@ aktualisieren wollen?',
   'follow_up_list'              => 'wiedervorlageliste',
   'for'                         => 'f&uuml;r',
   'for Period'                  => 'für den Zeitraum',
+  'found'                       => 'Gefunden',
   'from (time)'                 => 'von',
   'general_ledger_list'         => 'buchungsjournal',
   'history'                     => 'Historie',
@@ -1538,6 +1623,7 @@ aktualisieren wollen?',
   'list_of_transactions'        => 'buchungsliste',
   'logout'                      => 'abmelden',
   'mark as paid'                => 'als bezahlt markieren',
+  'missing'                     => 'Fehlbestand',
   'month'                       => 'Monatliche Abgabe',
   'new Window'                  => 'neues Fenster',
   'no'                          => 'nein',
@@ -1560,10 +1646,12 @@ aktualisieren wollen?',
   'purchase_order_list'         => 'lieferantenauftragsliste',
   'quarter'                     => 'Vierteljährliche (quartalsweise) Abgabe',
   'quotation_list'              => 'angebotsliste',
+  'release_material'            => 'Materialausgabebe',
   'report_generator_dispatch_to is not defined.' => 'report_generator_dispatch_to ist nicht definiert.',
   'report_generator_nextsub is not defined.' => 'report_generator_nextsub ist nicht definiert.',
   'request_quotation'           => 'Angebotsanforderung',
   'reset'                       => 'zurücksetzen',
+  'return_material'             => 'Materialr&uuml;ckgabe',
   'rfq_list'                    => 'anfragenliste',
   'sales_order'                 => 'Kundenauftrag',
   'sales_order_list'            => 'auftragsliste',
@@ -1576,6 +1664,7 @@ aktualisieren wollen?',
   'service_list'                => 'dienstleistungsliste',
   'singular first char'         => 'S',
   'soldtotal'                   => 'Verkaufte Anzahl',
+  'stock'                       => 'Einlagerung',
   'submit'                      => 'abschicken',
   'tax_chartaccno'              => 'Automatikkonto',
   'tax_percent'                 => 'Prozentsatz',
@@ -1585,8 +1674,10 @@ aktualisieren wollen?',
   'taxnumber'                   => 'Automatikkonto',
   'to (date)'                   => 'bis',
   'to (time)'                   => 'bis',
+  'transfer'                    => 'Umlagerung',
   'up'                          => 'hoch',
   'use program settings'        => 'benutze Programmeinstellungen',
+  'used'                        => 'Verbraucht',
   'valid from'                  => 'Gültig ab',
   'vendor'                      => 'Lieferant',
   'vendor_list'                 => 'lieferantenliste',
index c799992..aef0998 100644 (file)
@@ -59,6 +59,7 @@ $self->{texts} = {
   'Add Payment Terms'           => 'Zahlungskonditionen hinzufügen',
   'Add Price Factor'            => 'Preisfaktor erfassen',
   'Add Printer'                 => 'Drucker hinzufügen',
+  'Add Warehouse'               => 'Lager erfassen',
   'Add and edit %s'             => '%s hinzuf&uuml;gen und bearbeiten',
   'Address'                     => 'Adresse',
   'Advance turnover tax return' => 'Umsatzsteuervoranmeldung',
@@ -72,6 +73,7 @@ $self->{texts} = {
   'Bestandskonto'               => 'Bestandskonto',
   'Bin List'                    => 'Lagerliste',
   'Binding to the LDAP server as "#1" failed. Please check config/authentication.pl.' => 'Die Anmeldung am LDAP-Server als "#1" schlug fehl. Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/authentication.pl.',
+  'Bins saved.'                 => 'Lagerpl&auml;tze gespeichert.',
   'Books are open'              => 'Die Bücher sind geöffnet.',
   'Buchungsgruppe'              => 'Buchungsgruppe',
   'Buchungsgruppen'             => 'Buchungsgruppen',
@@ -137,6 +139,7 @@ $self->{texts} = {
   'Edit Preferences for #1'     => 'Benutzereinstellungen f&uuml;r #1 bearbeiten',
   'Edit Price Factor'           => 'Preisfaktor bearbeiten',
   'Edit Printer'                => 'Drucker bearbeiten',
+  'Edit Warehouse'              => 'Lager bearbeiten',
   'Enforce transaction reversal for all dates' => 'Gegenbuchungen für jeden Zeitraum aktualisieren',
   'Enter longdescription'       => 'Langtext eingeben',
   'Equity'                      => 'Passiva',
@@ -184,6 +187,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'None'                        => 'Kein',
   'Number Format'               => 'Zahlenformat',
@@ -196,6 +200,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment Terms'               => 'Zahlungskonditionen',
   'Payment Terms saved!'        => 'Zahlungskonditionen gespeichert!',
   'Payment terms deleted!'      => 'Zahlungskonditionen gelöscht!',
@@ -231,6 +237,7 @@ $self->{texts} = {
   'Screen'                      => 'Bildschirm',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Skonto'                      => 'Skonto',
   'Skonto Terms'                => 'Zahlungsziel Skonto',
@@ -268,6 +275,7 @@ $self->{texts} = {
   'The unit in row %d has been deleted in the meantime.' => 'Die Einheit in Zeile %d ist in der Zwischentzeit gel&ouml;scht worden.',
   'The unit in row %d has been used in the meantime and cannot be changed anymore.' => 'Die Einheit in Zeile %d wurde in der Zwischenzeit benutzt und kann nicht mehr ge&auml;ndert werden.',
   'The units have been saved.'  => 'Die Einheiten wurden gespeichert.',
+  'The warehouse could not be deleted because it has already been used.' => 'Das Lager konnte nicht gel&ouml;scht werden, da es bereits in Benutzung war.',
   'To (email)'                  => 'An',
   'Transaction reversal enforced for all dates' => 'Fehleintragungen müssen für jeden Zeitraum mit einer Kontraeintragung ausgebessert werden',
   'Transaction reversal enforced up to' => 'Fehleintragungen können bis zu dem angegebenen Zeitraum nur mit einer Kontraeintragung ausgebessert werden!',
@@ -282,6 +290,11 @@ $self->{texts} = {
   'Value'                       => 'Wert',
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse deleted.'          => 'Lager gel&ouml;scht.',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
+  'Warehouse saved.'            => 'Lager gespeichert.',
+  'Warehouses'                  => 'L&auml;ger',
   'Yes'                         => 'Ja',
   'You can use the following strings in the long description and all translations. They will be replaced by their actual values by Lx-Office before they\'re output.' => 'Sie k&ouml;nnen im Langtext und allen Ãœbersetzungen die folgenden Variablen benutzen, die vor der Ausgabe von Lx-Office automatisch ersetzt werden:',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
@@ -334,6 +347,7 @@ $self->{subs} = {
   'add_printer'                 => 'add_printer',
   'add_tax'                     => 'add_tax',
   'add_unit'                    => 'add_unit',
+  'add_warehouse'               => 'add_warehouse',
   'audit_control'               => 'audit_control',
   'buchungsgruppe_header'       => 'buchungsgruppe_header',
   'build_std_url'               => 'build_std_url',
@@ -354,6 +368,7 @@ $self->{subs} = {
   'delete_price_factor'         => 'delete_price_factor',
   'delete_printer'              => 'delete_printer',
   'delete_tax'                  => 'delete_tax',
+  'delete_warehouse'            => 'delete_warehouse',
   'delivery_customer_selection' => 'delivery_customer_selection',
   'department_header'           => 'department_header',
   'doclose'                     => 'doclose',
@@ -370,6 +385,7 @@ $self->{subs} = {
   'edit_printer'                => 'edit_printer',
   'edit_tax'                    => 'edit_tax',
   'edit_units'                  => 'edit_units',
+  'edit_warehouse'              => 'edit_warehouse',
   'form_footer'                 => 'form_footer',
   'format_dates'                => 'format_dates',
   'get_employee_id'             => 'get_employee_id',
@@ -386,13 +402,16 @@ $self->{subs} = {
   'list_price_factors'          => 'list_price_factors',
   'list_printer'                => 'list_printer',
   'list_tax'                    => 'list_tax',
+  'list_warehouses'             => 'list_warehouses',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'payment_header'              => 'payment_header',
   'printer_header'              => 'printer_header',
   'reformat_numbers'            => 'reformat_numbers',
   'retrieve_partunits'          => 'retrieve_partunits',
   'save'                        => 'save',
   'save_account'                => 'save_account',
+  'save_bin'                    => 'save_bin',
   'save_buchungsgruppe'         => 'save_buchungsgruppe',
   'save_business'               => 'save_business',
   'save_defaults'               => 'save_defaults',
@@ -405,6 +424,9 @@ $self->{subs} = {
   'save_printer'                => 'save_printer',
   'save_tax'                    => 'save_tax',
   'save_unit'                   => 'save_unit',
+  'save_warehouse'              => 'save_warehouse',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'set_unit_languages'          => 'set_unit_languages',
   'show_am_history'             => 'show_am_history',
@@ -415,12 +437,14 @@ $self->{subs} = {
   'swap_payment_terms'          => 'swap_payment_terms',
   'swap_price_factors'          => 'swap_price_factors',
   'swap_units'                  => 'swap_units',
+  'swap_warehouses'             => 'swap_warehouses',
   'vendor_selection'            => 'vendor_selection',
   'erfassen'                    => 'add',
   'konto_erfassen'              => 'add_account',
   'weiter'                      => 'continue',
   'löschen'                     => 'delete',
   'kontodaten_bearbeiten'       => 'edit_account',
+  'neue_ware'                   => 'new_part',
   'speichern'                   => 'save',
 };
 
index 01eba14..9267fdf 100644 (file)
@@ -67,6 +67,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Number'                      => 'Nummer',
   'Others'                      => 'Andere',
@@ -75,6 +76,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
   'Proforma Invoice'            => 'Proformarechnung',
@@ -88,6 +91,7 @@ $self->{texts} = {
   'SCREENED'                    => 'Angezeigt',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Selection'                   => 'Auswahlbox',
   'Storno Invoice'              => 'Stornorechnung',
@@ -117,6 +121,8 @@ $self->{texts} = {
   'Value'                       => 'Wert',
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'Yes/No (Checkbox)'           => 'Ja/Nein (Checkbox)',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
@@ -159,9 +165,12 @@ $self->{subs} = {
   'format_dates'                => 'format_dates',
   'list_cvar_configs'           => 'list_cvar_configs',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'reformat_numbers'            => 'reformat_numbers',
   'retrieve_partunits'          => 'retrieve_partunits',
   'save'                        => 'save',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
@@ -170,6 +179,7 @@ $self->{subs} = {
   'erfassen'                    => 'add',
   'weiter'                      => 'continue',
   'löschen'                     => 'delete',
+  'neue_ware'                   => 'new_part',
   'speichern'                   => 'save',
 };
 
index 1260316..31171c0 100644 (file)
@@ -68,6 +68,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Others'                      => 'Andere',
   'PAYMENT POSTED'              => 'Rechung gebucht',
@@ -75,6 +76,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment Reminder'            => 'Zahlungserinnerung',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
@@ -91,6 +94,7 @@ $self->{texts} = {
   'Saving the file \'%s\' failed. OS error message: %s' => 'Das Speichern der Datei \'%s\' schlug fehl. Fehlermeldung des Betriebssystems: %s',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Statement'                   => 'Sammelrechnung',
   'Storno Invoice'              => 'Stornorechnung',
@@ -117,6 +121,8 @@ $self->{texts} = {
   'Value'                       => 'Wert',
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'You\'re not editing a file.' => 'Sie bearbeiten momentan keine Datei.',
   '[email]'                     => '[email]',
@@ -156,10 +162,13 @@ $self->{subs} = {
   'edit_template'               => 'edit_template',
   'format_dates'                => 'format_dates',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'reformat_numbers'            => 'reformat_numbers',
   'retrieve_partunits'          => 'retrieve_partunits',
   'save'                        => 'save',
   'save_template'               => 'save_template',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
@@ -167,6 +176,7 @@ $self->{subs} = {
   'weiter'                      => 'continue',
   'anzeigen'                    => 'display',
   'bearbeiten'                  => 'edit',
+  'neue_ware'                   => 'new_part',
   'speichern'                   => 'save',
 };
 
index 5700039..92d3348 100644 (file)
@@ -138,6 +138,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Notes'                       => 'Bemerkungen',
   'Nov'                         => 'Nov',
@@ -156,6 +157,8 @@ $self->{texts} = {
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
   'Paid'                        => 'bezahlt',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment date missing!'       => 'Tag der Zahlung fehlt!',
   'Payment posted!'             => 'Zahlung gebucht!',
   'Payments'                    => 'Zahlungsausgänge',
@@ -185,6 +188,7 @@ $self->{texts} = {
   'Save draft'                  => 'Entwurf speichern',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
   'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
@@ -232,6 +236,8 @@ $self->{texts} = {
   'Vendor missing!'             => 'Lieferant fehlt!',
   'Vendor not on file or locked!' => 'Dieser Lieferant existiert nicht oder ist gesperrt.',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zero amount posting!'        => 'Buchung ohne Wert',
@@ -293,6 +299,7 @@ $self->{subs} = {
   'mark_as_paid'                => 'mark_as_paid',
   'mark_as_paid_common'         => 'mark_as_paid_common',
   'name_selected'               => 'name_selected',
+  'part_selection_internal'     => 'part_selection_internal',
   'post'                        => 'post',
   'post_as_new'                 => 'post_as_new',
   'post_payment'                => 'post_payment',
@@ -308,6 +315,8 @@ $self->{subs} = {
   'save_draft'                  => 'save_draft',
   'search'                      => 'search',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
@@ -323,6 +332,7 @@ $self->{subs} = {
   'löschen'                     => 'delete',
   'entwürfe_löschen'            => 'delete_drafts',
   'kreditorenbuchung_bearbeiten' => 'edit_accounts_payables_transaction',
+  'neue_ware'                   => 'new_part',
   'buchen'                      => 'post',
   'zahlung_buchen'              => 'post_payment',
   'entwurf_speichern'           => 'save_draft',
index 4cfffa7..0d49eab 100644 (file)
@@ -144,6 +144,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Notes'                       => 'Bemerkungen',
   'Nov'                         => 'Nov',
@@ -162,6 +163,8 @@ $self->{texts} = {
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
   'Paid'                        => 'bezahlt',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment date missing!'       => 'Tag der Zahlung fehlt!',
   'Payment posted!'             => 'Zahlung gebucht!',
   'Pick List'                   => 'Sammelliste',
@@ -190,6 +193,7 @@ $self->{texts} = {
   'Save draft'                  => 'Entwurf speichern',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
   'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
@@ -239,6 +243,8 @@ $self->{texts} = {
   'Vendor details'              => 'Lieferantendetails',
   'Vendor not on file or locked!' => 'Dieser Lieferant existiert nicht oder ist gesperrt.',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zero amount posting!'        => 'Buchung ohne Wert',
@@ -303,6 +309,7 @@ $self->{subs} = {
   'mark_as_paid'                => 'mark_as_paid',
   'mark_as_paid_common'         => 'mark_as_paid_common',
   'name_selected'               => 'name_selected',
+  'part_selection_internal'     => 'part_selection_internal',
   'post'                        => 'post',
   'post_as_new'                 => 'post_as_new',
   'post_payment'                => 'post_payment',
@@ -319,6 +326,8 @@ $self->{subs} = {
   'search'                      => 'search',
   'section_menu'                => 'section_menu',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
@@ -332,6 +341,7 @@ $self->{subs} = {
   'weiter'                      => 'continue',
   'löschen'                     => 'delete',
   'entwürfe_löschen'            => 'delete_drafts',
+  'neue_ware'                   => 'new_part',
   'buchen'                      => 'post',
   'zahlung_buchen'              => 'post_payment',
   'rechnung'                    => 'sales_invoice',
index 862427c..5af4d70 100644 (file)
@@ -66,6 +66,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Number'                      => 'Nummer',
   'Others'                      => 'Andere',
@@ -74,6 +75,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
   'Proforma Invoice'            => 'Proformarechnung',
@@ -88,6 +91,7 @@ $self->{texts} = {
   'SCREENED'                    => 'Angezeigt',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
   'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
@@ -112,6 +116,8 @@ $self->{texts} = {
   'Vendor details'              => 'Lieferantendetails',
   'Vendor not on file or locked!' => 'Dieser Lieferant existiert nicht oder ist gesperrt.',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'bin_list'                    => 'Lagerliste',
@@ -149,16 +155,20 @@ $self->{subs} = {
   'format_dates'                => 'format_dates',
   'mark_as_paid_common'         => 'mark_as_paid_common',
   'name_selected'               => 'name_selected',
+  'part_selection_internal'     => 'part_selection_internal',
   'project_selected'            => 'project_selected',
   'reformat_numbers'            => 'reformat_numbers',
   'retrieve_partunits'          => 'retrieve_partunits',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
   'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
+  'neue_ware'                   => 'new_part',
 };
 
 1;
index 10bcf82..fc2d7c4 100644 (file)
@@ -74,6 +74,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Order'                       => 'Auftrag',
   'Order Number'                => 'Auftragsnummer',
@@ -84,6 +85,8 @@ $self->{texts} = {
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
   'Packing Lists'               => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
   'Print'                       => 'Drucken',
@@ -99,7 +102,7 @@ $self->{texts} = {
   'Receipt, payment, reconciliation' => 'Zahlungseingang, Zahlungsausgang, Kontenabgleich',
   'Receipts'                    => 'Zahlungseingänge',
   'Reference'                   => 'Referenz',
-  'Remove'                      => 'entfernen',
+  'Remove'                      => 'Entfernen',
   'Removed spoolfiles!'         => 'Druckdateien entfernt!',
   'Removing marked entries from queue ...' => 'Markierte Einträge werden von der Warteschlange entfernt ...',
   'Reports'                     => 'Berichte',
@@ -110,6 +113,7 @@ $self->{texts} = {
   'Sales Orders'                => 'Aufträge',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select all'                  => 'Alle auswählen',
   'Spoolfile'                   => 'Druckdatei',
@@ -134,6 +138,8 @@ $self->{texts} = {
   'Variable'                    => 'Variable',
   'Vendor'                      => 'Lieferant',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
@@ -174,18 +180,22 @@ $self->{subs} = {
   'format_dates'                => 'format_dates',
   'list_spool'                  => 'list_spool',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'print'                       => 'print',
   'reformat_numbers'            => 'reformat_numbers',
   'remove'                      => 'remove',
   'retrieve_partunits'          => 'retrieve_partunits',
   'search'                      => 'search',
   'select_all'                  => 'select_all',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
   'vendor_selection'            => 'vendor_selection',
   'yes'                         => 'yes',
   'weiter'                      => 'continue',
+  'neue_ware'                   => 'new_part',
   'drucken'                     => 'print',
   'entfernen'                   => 'remove',
   'alle_auswählen'              => 'select_all',
index b0e6e6f..f06fdf5 100644 (file)
@@ -123,6 +123,8 @@ $self->{texts} = {
   'To (email)'                  => 'An',
   'Transactions, AR transactions, AP transactions' => 'Dialogbuchen, Debitorenrechnungen, Kreditorenrechnungen',
   'Unknown dependency \'%s\'.'  => 'Unbekannte Abh&auml;ngigkeit \'%s\'.',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'bin_list'                    => 'Lagerliste',
index e49835f..b5c8c5b 100644 (file)
@@ -62,6 +62,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Others'                      => 'Andere',
   'PAYMENT POSTED'              => 'Rechung gebucht',
@@ -69,6 +70,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
   'Proforma Invoice'            => 'Proformarechnung',
@@ -82,6 +85,7 @@ $self->{texts} = {
   'SCREENED'                    => 'Angezeigt',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Storno Invoice'              => 'Stornorechnung',
   'Storno Packing List'         => 'Stornolieferschein',
@@ -102,6 +106,8 @@ $self->{texts} = {
   'Value'                       => 'Wert',
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'bin_list'                    => 'Lagerliste',
@@ -135,13 +141,17 @@ $self->{subs} = {
   'delivery_customer_selection' => 'delivery_customer_selection',
   'format_dates'                => 'format_dates',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'reformat_numbers'            => 'reformat_numbers',
   'retrieve_partunits'          => 'retrieve_partunits',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
   'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
+  'neue_ware'                   => 'new_part',
 };
 
 1;
index 7f49afa..0f250f4 100644 (file)
@@ -85,6 +85,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Number'                      => 'Nummer',
   'Others'                      => 'Andere',
@@ -94,6 +95,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment'                     => 'Zahlungsausgang',
   'Payment posted!'             => 'Zahlung gebucht!',
   'Pick List'                   => 'Sammelliste',
@@ -120,6 +123,7 @@ $self->{texts} = {
   'Select'                      => 'auswählen',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
   'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
@@ -147,6 +151,8 @@ $self->{texts} = {
   'Vendor details'              => 'Lieferantendetails',
   'Vendor not on file or locked!' => 'Dieser Lieferant existiert nicht oder ist gesperrt.',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zero amount posting!'        => 'Buchung ohne Wert',
@@ -192,6 +198,7 @@ $self->{subs} = {
   'list_invoices'               => 'list_invoices',
   'mark_as_paid_common'         => 'mark_as_paid_common',
   'name_selected'               => 'name_selected',
+  'part_selection_internal'     => 'part_selection_internal',
   'payment'                     => 'payment',
   'post'                        => 'post',
   'print'                       => 'print',
@@ -199,6 +206,8 @@ $self->{subs} = {
   'reformat_numbers'            => 'reformat_numbers',
   'retrieve_partunits'          => 'retrieve_partunits',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
@@ -206,6 +215,7 @@ $self->{subs} = {
   'update'                      => 'update',
   'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
+  'neue_ware'                   => 'new_part',
   'buchen'                      => 'post',
   'drucken'                     => 'print',
   'erneuern'                    => 'update',
index 39710d5..ad88ce7 100644 (file)
@@ -88,6 +88,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Number'                      => 'Nummer',
   'Orphaned'                    => 'Nie benutzt',
@@ -98,6 +99,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
@@ -118,6 +121,7 @@ $self->{texts} = {
   'Sales quotation'             => 'Angebot',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Storno Invoice'              => 'Stornorechnung',
   'Storno Packing List'         => 'Stornolieferschein',
@@ -149,6 +153,8 @@ $self->{texts} = {
   'Vendor details'              => 'Lieferantendetails',
   'Vendor saved!'               => 'Lieferant gespeichert!',
   'Vendors'                     => 'Lieferanten',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
@@ -200,6 +206,7 @@ $self->{subs} = {
   'get_shipto'                  => 'get_shipto',
   'list_names'                  => 'list_names',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'reformat_numbers'            => 'reformat_numbers',
   'report_generator_back'       => 'report_generator_back',
   'report_generator_dispatcher' => 'report_generator_dispatcher',
@@ -216,6 +223,8 @@ $self->{subs} = {
   'save_and_quotation'          => 'save_and_quotation',
   'save_and_rfq'                => 'save_and_rfq',
   'search'                      => 'search',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
@@ -224,6 +233,7 @@ $self->{subs} = {
   'erfassen'                    => 'add',
   'weiter'                      => 'continue',
   'löschen'                     => 'delete',
+  'neue_ware'                   => 'new_part',
   'speichern'                   => 'save',
   'speichern_und_debitorenbuchung_erfassen' => 'save_and_ar_transaction',
   'speichern_und_schließen'     => 'save_and_close',
index 952a87e..4cf6539 100644 (file)
@@ -92,6 +92,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'November'                    => 'November',
   'OBE-Export erfolgreich!'     => 'OBE-Export erfolgreich!',
@@ -102,6 +103,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Password'                    => 'Passwort',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
@@ -117,6 +120,7 @@ $self->{texts} = {
   'SCREENED'                    => 'Angezeigt',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'September'                   => 'September',
   'Storno Invoice'              => 'Stornorechnung',
@@ -138,7 +142,9 @@ $self->{texts} = {
   'Value'                       => 'Wert',
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
   'Von Konto: '                 => 'von Konto: ',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zeitraum'                    => 'Zeitraum',
   '[email]'                     => '[email]',
@@ -181,13 +187,17 @@ $self->{subs} = {
   'export_stammdaten'           => 'export_stammdaten',
   'format_dates'                => 'format_dates',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'reformat_numbers'            => 'reformat_numbers',
   'retrieve_partunits'          => 'retrieve_partunits',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
   'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
+  'neue_ware'                   => 'new_part',
 };
 
 1;
index 1a41bab..aee0277 100644 (file)
@@ -140,6 +140,7 @@ $self->{texts} = {
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No dunnings have been selected for printing.' => 'Es wurden keine Mahnungen zum Drucken ausgew&auml;hlt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'No.'                         => 'Position',
   'Nov'                         => 'Nov',
@@ -163,6 +164,8 @@ $self->{texts} = {
   'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment Terms missing in row ' => 'Zahlungsfrist fehlt in Zeile ',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
@@ -198,6 +201,7 @@ $self->{texts} = {
   'Search Dunning'              => 'Mahnung suchen',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
@@ -238,6 +242,8 @@ $self->{texts} = {
   'Vendor Invoice'              => 'Einkaufsrechnung',
   'Vendor Number'               => 'Lieferantennummer',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zipcode'                     => 'PLZ',
@@ -293,6 +299,7 @@ $self->{subs} = {
   'new_item'                    => 'new_item',
   'new_license'                 => 'new_license',
   'order'                       => 'order',
+  'part_selection_internal'     => 'part_selection_internal',
   'post_as_new'                 => 'post_as_new',
   'print'                       => 'print',
   'print_dunning'               => 'print_dunning',
@@ -313,6 +320,8 @@ $self->{subs} = {
   'save_dunning'                => 'save_dunning',
   'search'                      => 'search',
   'select_item'                 => 'select_item',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'send_email'                  => 'send_email',
   'set_duedate'                 => 'set_duedate',
   'set_email'                   => 'set_email',
@@ -327,6 +336,7 @@ $self->{subs} = {
   'vendor_details'              => 'vendor_details',
   'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
+  'neue_ware'                   => 'new_part',
   'drucken'                     => 'print',
   'speichern'                   => 'save',
 };
index de000e0..b3c3a48 100644 (file)
@@ -64,6 +64,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Others'                      => 'Andere',
   'PAYMENT POSTED'              => 'Rechung gebucht',
@@ -71,6 +72,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
   'Proforma Invoice'            => 'Proformarechnung',
@@ -84,6 +87,7 @@ $self->{texts} = {
   'SCREENED'                    => 'Angezeigt',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Skip'                        => 'Ãœberspringen',
   'Storno Invoice'              => 'Stornorechnung',
@@ -105,6 +109,8 @@ $self->{texts} = {
   'Value'                       => 'Wert',
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'bin_list'                    => 'Lagerliste',
@@ -143,16 +149,20 @@ $self->{subs} = {
   'load_draft'                  => 'load_draft',
   'load_draft_maybe'            => 'load_draft_maybe',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'reformat_numbers'            => 'reformat_numbers',
   'remove_draft'                => 'remove_draft',
   'retrieve_partunits'          => 'retrieve_partunits',
   'save_draft'                  => 'save_draft',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
   'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
   'entwürfe_löschen'            => 'delete_drafts',
+  'neue_ware'                   => 'new_part',
   'entwurf_speichern'           => 'save_draft',
   'Ãœberspringen'                => 'skip',
 };
index ebff34f..02e6fd8 100644 (file)
@@ -120,6 +120,8 @@ $self->{texts} = {
   'Unknown dependency \'%s\'.'  => 'Unbekannte Abh&auml;ngigkeit \'%s\'.',
   'Vendor'                      => 'Lieferant',
   'Vendor Invoice'              => 'Einkaufsrechnung',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'You must chose a user.'      => 'Sie m&uuml;ssen einen Benutzer ausw&auml;hlen.',
index fb4b017..40c3438 100644 (file)
@@ -138,6 +138,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Notes'                       => 'Bemerkungen',
   'Nov'                         => 'Nov',
@@ -152,6 +153,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
   'Post'                        => 'Buchen',
@@ -177,6 +180,7 @@ $self->{texts} = {
   'Sales quotation'             => 'Angebot',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Sep'                         => 'Sep',
   'September'                   => 'September',
@@ -216,6 +220,8 @@ $self->{texts} = {
   'Vendor'                      => 'Lieferant',
   'Vendor Invoice'              => 'Einkaufsrechnung',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
@@ -265,6 +271,7 @@ $self->{subs} = {
   'format_dates'                => 'format_dates',
   'generate_report'             => 'generate_report',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'post'                        => 'post',
   'post_as_new'                 => 'post_as_new',
   'post_transaction'            => 'post_transaction',
@@ -277,6 +284,8 @@ $self->{subs} = {
   'report_generator_export_as_pdf' => 'report_generator_export_as_pdf',
   'retrieve_partunits'          => 'retrieve_partunits',
   'search'                      => 'search',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
@@ -289,6 +298,7 @@ $self->{subs} = {
   'weiter'                      => 'continue',
   'löschen'                     => 'delete',
   'dialogbuchung'               => 'gl_transaction',
+  'neue_ware'                   => 'new_part',
   'buchen'                      => 'post',
   'rechnung'                    => 'sales_invoice',
   'storno'                      => 'storno',
index 941fe62..7fcf2ab 100644 (file)
@@ -156,6 +156,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'No.'                         => 'Position',
   'Nov'                         => 'Nov',
@@ -189,6 +190,7 @@ $self->{texts} = {
   'Part Description missing!'   => 'Artikelbezeichnung fehlt!',
   'Part Number'                 => 'Artikelnummer',
   'Part Number missing!'        => 'Artikelnummer fehlt!',
+  'Part description'            => 'Artikelbeschreibung',
   'Partnumber must not be set to empty!' => 'Die Artikelnummer darf nicht auf leer ge&auml;ndert werden.',
   'Partnumber not unique!'      => 'Artikelnummer bereits vorhanden!',
   'Parts'                       => 'Waren',
@@ -231,6 +233,7 @@ $self->{texts} = {
   'Screen'                      => 'Bildschirm',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
@@ -282,6 +285,8 @@ $self->{texts} = {
   'Vendor Invoice'              => 'Einkaufsrechnung',
   'Vendor Number'               => 'Lieferantennummer',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Weight'                      => 'Gewicht',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
@@ -361,6 +366,7 @@ $self->{subs} = {
   'new_item'                    => 'new_item',
   'new_license'                 => 'new_license',
   'order'                       => 'order',
+  'part_selection_internal'     => 'part_selection_internal',
   'parts_language_selection'    => 'parts_language_selection',
   'parts_subtotal'              => 'parts_subtotal',
   'post_as_new'                 => 'post_as_new',
@@ -384,6 +390,8 @@ $self->{subs} = {
   'search_update_prices'        => 'search_update_prices',
   'section_menu'                => 'section_menu',
   'select_item'                 => 'select_item',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'send_email'                  => 'send_email',
   'set_duedate'                 => 'set_duedate',
   'set_longdescription'         => 'set_longdescription',
@@ -406,6 +414,7 @@ $self->{subs} = {
   'erzeugnis_bearbeiten'        => 'edit_assembly',
   'ware_bearbeiten'             => 'edit_part',
   'dienstleistung_bearbeiten'   => 'edit_service',
+  'neue_ware'                   => 'new_part',
   'speichern'                   => 'save',
   'als_neu_speichern'           => 'save_as_new',
   'top_100'                     => 'top100',
index 85fe02f..22c0e81 100644 (file)
@@ -115,6 +115,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'No.'                         => 'Position',
   'Nov'                         => 'Nov',
@@ -137,6 +138,8 @@ $self->{texts} = {
   'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
@@ -169,6 +172,7 @@ $self->{texts} = {
   'Screen'                      => 'Bildschirm',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
@@ -204,6 +208,8 @@ $self->{texts} = {
   'Vendor Invoice'              => 'Einkaufsrechnung',
   'Vendor Number'               => 'Lieferantennummer',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zipcode'                     => 'PLZ',
@@ -253,6 +259,7 @@ $self->{subs} = {
   'new_item'                    => 'new_item',
   'new_license'                 => 'new_license',
   'order'                       => 'order',
+  'part_selection_internal'     => 'part_selection_internal',
   'post_as_new'                 => 'post_as_new',
   'print'                       => 'print',
   'print_form'                  => 'print_form',
@@ -263,6 +270,8 @@ $self->{subs} = {
   'request_for_quotation'       => 'request_for_quotation',
   'retrieve_partunits'          => 'retrieve_partunits',
   'select_item'                 => 'select_item',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'send_email'                  => 'send_email',
   'set_duedate'                 => 'set_duedate',
   'set_longdescription'         => 'set_longdescription',
@@ -274,6 +283,7 @@ $self->{subs} = {
   'vendor_details'              => 'vendor_details',
   'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
+  'neue_ware'                   => 'new_part',
 };
 
 1;
index 24dbb13..5223f35 100644 (file)
@@ -151,6 +151,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'No.'                         => 'Position',
   'Notes'                       => 'Bemerkungen',
@@ -176,6 +177,8 @@ $self->{texts} = {
   'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment date missing!'       => 'Tag der Zahlung fehlt!',
   'Payment posted!'             => 'Zahlung gebucht!',
   'Payments'                    => 'Zahlungsausgänge',
@@ -220,6 +223,7 @@ $self->{texts} = {
   'Screen'                      => 'Bildschirm',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
@@ -269,6 +273,8 @@ $self->{texts} = {
   'Vendor missing!'             => 'Lieferant fehlt!',
   'Vendor not on file or locked!' => 'Dieser Lieferant existiert nicht oder ist gesperrt.',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zipcode'                     => 'PLZ',
@@ -339,6 +345,7 @@ $self->{subs} = {
   'new_item'                    => 'new_item',
   'new_license'                 => 'new_license',
   'order'                       => 'order',
+  'part_selection_internal'     => 'part_selection_internal',
   'post'                        => 'post',
   'post_as_new'                 => 'post_as_new',
   'post_payment'                => 'post_payment',
@@ -356,6 +363,8 @@ $self->{subs} = {
   'save_draft'                  => 'save_draft',
   'select_item'                 => 'select_item',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'send_email'                  => 'send_email',
   'set_duedate'                 => 'set_duedate',
@@ -374,6 +383,7 @@ $self->{subs} = {
   'weiter'                      => 'continue',
   'löschen'                     => 'delete',
   'entwürfe_löschen'            => 'delete_drafts',
+  'neue_ware'                   => 'new_part',
   'buchen'                      => 'post',
   'zahlung_buchen'              => 'post_payment',
   'entwurf_speichern'           => 'save_draft',
index c99cd69..0f9b0df 100644 (file)
@@ -168,6 +168,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'No.'                         => 'Position',
   'Notes'                       => 'Bemerkungen',
@@ -194,6 +195,8 @@ $self->{texts} = {
   'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment Terms'               => 'Zahlungskonditionen',
   'Payment date missing!'       => 'Tag der Zahlung fehlt!',
   'Payment posted!'             => 'Zahlung gebucht!',
@@ -243,6 +246,7 @@ $self->{texts} = {
   'Screen'                      => 'Bildschirm',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
@@ -295,6 +299,8 @@ $self->{texts} = {
   'Vendor details'              => 'Lieferantendetails',
   'Vendor not on file or locked!' => 'Dieser Lieferant existiert nicht oder ist gesperrt.',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zipcode'                     => 'PLZ',
@@ -367,6 +373,7 @@ $self->{subs} = {
   'new_item'                    => 'new_item',
   'new_license'                 => 'new_license',
   'order'                       => 'order',
+  'part_selection_internal'     => 'part_selection_internal',
   'post'                        => 'post',
   'post_as_new'                 => 'post_as_new',
   'post_payment'                => 'post_payment',
@@ -386,6 +393,8 @@ $self->{subs} = {
   'save_draft'                  => 'save_draft',
   'select_item'                 => 'select_item',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'send_email'                  => 'send_email',
   'set_duedate'                 => 'set_duedate',
@@ -406,6 +415,7 @@ $self->{subs} = {
   'löschen'                     => 'delete',
   'entwürfe_löschen'            => 'delete_drafts',
   'email'                       => 'e_mail',
+  'neue_ware'                   => 'new_part',
   'auftrag'                     => 'order',
   'buchen'                      => 'post',
   'zahlung_buchen'              => 'post_payment',
index d71d1d8..00febcd 100644 (file)
@@ -79,6 +79,7 @@ $self->{texts} = {
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No licenses were found that match the search criteria.' => 'Es wurden keine Lizenzen gefunden, auf die die Suchkriterien zutreffen.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Others'                      => 'Andere',
   'Own Product'                 => 'eigenes Produkt',
@@ -88,6 +89,7 @@ $self->{texts} = {
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
   'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Pick List'                   => 'Sammelliste',
   'Please enter a license key.' => 'Bitte geben Sie einen Lizenzschlüssel an.',
   'Please enter a number of licenses.' => 'Bitte geben Sie die Anzahl Lizenzschlüssel an.',
@@ -105,6 +107,7 @@ $self->{texts} = {
   'Save'                        => 'Speichern',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
@@ -132,6 +135,8 @@ $self->{texts} = {
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
   'View License'                => 'Lizenz ansehen',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   'Zipcode'                     => 'PLZ',
@@ -174,6 +179,7 @@ $self->{subs} = {
   'form_header'                 => 'form_header',
   'format_dates'                => 'format_dates',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'print_customer_selection'    => 'print_customer_selection',
   'print_license_form'          => 'print_license_form',
   'print_part_selection'        => 'print_part_selection',
@@ -182,6 +188,8 @@ $self->{subs} = {
   'retrieve_partunits'          => 'retrieve_partunits',
   'save'                        => 'save',
   'search'                      => 'search',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'set_std_hidden'              => 'set_std_hidden',
   'show_history'                => 'show_history',
@@ -190,6 +198,7 @@ $self->{subs} = {
   'vendor_selection'            => 'vendor_selection',
   'erfassen'                    => 'add',
   'weiter'                      => 'continue',
+  'neue_ware'                   => 'new_part',
   'speichern'                   => 'save',
   'erneuern'                    => 'update',
 };
index a90ef22..7b54033 100644 (file)
@@ -179,6 +179,7 @@ $self->{texts} = {
   'No action defined.'          => 'Keine Aktion definiert.',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'No.'                         => 'Position',
   'Not delivered'               => 'Nicht geliefert',
@@ -211,6 +212,8 @@ $self->{texts} = {
   'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
@@ -254,6 +257,7 @@ $self->{texts} = {
   'Screen'                      => 'Bildschirm',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
@@ -305,6 +309,8 @@ $self->{texts} = {
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
   'Vendor type'                 => 'Lieferantentyp',
   'Version'                     => 'Version',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Workflow purchase_order'     => 'Workflow Lieferantenauftrag',
   'Workflow request_quotation'  => 'Workflow Preisanfrage',
   'Workflow sales_order'        => 'Workflow Auftrag',
@@ -403,6 +409,7 @@ $self->{subs} = {
   'order'                       => 'order',
   'order_links'                 => 'order_links',
   'orders'                      => 'orders',
+  'part_selection_internal'     => 'part_selection_internal',
   'poso'                        => 'poso',
   'post_as_new'                 => 'post_as_new',
   'prepare_order'               => 'prepare_order',
@@ -433,6 +440,8 @@ $self->{subs} = {
   'search'                      => 'search',
   'select_item'                 => 'select_item',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'send_email'                  => 'send_email',
   'set_duedate'                 => 'set_duedate',
@@ -458,6 +467,7 @@ $self->{subs} = {
   'abschlie&szlig;en'           => 'finish',
   'rechnung'                    => 'invoice',
   'anmeldung'                   => 'login',
+  'neue_ware'                   => 'new_part',
   'nein'                        => 'no',
   'auftrag'                     => 'order',
   'drucken'                     => 'print',
index 4a1bd5f..4f93c3f 100644 (file)
@@ -37,6 +37,7 @@ $self->{texts} = {
   'Add Transaction'             => 'Dialogbuchen',
   'Add Vendor'                  => 'Lieferant erfassen',
   'Add Vendor Invoice'          => 'Einkaufsrechnung erfassen',
+  'Add Warehouse'               => 'Lager erfassen',
   'Administration area'         => 'Administrationsbereich',
   'Advance turnover tax return' => 'Umsatzsteuervoranmeldung',
   'All reports'                 => 'Alle Berichte (Konten&uuml;bersicht, Saldenbilanz, GuV, BWA, Bilanz, Projektbuchungen)',
@@ -110,6 +111,7 @@ $self->{texts} = {
   'List Pricegroups'            => 'Preisgruppen anzeigen',
   'List Printer'                => 'Drucker anzeigen',
   'List Tax'                    => 'Bearbeiten',
+  'List Warehouses'             => 'Lager anzeigen',
   'Logout'                      => 'Abmeldung',
   'Manage license keys'         => 'Lizenzschl&uuml;ssel verwalten',
   'Master Data'                 => 'Stammdaten',
@@ -142,6 +144,7 @@ $self->{texts} = {
   'Receipt, payment, reconciliation' => 'Zahlungseingang, Zahlungsausgang, Kontenabgleich',
   'Receipts'                    => 'Zahlungseingänge',
   'Reconciliation'              => 'Kontenabgleich',
+  'Removal'                     => 'Entnahme',
   'Reports'                     => 'Berichte',
   'Sales Invoices'              => 'Kundenrechnung',
   'Sales Orders'                => 'Aufträge',
@@ -149,6 +152,7 @@ $self->{texts} = {
   'Services'                    => 'Dienstleistungen',
   'Shipto'                      => 'Lieferanschriften',
   'Show TODO list'              => 'Aufgabenliste anzeigen',
+  'Stock'                       => 'Einlagern',
   'Stylesheet'                  => 'Stilvorlage',
   'Subject'                     => 'Betreff',
   'System'                      => 'System',
@@ -164,6 +168,7 @@ $self->{texts} = {
   'The creation of the authentication database failed:' => 'Das Anlegen der Authentifizierungsdatenbank schlug fehl:',
   'To (email)'                  => 'An',
   'Transactions, AR transactions, AP transactions' => 'Dialogbuchen, Debitorenrechnungen, Kreditorenrechnungen',
+  'Transfer'                    => 'Umlagern',
   'Trial Balance'               => 'Saldenbilanz',
   'Type of Business'            => 'Kunden-/Lieferantentyp',
   'UStVa'                       => 'UStVa',
@@ -174,6 +179,12 @@ $self->{texts} = {
   'Vendor Invoices'             => 'Einkaufsrechnungen',
   'Vendors'                     => 'Lieferanten',
   'Version'                     => 'Version',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'WHJournal'                   => 'Lagerbuchungen',
+  'Warehouse'                   => 'Lager',
+  'Warehouse content'           => 'Lagerbestand',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
+  'Warehouses'                  => 'L&auml;ger',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'config/authentication.pl: Key "DB_config" is missing.' => 'config/authentication.pl: Das Schl&uuml;sselwort "DB_config" fehlt.',
index aecfbd3..2e784b2 100755 (executable)
@@ -53,6 +53,8 @@ $self->{texts} = {
   'To (email)'                  => 'An',
   'Transactions, AR transactions, AP transactions' => 'Dialogbuchen, Debitorenrechnungen, Kreditorenrechnungen',
   'Unknown dependency \'%s\'.'  => 'Unbekannte Abh&auml;ngigkeit \'%s\'.',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'config/authentication.pl: Key "DB_config" is missing.' => 'config/authentication.pl: Das Schl&uuml;sselwort "DB_config" fehlt.',
index cfaee62..49ba5c7 100644 (file)
@@ -36,6 +36,7 @@ $self->{texts} = {
   'Add Transaction'             => 'Dialogbuchen',
   'Add Vendor'                  => 'Lieferant erfassen',
   'Add Vendor Invoice'          => 'Einkaufsrechnung erfassen',
+  'Add Warehouse'               => 'Lager erfassen',
   'Administration area'         => 'Administrationsbereich',
   'Advance turnover tax return' => 'Umsatzsteuervoranmeldung',
   'All reports'                 => 'Alle Berichte (Konten&uuml;bersicht, Saldenbilanz, GuV, BWA, Bilanz, Projektbuchungen)',
@@ -109,6 +110,7 @@ $self->{texts} = {
   'List Pricegroups'            => 'Preisgruppen anzeigen',
   'List Printer'                => 'Drucker anzeigen',
   'List Tax'                    => 'Bearbeiten',
+  'List Warehouses'             => 'Lager anzeigen',
   'Logout'                      => 'Abmeldung',
   'Manage license keys'         => 'Lizenzschl&uuml;ssel verwalten',
   'Master Data'                 => 'Stammdaten',
@@ -141,6 +143,7 @@ $self->{texts} = {
   'Receipt, payment, reconciliation' => 'Zahlungseingang, Zahlungsausgang, Kontenabgleich',
   'Receipts'                    => 'Zahlungseingänge',
   'Reconciliation'              => 'Kontenabgleich',
+  'Removal'                     => 'Entnahme',
   'Reports'                     => 'Berichte',
   'Sales Invoices'              => 'Kundenrechnung',
   'Sales Orders'                => 'Aufträge',
@@ -148,6 +151,7 @@ $self->{texts} = {
   'Services'                    => 'Dienstleistungen',
   'Shipto'                      => 'Lieferanschriften',
   'Show TODO list'              => 'Aufgabenliste anzeigen',
+  'Stock'                       => 'Einlagern',
   'Stylesheet'                  => 'Stilvorlage',
   'Subject'                     => 'Betreff',
   'System'                      => 'System',
@@ -163,6 +167,7 @@ $self->{texts} = {
   'The creation of the authentication database failed:' => 'Das Anlegen der Authentifizierungsdatenbank schlug fehl:',
   'To (email)'                  => 'An',
   'Transactions, AR transactions, AP transactions' => 'Dialogbuchen, Debitorenrechnungen, Kreditorenrechnungen',
+  'Transfer'                    => 'Umlagern',
   'Trial Balance'               => 'Saldenbilanz',
   'Type of Business'            => 'Kunden-/Lieferantentyp',
   'UStVa'                       => 'UStVa',
@@ -173,6 +178,12 @@ $self->{texts} = {
   'Vendor Invoices'             => 'Einkaufsrechnungen',
   'Vendors'                     => 'Lieferanten',
   'Version'                     => 'Version',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'WHJournal'                   => 'Lagerbuchungen',
+  'Warehouse'                   => 'Lager',
+  'Warehouse content'           => 'Lagerbestand',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
+  'Warehouses'                  => 'L&auml;ger',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'config/authentication.pl: Key "DB_config" is missing.' => 'config/authentication.pl: Das Schl&uuml;sselwort "DB_config" fehlt.',
index bad1b54..c84f999 100644 (file)
@@ -53,6 +53,8 @@ $self->{texts} = {
   'To (email)'                  => 'An',
   'Transactions, AR transactions, AP transactions' => 'Dialogbuchen, Debitorenrechnungen, Kreditorenrechnungen',
   'Unknown dependency \'%s\'.'  => 'Unbekannte Abh&auml;ngigkeit \'%s\'.',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'config/authentication.pl: Key "DB_config" is missing.' => 'config/authentication.pl: Das Schl&uuml;sselwort "DB_config" fehlt.',
index 60866c9..0218054 100644 (file)
@@ -160,6 +160,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'No.'                         => 'Position',
   'Not delivered'               => 'Nicht geliefert',
@@ -189,6 +190,8 @@ $self->{texts} = {
   'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
@@ -231,6 +234,7 @@ $self->{texts} = {
   'Screen'                      => 'Bildschirm',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
@@ -276,6 +280,8 @@ $self->{texts} = {
   'Vendor not on file or locked!' => 'Dieser Lieferant existiert nicht oder ist gesperrt.',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
   'Vendor type'                 => 'Lieferantentyp',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Workflow purchase_order'     => 'Workflow Lieferantenauftrag',
   'Workflow request_quotation'  => 'Workflow Preisanfrage',
   'Workflow sales_order'        => 'Workflow Auftrag',
@@ -361,6 +367,7 @@ $self->{subs} = {
   'order'                       => 'order',
   'order_links'                 => 'order_links',
   'orders'                      => 'orders',
+  'part_selection_internal'     => 'part_selection_internal',
   'poso'                        => 'poso',
   'post_as_new'                 => 'post_as_new',
   'prepare_order'               => 'prepare_order',
@@ -388,6 +395,8 @@ $self->{subs} = {
   'search'                      => 'search',
   'select_item'                 => 'select_item',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'send_email'                  => 'send_email',
   'set_duedate'                 => 'set_duedate',
@@ -406,6 +415,7 @@ $self->{subs} = {
   'löschen'                     => 'delete',
   'email'                       => 'e_mail',
   'rechnung'                    => 'invoice',
+  'neue_ware'                   => 'new_part',
   'nein'                        => 'no',
   'auftrag'                     => 'order',
   'drucken'                     => 'print',
index 0b24351..9afcc65 100644 (file)
@@ -82,6 +82,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Number'                      => 'Nummer',
   'Orphaned'                    => 'Nie benutzt',
@@ -91,6 +92,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
   'Preisgruppe'                 => 'Preisgruppe',
@@ -115,6 +118,7 @@ $self->{texts} = {
   'Save'                        => 'Speichern',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Storno Invoice'              => 'Stornorechnung',
   'Storno Packing List'         => 'Stornolieferschein',
@@ -135,6 +139,8 @@ $self->{texts} = {
   'Value'                       => 'Wert',
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Yes'                         => 'Ja',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
@@ -180,6 +186,7 @@ $self->{subs} = {
   'form_project_header'         => 'form_project_header',
   'format_dates'                => 'format_dates',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'partsgroup_report'           => 'partsgroup_report',
   'pricegroup_report'           => 'pricegroup_report',
   'project_report'              => 'project_report',
@@ -187,6 +194,8 @@ $self->{subs} = {
   'retrieve_partunits'          => 'retrieve_partunits',
   'save'                        => 'save',
   'search'                      => 'search',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
@@ -194,6 +203,7 @@ $self->{subs} = {
   'erfassen'                    => 'add',
   'weiter'                      => 'continue',
   'löschen'                     => 'delete',
+  'neue_ware'                   => 'new_part',
   'speichern'                   => 'save',
 };
 
index c0aad7c..42e802b 100644 (file)
@@ -75,6 +75,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Others'                      => 'Andere',
   'Out of balance!'             => 'Summen stimmen nicht berein!',
@@ -83,6 +84,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payment'                     => 'Zahlungsausgang',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
@@ -98,6 +101,7 @@ $self->{texts} = {
   'SCREENED'                    => 'Angezeigt',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select all'                  => 'Alle auswählen',
   'Source'                      => 'Beleg',
@@ -123,6 +127,8 @@ $self->{texts} = {
   'Value'                       => 'Wert',
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'bin_list'                    => 'Lagerliste',
@@ -160,10 +166,13 @@ $self->{subs} = {
   'format_dates'                => 'format_dates',
   'get_payments'                => 'get_payments',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'reconciliation'              => 'reconciliation',
   'reformat_numbers'            => 'reformat_numbers',
   'retrieve_partunits'          => 'retrieve_partunits',
   'select_all'                  => 'select_all',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show_history'                => 'show_history',
   'show_vc_details'             => 'show_vc_details',
@@ -171,6 +180,7 @@ $self->{subs} = {
   'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
   'fertig'                      => 'done',
+  'neue_ware'                   => 'new_part',
   'alle_auswählen'              => 'select_all',
   'erneuern'                    => 'update',
 };
index d7f5d71..47d608f 100644 (file)
@@ -85,6 +85,8 @@ $self->{texts} = {
   'To (email)'                  => 'An',
   'Transactions, AR transactions, AP transactions' => 'Dialogbuchen, Debitorenrechnungen, Kreditorenrechnungen',
   'Unknown dependency \'%s\'.'  => 'Unbekannte Abh&auml;ngigkeit \'%s\'.',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
   '[email]'                     => '[email]',
   'bin_list'                    => 'Lagerliste',
index 04e7fe7..d16577c 100644 (file)
@@ -127,6 +127,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Non-taxable Purchases'       => 'Nicht zu versteuernde Einkäufe',
   'Non-taxable Sales'           => 'Nicht zu versteuernde Verkäufe',
@@ -144,6 +145,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Payments'                    => 'Zahlungsausgänge',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
@@ -170,6 +173,7 @@ $self->{texts} = {
   'Screen'                      => 'Bildschirm',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
   'Select from one of the projects below' => 'Wählen Sie eines der untenstehenden Projekte',
@@ -209,6 +213,8 @@ $self->{texts} = {
   'Vendor details'              => 'Lieferantendetails',
   'Vendor not on file or locked!' => 'Dieser Lieferant existiert nicht oder ist gesperrt.',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'YYYY'                        => 'JJJJ',
   'Year'                        => 'Jahr',
   'Yearly'                      => 'jährlich',
@@ -277,6 +283,7 @@ $self->{subs} = {
   'list_payments'               => 'list_payments',
   'mark_as_paid_common'         => 'mark_as_paid_common',
   'name_selected'               => 'name_selected',
+  'part_selection_internal'     => 'part_selection_internal',
   'print'                       => 'print',
   'print_form'                  => 'print_form',
   'print_options'               => 'print_options',
@@ -291,6 +298,8 @@ $self->{subs} = {
   'retrieve_partunits'          => 'retrieve_partunits',
   'select_all'                  => 'select_all',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'send_email'                  => 'send_email',
   'set_longdescription'         => 'set_longdescription',
@@ -301,6 +310,7 @@ $self->{subs} = {
   'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
   'email'                       => 'e_mail',
+  'neue_ware'                   => 'new_part',
   'drucken'                     => 'print',
   'alle_auswählen'              => 'select_all',
 };
index 2100103..3730c92 100644 (file)
@@ -176,6 +176,7 @@ $self->{texts} = {
   'No action defined.'          => 'Keine Aktion definiert.',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'No.'                         => 'Position',
   'Not delivered'               => 'Nicht geliefert',
@@ -208,6 +209,8 @@ $self->{texts} = {
   'Packing List Date missing!'  => 'Datum für Verpackungsliste fehlt!',
   'Packing List Number missing!' => 'Verpackungslistennummer fehlt!',
   'Part Description'            => 'Artikelbeschreibung',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Phone'                       => 'Telefon',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
@@ -251,6 +254,7 @@ $self->{texts} = {
   'Screen'                      => 'Bildschirm',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
   'Select from one of the names below' => 'Wählen Sie einen der untenstehenden Namen',
@@ -300,6 +304,8 @@ $self->{texts} = {
   'Vendor not on file or locked!' => 'Dieser Lieferant existiert nicht oder ist gesperrt.',
   'Vendor not on file!'         => 'Lieferant ist nicht in der Datenbank!',
   'Vendor type'                 => 'Lieferantentyp',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Workflow purchase_order'     => 'Workflow Lieferantenauftrag',
   'Workflow request_quotation'  => 'Workflow Preisanfrage',
   'Workflow sales_order'        => 'Workflow Auftrag',
@@ -392,6 +398,7 @@ $self->{subs} = {
   'order'                       => 'order',
   'order_links'                 => 'order_links',
   'orders'                      => 'orders',
+  'part_selection_internal'     => 'part_selection_internal',
   'poso'                        => 'poso',
   'post_as_new'                 => 'post_as_new',
   'prepare_order'               => 'prepare_order',
@@ -422,6 +429,8 @@ $self->{subs} = {
   'search'                      => 'search',
   'select_item'                 => 'select_item',
   'select_name'                 => 'select_name',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'select_project'              => 'select_project',
   'send_email'                  => 'send_email',
   'set_duedate'                 => 'set_duedate',
@@ -445,6 +454,7 @@ $self->{subs} = {
   'email'                       => 'e_mail',
   'abschlie&szlig;en'           => 'finish',
   'rechnung'                    => 'invoice',
+  'neue_ware'                   => 'new_part',
   'nein'                        => 'no',
   'auftrag'                     => 'order',
   'drucken'                     => 'print',
index 4659b32..58c17f7 100644 (file)
@@ -98,6 +98,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
   'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
   'Nov'                         => 'Nov',
   'November'                    => 'November',
@@ -109,6 +110,8 @@ $self->{texts} = {
   'POSTED AS NEW'               => 'Als neu gebucht',
   'PRINTED'                     => 'Gedruckt',
   'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
   'Pick List'                   => 'Sammelliste',
   'Please enter values'         => 'Bitte Werte eingeben',
   'Preview'                     => 'Druckvorschau',
@@ -123,6 +126,7 @@ $self->{texts} = {
   'SCREENED'                    => 'Angezeigt',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
   'Select a period'             => 'Bitte Zeitraum auswählen',
   'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
   'Sep'                         => 'Sep',
@@ -151,6 +155,8 @@ $self->{texts} = {
   'Value'                       => 'Wert',
   'Variable'                    => 'Variable',
   'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
   'Wrong Period'                => 'Falscher Zeitraum',
   'Year'                        => 'Jahr',
   'Yearly'                      => 'jährlich',
@@ -204,10 +210,13 @@ $self->{subs} = {
   'generate_ustva'              => 'generate_ustva',
   'help'                        => 'help',
   'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
   'reformat_numbers'            => 'reformat_numbers',
   'report'                      => 'report',
   'retrieve_partunits'          => 'retrieve_partunits',
   'save'                        => 'save',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
   'set_longdescription'         => 'set_longdescription',
   'show'                        => 'show',
   'show_history'                => 'show_history',
@@ -216,6 +225,7 @@ $self->{subs} = {
   'ustva_vorauswahl'            => 'ustva_vorauswahl',
   'vendor_selection'            => 'vendor_selection',
   'weiter'                      => 'continue',
+  'neue_ware'                   => 'new_part',
   'speichern'                   => 'save',
   'zeigen'                      => 'show',
   'zurück'                      => 'back',
diff --git a/locale/de/wh b/locale/de/wh
new file mode 100644 (file)
index 0000000..81fafeb
--- /dev/null
@@ -0,0 +1,254 @@
+#!/usr/bin/perl
+
+$self->{texts} = {
+  'ADDED'                       => 'Hinzugefügt',
+  'AP'                          => 'Einkauf',
+  'AP Transaction'              => 'Kreditorenbuchung',
+  'AR'                          => 'Verkauf',
+  'AR Transaction'              => 'Debitorenbuchung',
+  'Address'                     => 'Adresse',
+  'Advance turnover tax return' => 'Umsatzsteuervoranmeldung',
+  'All reports'                 => 'Alle Berichte (Konten&uuml;bersicht, Saldenbilanz, GuV, BWA, Bilanz, Projektbuchungen)',
+  'Attempt to call an undefined sub named \'%s\'' => 'Es wurde versucht, eine nicht definierte Unterfunktion namens \'%s\' aufzurufen.',
+  'Bcc'                         => 'Bcc',
+  'Bin'                         => 'Lagerplatz',
+  'Bin From'                    => 'Quelllagerplatz',
+  'Bin List'                    => 'Lagerliste',
+  'Bin To'                      => 'Ziellagerplatz',
+  'Binding to the LDAP server as "#1" failed. Please check config/authentication.pl.' => 'Die Anmeldung am LDAP-Server als "#1" schlug fehl. Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/authentication.pl.',
+  'CANCELED'                    => 'Storniert',
+  'CSV export -- options'       => 'CSV-Export -- Optionen',
+  'Cc'                          => 'Cc',
+  'Change Lx-Office installation settings (all menu entries beneath \'System\')' => 'Ver&auml;ndern der Lx-Office-Installationseinstellungen (Men&uuml;punkte unterhalb von \'System\')',
+  'Charge Number'               => 'Chargennummer',
+  'Comment'                     => 'Kommentar',
+  'Confirmation'                => 'Auftragsbestätigung',
+  'Contact'                     => 'Kontakt',
+  'Could not spawn html2ps or GhostScript.' => 'html2ps oder GhostScript konnte nicht gestartet werden.',
+  'Could not spawn the printer command.' => 'Die Druckanwendung konnte nicht gestartet werden.',
+  'Could not write the html2ps config file.' => 'Die tempor&auml;re html2ps-Konfigurationsdatei konnte nicht geschrieben werden.',
+  'Could not write the temporary HTML file.' => 'Eine tempor&auml;re HTML-Datei konnte nicht geschrieben werden.',
+  'Create and edit RFQs'        => 'Lieferantenanfragen erfassen und bearbeiten',
+  'Create and edit customers and vendors' => 'Kunden und Lieferanten erfassen und bearbeiten',
+  'Create and edit dunnings'    => 'Mahnungen erfassen und bearbeiten',
+  'Create and edit invoices and credit notes' => 'Rechnungen und Gutschriften erfassen und bearbeiten',
+  'Create and edit parts, services, assemblies' => 'Artikel, Dienstleistungen, Erzeugnisse erfassen und bearbeiten',
+  'Create and edit projects'    => 'Projekte erfassen und bearbeiten',
+  'Create and edit purchase delivery orders' => 'Lieferscheine von Lieferanten erfassen und bearbeiten',
+  'Create and edit purchase orders' => 'Lieferantenauftr&auml;ge erfassen und bearbeiten',
+  'Create and edit sales delivery orders' => 'Lieferscheine f&uuml;r Kunden erfassen und bearbeiten',
+  'Create and edit sales orders' => 'Auftragsbest&auml;tigungen erfassen und bearbeiten',
+  'Create and edit sales quotations' => 'Angebote erfassen und bearbeiten',
+  'Create and edit vendor invoices' => 'Eingangsrechnungen erfassen und bearbeiten',
+  'Credit Note'                 => 'Gutschrift',
+  'Customer'                    => 'Kunde',
+  'Customer Number'             => 'Kundennummer',
+  'Customer details'            => 'Kundendetails',
+  'DATEV Export'                => 'DATEV-Export',
+  'DELETED'                     => 'Gelöscht',
+  'DUNNING STARTED'             => 'Mahnprozess gestartet',
+  'Dataset upgrade'             => 'Datenbankaktualisierung',
+  'Date'                        => 'Datum',
+  'Dependency loop detected:'   => 'Schleife in den Abh&auml;ngigkeiten entdeckt:',
+  'Description'                 => 'Beschreibung',
+  'Directory'                   => 'Verzeichnis',
+  'Dunning'                     => 'Mahnung',
+  'ELSE'                        => 'Zusatz',
+  'Employee'                    => 'Bearbeiter',
+  'Enter longdescription'       => 'Langtext eingeben',
+  'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
+  'File'                        => 'Datei',
+  'GL Transaction'              => 'Dialogbuchung',
+  'General ledger and cash'     => 'Finanzbuchhaltung und Zahlungsverkehr',
+  'History'                     => 'Historie',
+  'Invalid quantity.'           => 'Die Mengenangabe ist ung&uuml;ltig.',
+  'Invoice'                     => 'Rechnung',
+  'MAILED'                      => 'Gesendet',
+  'Manage license keys'         => 'Lizenzschl&uuml;ssel verwalten',
+  'Mark as paid?'               => 'Als bezahlt markieren?',
+  'Marked as paid'              => 'Als bezahlt markiert',
+  'Master Data'                 => 'Stammdaten',
+  'May set the BCC field when sending emails' => 'Beim Verschicken von Emails das Feld \'BCC\' setzen',
+  'Message'                     => 'Nachricht',
+  'Missing \'description\' field.' => 'Fehlendes Feld \'description\'.',
+  'Missing \'tag\' field.'      => 'Fehlendes Feld \'tag\'.',
+  'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
+  'More than one control file with the tag \'%s\' exist.' => 'Es gibt mehr als eine Kontrolldatei mit dem Tag \'%s\'.',
+  'Name'                        => 'Name',
+  'No'                          => 'Nein',
+  'No %s was found matching the search parameters.' => 'Es wurde kein %s gefunden, auf den die Suchparameter zutreffen.',
+  'No Customer was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Endkunde gefunden',
+  'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
+  'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
+  'No or an unknown authenticantion module specified in "config/authentication.pl".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/authentication.pl" angegeben.',
+  'No part was found matching the search parameters.' => 'Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.',
+  'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
+  'No warehouse has been created yet.' => 'Es wurde noch kein Lager angelegt.',
+  'Nothing has been selected for removal.' => 'Es wurde nichts f&uuml;r eine Entnahme ausgew&auml;hlt.',
+  'Nothing has been selected for transfer.' => 'Es wurde nichts zum Umlagern ausgew&auml;hlt.',
+  'Others'                      => 'Andere',
+  'PAYMENT POSTED'              => 'Rechung gebucht',
+  'PDF export -- options'       => 'PDF-Export -- Optionen',
+  'POSTED'                      => 'Gebucht',
+  'POSTED AS NEW'               => 'Als neu gebucht',
+  'PRINTED'                     => 'Gedruckt',
+  'Packing List'                => 'Lieferschein',
+  'Part Number'                 => 'Artikelnummer',
+  'Part description'            => 'Artikelbeschreibung',
+  'Pick List'                   => 'Sammelliste',
+  'Please ask your administrator to create warehouses and bins.' => 'Bitten Sie Ihren Administrator, dass er Lager und Lagerpl&auml;tze anlegt.',
+  'Please enter values'         => 'Bitte Werte eingeben',
+  'Proforma Invoice'            => 'Proformarechnung',
+  'Project Number'              => 'Projektnummer',
+  'Purchase Order'              => 'Lieferantenauftrag',
+  'Qty'                         => 'Menge',
+  'Quantity missing.'           => 'Die Mengenangabe fehlt.',
+  'Quotation'                   => 'Angebot',
+  'RFQ'                         => 'Anfrage',
+  'Receipt, payment, reconciliation' => 'Zahlungseingang, Zahlungsausgang, Kontenabgleich',
+  'Removal'                     => 'Entnahme',
+  'Removal from Warehouse'      => 'Lagerentnahme',
+  'Report about wareouse contents' => 'Bericht &uuml;ber eingelagerte Waren',
+  'Reports'                     => 'Berichte',
+  'Request quotation'           => 'Preisanfrage',
+  'SAVED'                       => 'Gespeichert',
+  'SAVED FOR DUNNING'           => 'Gespeichert',
+  'SCREENED'                    => 'Angezeigt',
+  'Sales Invoice'               => 'Rechnung',
+  'Sales Order'                 => 'Kundenauftrag',
+  'Sales quotation'             => 'Angebot',
+  'Select a Customer'           => 'Endkunde auswählen',
+  'Select a customer'           => 'Einen Kunden ausw&auml;hlen',
+  'Select a part'               => 'Artikel ausw&auml;hlen',
+  'Select a vendor'             => 'Einen Lieferanten ausw&auml;hlen',
+  'Stock'                       => 'Einlagern',
+  'Storno Invoice'              => 'Stornorechnung',
+  'Storno Packing List'         => 'Stornolieferschein',
+  'Subject'                     => 'Betreff',
+  'The \'tag\' field must only consist of alphanumeric characters or the carachters - _ ( )' => 'Das Feld \'tag\' darf nur aus alphanumerischen Zeichen und den Zeichen - _ ( ) bestehen.',
+  'The LDAP server "#1:#2" is unreachable. Please check config/authentication.pl.' => 'Der LDAP-Server "#1:#2" ist nicht erreichbar. Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/authentication.pl.',
+  'The config file "config/authentication.pl" contained invalid Perl code:' => 'Die Konfigurationsdatei "config/authentication.pl" enthielt ung&uuml;tigen Perl-Code:',
+  'The config file "config/authentication.pl" was not found.' => 'Die Konfigurationsdatei "config/authentication.pl" wurde nicht gefunden.',
+  'The connection to the LDAP server cannot be encrypted (SSL/TLS startup failure). Please check config/authentication.pl.' => 'Die Verbindung zum LDAP-Server kann nicht verschl&uuml;sselt werden (Fehler bei SSL/TLS-Initialisierung). Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/authentication.pl.',
+  'The connection to the authentication database failed:' => 'Die Verbindung zur Authentifizierungsdatenbank schlug fehl:',
+  'The connection to the template database failed:' => 'Die Verbindung zur Vorlagendatenbank schlug fehl:',
+  'The creation of the authentication database failed:' => 'Das Anlegen der Authentifizierungsdatenbank schlug fehl:',
+  'The list has been printed.'  => 'Die Liste wurde ausgedruckt.',
+  'The parts have been removed.' => 'Die Waren wurden aus dem Lager entnommen.',
+  'The parts have been stocked.' => 'Die Artikel wurden eingelagert.',
+  'The parts have been transferred.' => 'Die Waren wurden umgelagert.',
+  'The selected bin does not exist.' => 'Der ausgew&auml;hlte Lagerplatz existiert nicht.',
+  'The selected warehouse does not exist.' => 'Das ausgew&auml;hlte Lager existiert nicht.',
+  'The selected warehouse is empty.' => 'Das ausgew&auml;hlte Lager ist leer.',
+  'The source warehouse does not contain any bins.' => 'Das Quelllager enth&auml;lt keine Lagerpl&auml;tze.',
+  'The warehouse does not contain any bins.' => 'Das Lager enth&auml;lt keine Lagerpl&auml;tze.',
+  'The warehouse or the bin is missing.' => 'Das Lager oder der Lagerplatz fehlen.',
+  'There is not enough left of \'#1\' in bin \'#2\' for the removal of #3.' => 'In Lagerplatz \'#2\' ist nicht genug von \'#1\' vorhanden, um #3 zu entnehmen.',
+  'To (email)'                  => 'An',
+  'Trans Id'                    => 'Trans-ID',
+  'Trans Type'                  => 'Trasfertyp',
+  'Transactions, AR transactions, AP transactions' => 'Dialogbuchen, Debitorenrechnungen, Kreditorenrechnungen',
+  'Transfer'                    => 'Umlagern',
+  'Trying to call a sub without a name' => 'Es wurde versucht, eine Unterfunktion ohne Namen aufzurufen.',
+  'Unit'                        => 'Einheit',
+  'Unit missing.'               => 'Die Einheit fehlt.',
+  'Unknown dependency \'%s\'.'  => 'Unbekannte Abh&auml;ngigkeit \'%s\'.',
+  'Value'                       => 'Wert',
+  'Variable'                    => 'Variable',
+  'Vendor'                      => 'Lieferant',
+  'Vendor Invoice'              => 'Einkaufsrechnung',
+  'Vendor details'              => 'Lieferantendetails',
+  'View warehouse content'      => 'Lagerbestand ansehen',
+  'WHJournal'                   => 'Lagerbuchungen',
+  'Warehouse'                   => 'Lager',
+  'Warehouse From'              => 'Quelllager',
+  'Warehouse To'                => 'Ziellager',
+  'Warehouse management'        => 'Lagerverwaltung/Bestandsveränderung',
+  'Yes'                         => 'Ja',
+  'You can create warehouses and bins via the menu "System -> Warehouses".' => 'Sie k&ouml;nnen Lager und Lagerpl&auml;tze &uuml;ber das Men&uuml; "System -> Lager" anlegen.',
+  'You do not have the permissions to access this function.' => 'Sie verf&uuml;gen nicht &uuml;ber die notwendigen Rechte, um auf diese Funktion zuzugreifen.',
+  '[email]'                     => '[email]',
+  'back'                        => 'zurück',
+  'bin_list'                    => 'Lagerliste',
+  'config/authentication.pl: Key "DB_config" is missing.' => 'config/authentication.pl: Das Schl&uuml;sselwort "DB_config" fehlt.',
+  'config/authentication.pl: Key "LDAP_config" is missing.' => 'config/authentication.pl: Der Schl&uuml;ssel "LDAP_config" fehlt.',
+  'config/authentication.pl: Missing parameters in "DB_config". Required parameters are "host", "db" and "user".' => 'config/authentication.pl: Fehlende Parameter in "DB_config". Ben&ouml;tigte Parameter sind "host", "db" und "user".',
+  'config/authentication.pl: Missing parameters in "LDAP_config". Required parameters are "host", "attribute" and "base_dn".' => 'config/authentication.pl: Fehlende Parameter in "LDAP_config". Ben&ouml;tigt werden "host", "attribute" und "base_dn".',
+  'correction'                  => 'Korrektur',
+  'customer'                    => 'Kunde',
+  'disposed'                    => 'Entsorgung',
+  'found'                       => 'Gefunden',
+  'invoice'                     => 'Rechnung',
+  'missing'                     => 'Fehlbestand',
+  'no'                          => 'nein',
+  'packing_list'                => 'Versandliste',
+  'pick_list'                   => 'Entnahmeliste',
+  'proforma'                    => 'Proforma',
+  'purchase_order'              => 'Auftrag',
+  'release_material'            => 'Materialausgabebe',
+  'report_generator_dispatch_to is not defined.' => 'report_generator_dispatch_to ist nicht definiert.',
+  'report_generator_nextsub is not defined.' => 'report_generator_nextsub ist nicht definiert.',
+  'request_quotation'           => 'Angebotsanforderung',
+  'return_material'             => 'Materialr&uuml;ckgabe',
+  'sales_order'                 => 'Kundenauftrag',
+  'sales_quotation'             => 'Verkaufsangebot',
+  'stock'                       => 'Einlagerung',
+  'transfer'                    => 'Umlagerung',
+  'used'                        => 'Verbraucht',
+  'vendor'                      => 'Lieferant',
+  'yes'                         => 'ja',
+};
+
+$self->{subs} = {
+  'E'                           => 'E',
+  'H'                           => 'H',
+  'NTI'                         => 'NTI',
+  'Q'                           => 'Q',
+  'build_std_url'               => 'build_std_url',
+  'calculate_qty'               => 'calculate_qty',
+  'call_sub'                    => 'call_sub',
+  'continue'                    => 'continue',
+  'cov_selection_internal'      => 'cov_selection_internal',
+  'delivery_customer_selection' => 'delivery_customer_selection',
+  'format_dates'                => 'format_dates',
+  'generate_journal'            => 'generate_journal',
+  'generate_report'             => 'generate_report',
+  'get_bin_idx'                 => 'get_bin_idx',
+  'get_warehouse_idx'           => 'get_warehouse_idx',
+  'journal'                     => 'journal',
+  'mark_as_paid_common'         => 'mark_as_paid_common',
+  'part_selection_internal'     => 'part_selection_internal',
+  'reformat_numbers'            => 'reformat_numbers',
+  'removal_parts_selection'     => 'removal_parts_selection',
+  'remove_parts'                => 'remove_parts',
+  'report'                      => 'report',
+  'report_generator_back'       => 'report_generator_back',
+  'report_generator_dispatcher' => 'report_generator_dispatcher',
+  'report_generator_do'         => 'report_generator_do',
+  'report_generator_export_as_csv' => 'report_generator_export_as_csv',
+  'report_generator_export_as_pdf' => 'report_generator_export_as_pdf',
+  'retrieve_partunits'          => 'retrieve_partunits',
+  'select_part'                 => 'select_part',
+  'select_part_internal'        => 'select_part_internal',
+  'set_longdescription'         => 'set_longdescription',
+  'show_history'                => 'show_history',
+  'show_no_warehouses_error'    => 'show_no_warehouses_error',
+  'show_vc_details'             => 'show_vc_details',
+  'stock'                       => 'stock',
+  'transfer_or_removal_prepare_contents' => 'transfer_or_removal_prepare_contents',
+  'transfer_parts'              => 'transfer_parts',
+  'transfer_parts_selection'    => 'transfer_parts_selection',
+  'transfer_stock'              => 'transfer_stock',
+  'transfer_stock_get_partunit' => 'transfer_stock_get_partunit',
+  'transfer_stock_part_selected' => 'transfer_stock_part_selected',
+  'transfer_stock_update_part'  => 'transfer_stock_update_part',
+  'transfer_warehouse_selection' => 'transfer_warehouse_selection',
+  'update'                      => 'update',
+  'vendor_selection'            => 'vendor_selection',
+  'weiter'                      => 'continue',
+  'neue_ware'                   => 'new_part',
+  'einlagern'                   => 'stock',
+  'erneuern'                    => 'update',
+};
+
+1;
index 1522221..859e4bd 100644 (file)
--- a/menu.ini
+++ b/menu.ini
@@ -206,6 +206,43 @@ action=search
 nextsub=ap_transactions
 
 
+[Warehouse]
+
+[Warehouse--Stock]
+ACCESS=warehouse_management
+module=wh.pl
+action=transfer_warehouse_selection
+trans_type=stock
+
+[Warehouse--Transfer]
+ACCESS=warehouse_management
+module=wh.pl
+action=transfer_warehouse_selection
+trans_type=transfer
+
+[Warehouse--Removal]
+ACCESS=warehouse_management
+module=wh.pl
+action=transfer_warehouse_selection
+trans_type=removal
+
+[Warehouse--Reports]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[Warehouse--Reports--Warehouse content]
+ACCESS=warehouse_content | warehouse_management
+module=wh.pl
+action=report
+
+[Warehouse--Reports--WHJournal]
+ACCESS=warehouse_management
+module=wh.pl
+action=journal
+
+
 [General Ledger]
 
 [General Ledger--Add Transaction]
@@ -638,6 +675,20 @@ module=amcvar.pl
 action=list_cvar_configs
 cvar_module=CT
 
+[System--Warehouses]
+module=menu.pl
+action=acc_menu
+target=acc_menu
+submenu=1
+
+[System--Warehouses--Add Warehouse]
+module=am.pl
+action=add_warehouse
+
+[System--Warehouses--List Warehouses]
+module=am.pl
+action=list_warehouses
+
 
 #[System--Import Datanorm]
 #module=menu.pl
diff --git a/sql/Pg-upgrade2/warehouse.sql b/sql/Pg-upgrade2/warehouse.sql
new file mode 100644 (file)
index 0000000..39db42b
--- /dev/null
@@ -0,0 +1,117 @@
+-- @tag: warehouse
+-- @description: Diverse neue Tabellen und Spalten zur Mehrlagerf&auml;higkeit
+-- @depends: release_2_4_3
+
+-- Tabelle "bin" für Lagerplätze.
+CREATE TABLE bin (
+  id integer NOT NULL DEFAULT nextval('id'),
+  warehouse_id integer NOT NULL,
+  description text,
+  itime timestamp DEFAULT now(),
+  mtime timestamp,
+
+  PRIMARY KEY (id),
+  FOREIGN KEY (warehouse_id) REFERENCES warehouse (id)
+);
+
+CREATE TRIGGER mtime_bin BEFORE UPDATE ON bin
+    FOR EACH ROW EXECUTE PROCEDURE set_mtime();
+
+-- Tabelle "warehouse"
+ALTER TABLE warehouse ADD COLUMN sortkey integer;
+CREATE SEQUENCE tmp_counter;
+UPDATE warehouse SET sortkey = nextval('tmp_counter');
+DROP SEQUENCE tmp_counter;
+
+ALTER TABLE warehouse ADD COLUMN invalid boolean;
+UPDATE warehouse SET invalid = 'f';
+
+CREATE TRIGGER mtime_warehouse BEFORE UPDATE ON warehouse
+    FOR EACH ROW EXECUTE PROCEDURE set_mtime();
+
+-- Tabelle "transfer_type"
+CREATE TABLE transfer_type (
+  id integer NOT NULL DEFAULT nextval('id'),
+  direction varchar(10) NOT NULL,
+  description text,
+  sortkey integer,
+  itime timestamp DEFAULT now(),
+  mtime timestamp,
+
+  PRIMARY KEY (id)
+);
+
+CREATE TRIGGER mtime_transfer_type BEFORE UPDATE ON transfer_type
+    FOR EACH ROW EXECUTE PROCEDURE set_mtime();
+
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('in', 'stock', 1);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('in', 'found', 2);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('in', 'correction', 3);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'used', 4);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'disposed', 5);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'back', 6);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'missing', 7);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('out', 'correction', 9);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('transfer', 'transfer', 10);
+INSERT INTO transfer_type (direction, description, sortkey) VALUES ('transfer', 'correction', 11);
+
+-- Anpassungen an "inventory".
+DELETE FROM inventory;
+
+ALTER TABLE inventory ADD COLUMN bin_id integer;
+ALTER TABLE inventory ADD FOREIGN KEY (bin_id) REFERENCES bin (id);
+ALTER TABLE inventory ALTER COLUMN bin_id SET NOT NULL;
+
+ALTER TABLE inventory DROP COLUMN qty;
+ALTER TABLE inventory ADD COLUMN qty numeric(25, 5);
+
+ALTER TABLE inventory ALTER COLUMN parts_id SET NOT NULL;
+ALTER TABLE inventory ADD FOREIGN KEY (parts_id) REFERENCES parts(id);
+
+ALTER TABLE inventory ALTER COLUMN warehouse_id SET NOT NULL;
+ALTER TABLE inventory ADD FOREIGN KEY (warehouse_id) REFERENCES warehouse(id);
+
+ALTER TABLE inventory ALTER COLUMN employee_id SET NOT NULL;
+ALTER TABLE inventory ADD FOREIGN KEY (employee_id) REFERENCES employee (id);
+
+ALTER TABLE inventory ADD COLUMN trans_id integer;
+ALTER TABLE inventory ALTER COLUMN trans_id SET NOT NULL;
+
+ALTER TABLE inventory ADD COLUMN trans_type_id integer;
+ALTER TABLE inventory ALTER COLUMN trans_type_id SET NOT NULL;
+ALTER TABLE inventory ADD FOREIGN KEY (trans_type_id) REFERENCES transfer_type (id);
+
+ALTER TABLE inventory ADD COLUMN project_id integer;
+ALTER TABLE inventory ADD FOREIGN KEY (project_id) REFERENCES project (id);
+
+ALTER TABLE inventory ADD COLUMN chargenumber text;
+ALTER TABLE inventory ADD COLUMN comment text;
+
+-- "onhand" in "parts" Ã¼ber einen Trigger automatisch berechnen lassen.
+ALTER TABLE parts DROP COLUMN onhand;
+ALTER TABLE parts ADD COLUMN onhand numeric(25,5);
+UPDATE parts SET onhand = COALESCE((SELECT SUM(qty) FROM inventory WHERE inventory.parts_id = parts.id), 0);
+
+ALTER TABLE parts ADD COLUMN stockable boolean;
+ALTER TABLE parts ALTER COLUMN stockable SET DEFAULT 'f';
+UPDATE parts SET stockable = 'f';
+
+CREATE OR REPLACE FUNCTION update_onhand() RETURNS trigger AS '
+BEGIN
+  IF tg_op = ''INSERT'' THEN
+    UPDATE parts SET onhand = COALESCE(onhand, 0) + new.qty WHERE id = new.parts_id;
+    RETURN new;
+  ELSIF tg_op = ''DELETE'' THEN
+    UPDATE parts SET onhand = COALESCE(onhand, 0) - old.qty WHERE id = old.parts_id;
+    RETURN old;
+  ELSE
+    UPDATE parts SET onhand = COALESCE(onhand, 0) - old.qty + new.qty WHERE id = old.parts_id;
+    RETURN new;
+  END IF;
+END;
+' LANGUAGE plpgsql;
+
+CREATE TRIGGER trig_update_onhand
+  AFTER INSERT OR UPDATE OR DELETE ON inventory
+  FOR EACH ROW EXECUTE PROCEDURE update_onhand();
+
diff --git a/templates/webpages/am/confirm_delete_warehouse_de.html b/templates/webpages/am/confirm_delete_warehouse_de.html
new file mode 100644 (file)
index 0000000..6244412
--- /dev/null
@@ -0,0 +1,21 @@
+[% USE HTML %]<body>
+
+ <div class="listtop">[% title %]</div>
+
+ <p>Wollen Sie dieses Lager wirklich l&ouml;schen?</p>
+
+ <p>Lager: [% HTML.escape(orig_description) %]</p>
+
+ <form action="am.pl" method="post">
+
+  <input type="hidden" name="id" value="[% HTML.escape(id) %]">
+  <input type="hidden" name="callback" value="[% HTML.escape(callback) %]">
+  <input type="hidden" name="type" value="warehouse">
+  <input type="hidden" name="confirmed" value="1">
+
+  <button type="button" class="submit" onclick="history.back()">Zurück</button>
+  <input type="submit" class="submit" name="action" value="Löschen">
+ </form>
+
+</body>
+</form>
diff --git a/templates/webpages/am/confirm_delete_warehouse_master.html b/templates/webpages/am/confirm_delete_warehouse_master.html
new file mode 100644 (file)
index 0000000..24bec53
--- /dev/null
@@ -0,0 +1,21 @@
+[% USE HTML %]<body>
+
+ <div class="listtop">[% title %]</div>
+
+ <p><translate>Do you really want to delete this warehouse?</translate></p>
+
+ <p><translate>Warehouse</translate>: [% HTML.escape(orig_description) %]</p>
+
+ <form action="am.pl" method="post">
+
+  <input type="hidden" name="id" value="[% HTML.escape(id) %]">
+  <input type="hidden" name="callback" value="[% HTML.escape(callback) %]">
+  <input type="hidden" name="type" value="warehouse">
+  <input type="hidden" name="confirmed" value="1">
+
+  <button type="button" class="submit" onclick="history.back()"><translate>Back</translate></button>
+  <input type="submit" class="submit" name="action" value="<translate>Delete</translate>">
+ </form>
+
+</body>
+</form>
diff --git a/templates/webpages/am/edit_warehouse_de.html b/templates/webpages/am/edit_warehouse_de.html
new file mode 100644 (file)
index 0000000..81bf9a4
--- /dev/null
@@ -0,0 +1,111 @@
+[% USE HTML %]<body [% IF onload %]onload="[% onload %]"[% END %]>
+
+ [% IF saved_message %]
+  <p>[% saved_message %]</p>
+ [% END %]
+
+ <form method="post" action="am.pl">
+
+  <input type="hidden" name="id" value="[% HTML.escape(id) %]">
+
+  <input type="hidden" name="type" value="warehouse">
+  <input type="hidden" name="callback" value="[% HTML.escape(callback) %]">
+
+  <div class="listtop">[% IF id %]Lager bearbeiten[% ELSE %]Lager erfassen[% END %]</div>
+
+  <table border="0">
+   <tr>
+    <td align="right">Beschreibung</td>
+    <td>
+     <input name="description" size="60" value="[% HTML.escape(description) %]">
+     <input type="hidden" name="orig_description" value="[% HTML.escape(description) %]">
+    </td>
+   </tr>
+
+   <tr>
+    <td align="right">Ung&uuml;ltig</td>
+    <td><input type="checkbox" name="invalid" value="1" [% IF invalid %]checked[% END %]></td>
+   </tr>
+
+   <tr>
+    <td align="right">Anzahl neuer Lagerpl&auml;tze</td>
+    <td><input name="number_of_new_bins"></td>
+   </tr>
+
+   <tr>
+    <td align="right">Namenspr&auml;fix f&uuml;r die neuen Lagerpl&auml;tze</td>
+    <td><input name="prefix" value="Lagerplatz"></td>
+   </tr>
+  </table>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="Speichern">
+   [%- IF id %][%- UNLESS in_use %]
+   <input type="submit" class="submit" name="action" value="Löschen">
+   [%- END %][%- END %]
+  </p>
+
+ </form>
+
+ [% IF id %]
+
+ <hr height="3">
+
+ <div class="listtop">Lagerpl&auml;tze bearbeiten</div>
+
+ [% UNLESS BINS.size %]
+ <p>Es wurden zu diesem Lager noch keine Lagerpl&auml;tze angelegt.</p>
+
+ [% ELSE %]
+
+ <p>
+  Lagerpl&auml;tze, die bereits benutzt wurden, k&ouml;nnen nicht mehr gel&ouml;scht werden. Deswegen fehlt bei ihnen die Checkbox in der Spalte &quot;L&ouml;schen&quot;.
+ </p>
+
+ <form method="post" action="am.pl">
+
+  <input type="hidden" name="warehouse_id" value="[% HTML.escape(id) %]">
+
+  <input type="hidden" name="type" value="bin">
+  <input type="hidden" name="callback" value="[% HTML.escape(callback) %]">
+
+  <table border="0">
+   <tr>
+    <th class="listheading">Löschen</th><th class="listheading">Beschreibung</th>
+    <th class="listheading">Löschen</th><th class="listheading">Beschreibung</th>
+   </tr>
+   [%- SET row_odd = '1' %]
+   [%- USE bin_it = Iterator(BINS) %]
+   [%- FOREACH bin = bin_it %]
+   [%- IF row_odd %]
+   <tr>
+    [%- END %]
+
+    <td>[% IF bin.in_use %]&nbsp;[% ELSE %]<input type="checkbox" name="delete_[% bin_it.count %]" value="1">[% END %]</td>
+    <td>
+     <input type="hidden" name="id_[% bin_it.count %]" value="[% HTML.escape(bin.id) %]">
+     <input name="description_[% bin_it.count %]" value="[% HTML.escape(bin.description) %]">
+    </td>
+
+    [%- SET end_tr = '0' %]
+    [%- UNLESS row_odd %][%- SET end_tr = '1' %][%- END %]
+    [%- IF bin_it.last %][%- SET end_tr = '1' %][%- END %]
+    [%- IF end_tr %]
+   </tr>
+   [%- END %]
+
+   [%- IF row_odd %][% SET row_odd = '0' %][% ELSE %][% SET row_odd = '1' %][% END %]
+   [%- END %]
+  </table>
+
+  <input type="hidden" name="rowcount" value="[% BINS.size %]">
+
+  <p><input type="submit" class="submit" name="action" value="Speichern"></p>
+ </form>
+
+ [% END %]
+
+ [% END %]
+
+</body>
+</html>
diff --git a/templates/webpages/am/edit_warehouse_master.html b/templates/webpages/am/edit_warehouse_master.html
new file mode 100644 (file)
index 0000000..d6f21ce
--- /dev/null
@@ -0,0 +1,113 @@
+[% USE HTML %]<body [% IF onload %]onload="[% onload %]"[% END %]>
+
+ [% IF saved_message %]
+  <p>[% saved_message %]</p>
+ [% END %]
+
+ <form method="post" action="am.pl">
+
+  <input type="hidden" name="id" value="[% HTML.escape(id) %]">
+
+  <input type="hidden" name="type" value="warehouse">
+  <input type="hidden" name="callback" value="[% HTML.escape(callback) %]">
+
+  <div class="listtop">[% IF id %]<translate>Edit Warehouse</translate>[% ELSE %]<translate>Add Warehouse</translate>[% END %]</div>
+
+  <table border="0">
+   <tr>
+    <td align="right"><translate>Description</translate></td>
+    <td>
+     <input name="description" size="60" value="[% HTML.escape(description) %]">
+     <input type="hidden" name="orig_description" value="[% HTML.escape(description) %]">
+    </td>
+   </tr>
+
+   <tr>
+    <td align="right"><translate>Invalid</translate></td>
+    <td><input type="checkbox" name="invalid" value="1" [% IF invalid %]checked[% END %]></td>
+   </tr>
+
+   <tr>
+    <td align="right"><translate>Number of new bins</translate></td>
+    <td><input name="number_of_new_bins"></td>
+   </tr>
+
+   <tr>
+    <td align="right"><translate>Prefix for the new bins' names</translate></td>
+    <td><input name="prefix" value="<translate>Bin</translate>"></td>
+   </tr>
+  </table>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="<translate>Save</translate>">
+   [%- IF id %][%- UNLESS in_use %]
+   <input type="submit" class="submit" name="action" value="<translate>Delete</translate>">
+   [%- END %][%- END %]
+  </p>
+
+ </form>
+
+ [% IF id %]
+
+ <hr height="3">
+
+ <div class="listtop"><translate>Edit Bins</translate></div>
+
+ [% UNLESS BINS.size %]
+ <p><translate>No bins have been added to this warehouse yet.</translate></p>
+
+ [% ELSE %]
+
+ <p>
+  <translate>Bins that have been used in the past cannot be deleted
+   anymore. For these bins there's no checkbox in the
+   &quot;Delete&quot; column.</translate>
+ </p>
+
+ <form method="post" action="am.pl">
+
+  <input type="hidden" name="warehouse_id" value="[% HTML.escape(id) %]">
+
+  <input type="hidden" name="type" value="bin">
+  <input type="hidden" name="callback" value="[% HTML.escape(callback) %]">
+
+  <table border="0">
+   <tr>
+    <th class="listheading"><translate>Delete</translate></th><th class="listheading"><translate>Description</translate></th>
+    <th class="listheading"><translate>Delete</translate></th><th class="listheading"><translate>Description</translate></th>
+   </tr>
+   [%- SET row_odd = '1' %]
+   [%- USE bin_it = Iterator(BINS) %]
+   [%- FOREACH bin = bin_it %]
+   [%- IF row_odd %]
+   <tr>
+    [%- END %]
+
+    <td>[% IF bin.in_use %]&nbsp;[% ELSE %]<input type="checkbox" name="delete_[% bin_it.count %]" value="1">[% END %]</td>
+    <td>
+     <input type="hidden" name="id_[% bin_it.count %]" value="[% HTML.escape(bin.id) %]">
+     <input name="description_[% bin_it.count %]" value="[% HTML.escape(bin.description) %]">
+    </td>
+
+    [%- SET end_tr = '0' %]
+    [%- UNLESS row_odd %][%- SET end_tr = '1' %][%- END %]
+    [%- IF bin_it.last %][%- SET end_tr = '1' %][%- END %]
+    [%- IF end_tr %]
+   </tr>
+   [%- END %]
+
+   [%- IF row_odd %][% SET row_odd = '0' %][% ELSE %][% SET row_odd = '1' %][% END %]
+   [%- END %]
+  </table>
+
+  <input type="hidden" name="rowcount" value="[% BINS.size %]">
+
+  <p><input type="submit" class="submit" name="action" value="<translate>Save</translate>"></p>
+ </form>
+
+ [% END %]
+
+ [% END %]
+
+</body>
+</html>
diff --git a/templates/webpages/am/list_warehouses_de.html b/templates/webpages/am/list_warehouses_de.html
new file mode 100644 (file)
index 0000000..fe688ba
--- /dev/null
@@ -0,0 +1,42 @@
+[% USE HTML %]<body>
+
+ [% IF saved_message %]<p>[% saved_message %]</p>[% END %]
+
+ <div class="listtop">[% title %]</div>
+
+ <p>
+  <table width="100%">
+   <tr>
+    <td class="listheading" width="0%"></td>
+    <td class="listheading" width="0%"></td>
+    <td class="listheading" width="70%">Beschreibung</td>
+    <td class="listheading" width="20%">Anzahl Lagerpl&auml;tze</td>
+    <td class="listheading" width="20%">Personenlager von</td>
+    <td class="listheading" width="10%">Ung&uuml;ltig</td>
+   </tr>
+
+   [% SET row_odd = '1' %][% FOREACH warehouse = WAREHOUSES %]
+   <tr class="listrow[% IF row_odd %]1[% SET row_odd = '0' %][% ELSE %]0[% SET row_odd = '1' %][% END %]">
+    <td>[% IF warehouse.previous_id %]<a href="[% url_base %]&action=swap_warehouses&id1=[% HTML.url(warehouse.previous_id) %]&id2=[% HTML.url(warehouse.id) %]"><img border="0" src="image/up.png"></a>[% END %]</td>
+    <td>[% IF warehouse.next_id %]<a href="[% url_base %]&action=swap_warehouses&id1=[% HTML.url(warehouse.next_id) %]&id2=[% HTML.url(warehouse.id) %]"><img border="0" src="image/down.png"></a>[% END %]</td>
+    <td><a href="[% url_base %]&action=edit_warehouse&id=[% HTML.url(warehouse.id) %]">[% HTML.escape(warehouse.description) %]</a></td>
+    <td>[% HTML.escape(warehouse.number_of_bins) %]</td>
+    <td>[% IF warehouse.personal_warehouse_of %][% HTML.escape(warehouse.personal_warehouse_of_name) %][% ELSE %]-[% END %]</td>
+    <td>[% IF warehouse.invalid %]Ja[% ELSE %]Nein[% END %]</td>
+   </tr>
+   [% END %]
+  </table>
+ </p>
+
+ <hr height="3">
+
+ <p>
+  <form method="post" action="am.pl">
+   <input type="hidden" name="type" value="warehouse">
+
+   <input type="submit" class="submit" name="action" value="Erfassen">
+  </form>
+ </p>
+
+</body>
+</html>
diff --git a/templates/webpages/am/list_warehouses_master.html b/templates/webpages/am/list_warehouses_master.html
new file mode 100644 (file)
index 0000000..6f7d1de
--- /dev/null
@@ -0,0 +1,42 @@
+[% USE HTML %]<body>
+
+ [% IF saved_message %]<p>[% saved_message %]</p>[% END %]
+
+ <div class="listtop">[% title %]</div>
+
+ <p>
+  <table width="100%">
+   <tr>
+    <td class="listheading" width="0%"></td>
+    <td class="listheading" width="0%"></td>
+    <td class="listheading" width="70%"><translate>Description</translate></td>
+    <td class="listheading" width="20%"><translate>Number of bins</translate></td>
+    <td class="listheading" width="20%"><translate>Personal warehouse of</translate></td>
+    <td class="listheading" width="10%"><translate>Invalid</translate></td>
+   </tr>
+
+   [% SET row_odd = '1' %][% FOREACH warehouse = WAREHOUSES %]
+   <tr class="listrow[% IF row_odd %]1[% SET row_odd = '0' %][% ELSE %]0[% SET row_odd = '1' %][% END %]">
+    <td>[% IF warehouse.previous_id %]<a href="[% url_base %]&action=swap_warehouses&id1=[% HTML.url(warehouse.previous_id) %]&id2=[% HTML.url(warehouse.id) %]"><img border="0" src="image/up.png"></a>[% END %]</td>
+    <td>[% IF warehouse.next_id %]<a href="[% url_base %]&action=swap_warehouses&id1=[% HTML.url(warehouse.next_id) %]&id2=[% HTML.url(warehouse.id) %]"><img border="0" src="image/down.png"></a>[% END %]</td>
+    <td><a href="[% url_base %]&action=edit_warehouse&id=[% HTML.url(warehouse.id) %]">[% HTML.escape(warehouse.description) %]</a></td>
+    <td>[% HTML.escape(warehouse.number_of_bins) %]</td>
+    <td>[% IF warehouse.personal_warehouse_of %][% HTML.escape(warehouse.personal_warehouse_of_name) %][% ELSE %]-[% END %]</td>
+    <td>[% IF warehouse.invalid %]<translate>Yes</translate>[% ELSE %]<translate>No</translate>[% END %]</td>
+   </tr>
+   [% END %]
+  </table>
+ </p>
+
+ <hr height="3">
+
+ <p>
+  <form method="post" action="am.pl">
+   <input type="hidden" name="type" value="warehouse">
+
+   <input type="submit" class="submit" name="action" value="<translate>Add</translate>">
+  </form>
+ </p>
+
+</body>
+</html>
diff --git a/templates/webpages/generic/part_selection_de.html b/templates/webpages/generic/part_selection_de.html
new file mode 100644 (file)
index 0000000..f6c8b02
--- /dev/null
@@ -0,0 +1,116 @@
+[% USE HTML %]<body [% IF onload %]onload="[% onload %]"[% END %]>
+
+ <form action="[% HTML.escape(script) %]" method="post" name="Form">
+
+  <input type="hidden" name="input_partnumber" value="[% HTML.escape(input_partnumber) %]">
+  <input type="hidden" name="input_description" value="[% HTML.escape(input_description) %]">
+  <input type="hidden" name="input_partsid" value="[% HTML.escape(input_partsid) %]">
+  <input type="hidden" name="input_partnotes" value="[% HTML.escape(input_partnotes) %]">
+  <input type="hidden" name="allow_creation" value="[% HTML.escape(allow_creation) %]">
+  <input type="hidden" name="action_on_part_selected" value="[% HTML.escape(action_on_part_selected) %]">
+  <input type="hidden" name="filter" value="[% HTML.escape(filter) %]">
+  <input type="hidden" name="new_description" value="[% HTML.escape(description) %]">
+
+  <div class="listtop">[% title %]</div>
+
+  <table width="100%">
+   <tr>
+    <td>
+     [% IF no_parts_found %]
+     Es wurde kein Artikel gefunden, auf den die Suchparameter zutreffen.
+     [% IF allow_creation %]
+     Sie k&ouml;nnen jedoch einen neuen Artikel anlegen, der dann automatisch ausgew&auml;hlt wird.
+     [% END %]
+     [% ELSE %]
+     Bitte w&auml;hlen Sie einen Artikel aus der Liste aus.
+     [% IF allow_creation %]
+     Sie k&ouml;nnen auch einen neuen Artikel anlegen, der dann automatisch ausgew&auml;hlt wird.
+     [% END %]
+     [% END %]
+    </td>
+   </tr>
+
+   [% UNLESS no_parts_found %]
+   <tr>
+    <td>
+     <table>
+      <tr class="listheading">
+       <th class="listheading">&nbsp;</th>
+       [% FOREACH header = HEADER %]
+       <th nowrap class="listheading"><a href="[% HTML.escape(header.callback) %]">[% header.column_title %]</a></th>
+       [% END %]
+      </tr>
+
+      [% FOREACH part = PARTS %]
+      <tr class="listrow[% IF loop.count % 2 %]1[% ELSE %]0[% END %]">
+       <td><button type="button" onclick="part_selected('[% loop.count %]')">auswählen</button></td>
+       <td>
+        <input type="hidden" id="partsid_[% loop.count %]" name="partsid_[% loop.count %]" value="[% HTML.escape(part.id) %]">
+        <input type="hidden" id="partnumber_[% loop.count %]" name="partnumber_[% loop.count %]" value="[% HTML.escape(part.partnumber) %]">
+        [% HTML.escape(part.partnumber) %]
+       </td>
+       <td>
+        <input type="hidden" id="description_[% loop.count %]" name="description_[% loop.count %]" value="[% HTML.escape(part.description) %]">
+        <input type="hidden" id="partnotes_[% loop.count %]" name="partnotes_[% loop.count %]" value="[% HTML.escape(part.partnotes) %]">
+        [% HTML.escape(part.description) %]
+       </td>
+<!--        <td> -->
+<!--         <input type="hidden" id="onhand_[% loop.count %]" name="onhand_[% loop.count %]" value="[% HTML.escape(part.onhand) %]"> -->
+<!--         [% HTML.escape(part.onhand) %] -->
+<!--        </td> -->
+      </tr>
+      [% END %]
+     </table>
+    </td>
+   </tr>
+   [% END %]
+  </table>
+
+  [% IF allow_creation %]
+  <p><input type="submit" name="action" value="Neue Ware"></p>
+  [% END %]
+
+ </form>
+
+ <script type="text/javascript">
+  <!--
+      function part_selected(selected) {
+        var partnumber = document.getElementsByName("partnumber_" + selected)[0].value;
+        var description = document.getElementsByName("description_" + selected)[0].value;
+        var partsid = document.getElementsByName("partsid_" + selected)[0].value;
+        var partnotes = document.getElementsByName("partnotes_" + selected)[0].value;
+        var pnum_name = document.Form.input_partnumber.value;
+        window.opener.document.getElementsByName(pnum_name)[0].value = partnumber;
+        window.opener.document.getElementsByName(document.Form.input_description.value)[0].value = description;
+        if (document.Form.input_partsid.value != "") {
+          window.opener.document.getElementsByName(document.Form.input_partsid.value)[0].value = partsid;
+        }
+        if (document.Form.input_partnotes.value != "") {
+          var el = window.opener.document.getElementsByName(document.Form.input_partnotes.value)[0];
+          if (el)
+            el.value = partnotes;
+        }
+        if (document.Form.action_on_part_selected.value != "") {
+          window.opener.document.getElementsByName("action")[0].value = document.Form.action_on_part_selected.value;
+          window.opener.document.Form.submit();
+        }
+
+
+        var prefix = "";
+        if (pnum_name.substr(0, 2) == "f_") {
+          prefix = "f_";
+          pnum_name = pnum_name.substr(2);
+        }
+        pnum_name = prefix + "old_" + pnum_name;
+        var input = window.opener.document.getElementsByName(pnum_name)[0];
+        if (input) {
+          input.value = name;
+        }
+
+        self.close();
+      }
+      //-->
+ </script>
+
+</body>
+</html>
diff --git a/templates/webpages/generic/part_selection_master.html b/templates/webpages/generic/part_selection_master.html
new file mode 100644 (file)
index 0000000..41c3f51
--- /dev/null
@@ -0,0 +1,116 @@
+[% USE HTML %]<body [% IF onload %]onload="[% onload %]"[% END %]>
+
+ <form action="[% HTML.escape(script) %]" method="post" name="Form">
+
+  <input type="hidden" name="input_partnumber" value="[% HTML.escape(input_partnumber) %]">
+  <input type="hidden" name="input_description" value="[% HTML.escape(input_description) %]">
+  <input type="hidden" name="input_partsid" value="[% HTML.escape(input_partsid) %]">
+  <input type="hidden" name="input_partnotes" value="[% HTML.escape(input_partnotes) %]">
+  <input type="hidden" name="allow_creation" value="[% HTML.escape(allow_creation) %]">
+  <input type="hidden" name="action_on_part_selected" value="[% HTML.escape(action_on_part_selected) %]">
+  <input type="hidden" name="filter" value="[% HTML.escape(filter) %]">
+  <input type="hidden" name="new_description" value="[% HTML.escape(description) %]">
+
+  <div class="listtop">[% title %]</div>
+
+  <table width="100%">
+   <tr>
+    <td>
+     [% IF no_parts_found %]
+     <translate>No part was found matching the search parameters.</translate>
+     [% IF allow_creation %]
+     <translate>However, you can create a new part which will then be selected.</translate>
+     [% END %]
+     [% ELSE %]
+     <translate>Please select a part from the list below.</translate>
+     [% IF allow_creation %]
+     <translate>Alternatively you can create a new part which will then be selected.</translate>
+     [% END %]
+     [% END %]
+    </td>
+   </tr>
+
+   [% UNLESS no_parts_found %]
+   <tr>
+    <td>
+     <table>
+      <tr class="listheading">
+       <th class="listheading">&nbsp;</th>
+       [% FOREACH header = HEADER %]
+       <th nowrap class="listheading"><a href="[% HTML.escape(header.callback) %]">[% header.column_title %]</a></th>
+       [% END %]
+      </tr>
+
+      [% FOREACH part = PARTS %]
+      <tr class="listrow[% IF loop.count % 2 %]1[% ELSE %]0[% END %]">
+       <td><button type="button" onclick="part_selected('[% loop.count %]')"><translate>Select</translate></button></td>
+       <td>
+        <input type="hidden" id="partsid_[% loop.count %]" name="partsid_[% loop.count %]" value="[% HTML.escape(part.id) %]">
+        <input type="hidden" id="partnumber_[% loop.count %]" name="partnumber_[% loop.count %]" value="[% HTML.escape(part.partnumber) %]">
+        [% HTML.escape(part.partnumber) %]
+       </td>
+       <td>
+        <input type="hidden" id="description_[% loop.count %]" name="description_[% loop.count %]" value="[% HTML.escape(part.description) %]">
+        <input type="hidden" id="partnotes_[% loop.count %]" name="partnotes_[% loop.count %]" value="[% HTML.escape(part.partnotes) %]">
+        [% HTML.escape(part.description) %]
+       </td>
+<!--        <td> -->
+<!--         <input type="hidden" id="onhand_[% loop.count %]" name="onhand_[% loop.count %]" value="[% HTML.escape(part.onhand) %]"> -->
+<!--         [% HTML.escape(part.onhand) %] -->
+<!--        </td> -->
+      </tr>
+      [% END %]
+     </table>
+    </td>
+   </tr>
+   [% END %]
+  </table>
+
+  [% IF allow_creation %]
+  <p><input type="submit" name="action" value="<translate>New part</translate>"></p>
+  [% END %]
+
+ </form>
+
+ <script type="text/javascript">
+  <!--
+      function part_selected(selected) {
+        var partnumber = document.getElementsByName("partnumber_" + selected)[0].value;
+        var description = document.getElementsByName("description_" + selected)[0].value;
+        var partsid = document.getElementsByName("partsid_" + selected)[0].value;
+        var partnotes = document.getElementsByName("partnotes_" + selected)[0].value;
+        var pnum_name = document.Form.input_partnumber.value;
+        window.opener.document.getElementsByName(pnum_name)[0].value = partnumber;
+        window.opener.document.getElementsByName(document.Form.input_description.value)[0].value = description;
+        if (document.Form.input_partsid.value != "") {
+          window.opener.document.getElementsByName(document.Form.input_partsid.value)[0].value = partsid;
+        }
+        if (document.Form.input_partnotes.value != "") {
+          var el = window.opener.document.getElementsByName(document.Form.input_partnotes.value)[0];
+          if (el)
+            el.value = partnotes;
+        }
+        if (document.Form.action_on_part_selected.value != "") {
+          window.opener.document.getElementsByName("action")[0].value = document.Form.action_on_part_selected.value;
+          window.opener.document.Form.submit();
+        }
+
+
+        var prefix = "";
+        if (pnum_name.substr(0, 2) == "f_") {
+          prefix = "f_";
+          pnum_name = pnum_name.substr(2);
+        }
+        pnum_name = prefix + "old_" + pnum_name;
+        var input = window.opener.document.getElementsByName(pnum_name)[0];
+        if (input) {
+          input.value = name;
+        }
+
+        self.close();
+      }
+      //-->
+ </script>
+
+</body>
+</html>
diff --git a/templates/webpages/generic/select_part_de.html b/templates/webpages/generic/select_part_de.html
new file mode 100644 (file)
index 0000000..abf7a72
--- /dev/null
@@ -0,0 +1,61 @@
+[% USE HTML %]<body [% IF onload %]onload="[% onload %]"[% END %]>
+
+ <form method="post" action="[% HTML.escape(script) %]">
+
+  <input type="hidden" name="nextsub" value="[% HTML.escape(nextsub) %]">
+  <input type="hidden" name="callback_sub" value="[% HTML.escape(callback_sub) %]">
+
+  <input type="hidden" name="old_form" value="[% HTML.escape(old_form) %]">
+  <input type="hidden" name="remap_parts_id" value="[% HTML.escape(remap_parts_id) %]">
+  <input type="hidden" name="remap_partnumber" value="[% HTML.escape(remap_partnumber) %]">
+
+  <div class="listtop">Artikel ausw&auml;hlen</div>
+
+  <p>
+   <table>
+    <tr>
+     <th class="listheading">&nbsp;</th>
+     <th class="listheading">Nummer</th>
+     <th class="listheading">Beschreibung</th>
+     [% IF has_charge %]
+     <th class="listheading">Chargennummer</th>
+     [% END %]
+    </tr>
+
+    [% FOREACH part = PARTS %]
+    <tr class="listrow[% loop.count % 2 %]">
+     <td>
+      <input type="radio" name="selection" value="[% loop.count %]"[% IF loop.first %] checked[% END %]>
+     </td>
+
+     <td>
+      <input type="hidden" name="new_id_[% loop.count %]" value="[% HTML.escape(part.id) %]">
+      <input type="hidden" name="new_number_[% loop.count %]" value="[% HTML.escape(part.number) %]">
+      [% HTML.escape(part.number) %]
+     </td>
+
+     <td>
+      <input type="hidden" name="new_description_[% loop.count %]" value="[% HTML.escape(part.description) %]">
+      [% HTML.escape(part.description) %]
+     </td>
+
+     [% IF has_charge %]
+     <td>
+      <input type="hidden" name="new_charge_id_[% loop.count %]" value="[% HTML.escape(part.charge_id) %]">
+      <input type="hidden" name="new_chargenumber_[% loop.count %]" value="[% HTML.escape(part.chargenumber) %]">
+      [% HTML.escape(part.chargenumber) %]
+     </td>
+     [% END %]
+    </tr>
+    [% END %]
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="Weiter">
+  </p>
+
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/generic/select_part_master.html b/templates/webpages/generic/select_part_master.html
new file mode 100644 (file)
index 0000000..836dde5
--- /dev/null
@@ -0,0 +1,61 @@
+[% USE HTML %]<body [% IF onload %]onload="[% onload %]"[% END %]>
+
+ <form method="post" action="[% HTML.escape(script) %]">
+
+  <input type="hidden" name="nextsub" value="[% HTML.escape(nextsub) %]">
+  <input type="hidden" name="callback_sub" value="[% HTML.escape(callback_sub) %]">
+
+  <input type="hidden" name="old_form" value="[% HTML.escape(old_form) %]">
+  <input type="hidden" name="remap_parts_id" value="[% HTML.escape(remap_parts_id) %]">
+  <input type="hidden" name="remap_partnumber" value="[% HTML.escape(remap_partnumber) %]">
+
+  <div class="listtop"><translate>Select a part</translate></div>
+
+  <p>
+   <table>
+    <tr>
+     <th class="listheading">&nbsp;</th>
+     <th class="listheading"><translate>Number</translate></th>
+     <th class="listheading"><translate>Description</translate></th>
+     [% IF has_charge %]
+     <th class="listheading"><translate>Charge number</translate></th>
+     [% END %]
+    </tr>
+
+    [% FOREACH part = PARTS %]
+    <tr class="listrow[% loop.count % 2 %]">
+     <td>
+      <input type="radio" name="selection" value="[% loop.count %]"[% IF loop.first %] checked[% END %]>
+     </td>
+
+     <td>
+      <input type="hidden" name="new_id_[% loop.count %]" value="[% HTML.escape(part.id) %]">
+      <input type="hidden" name="new_number_[% loop.count %]" value="[% HTML.escape(part.number) %]">
+      [% HTML.escape(part.number) %]
+     </td>
+
+     <td>
+      <input type="hidden" name="new_description_[% loop.count %]" value="[% HTML.escape(part.description) %]">
+      [% HTML.escape(part.description) %]
+     </td>
+
+     [% IF has_charge %]
+     <td>
+      <input type="hidden" name="new_charge_id_[% loop.count %]" value="[% HTML.escape(part.charge_id) %]">
+      <input type="hidden" name="new_chargenumber_[% loop.count %]" value="[% HTML.escape(part.chargenumber) %]">
+      [% HTML.escape(part.chargenumber) %]
+     </td>
+     [% END %]
+    </tr>
+    [% END %]
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="<translate>Continue</translate>">
+  </p>
+
+ </form>
+
+</body>
+</html>
index 6daa36f..1d410da 100644 (file)
 
   [%- IF is_assembly %]
               <tr>
-               <th align="right" nowrap>einlagern</th>
+               <th align="right" nowrap>Einlagern</th>
                <td><input name=stock size=10 value="[% LxERP.format_amount(stock) %]"></td>
              </tr>
   [%- END %]
diff --git a/templates/webpages/wh/journal_filter_de.html b/templates/webpages/wh/journal_filter_de.html
new file mode 100644 (file)
index 0000000..4ff546e
--- /dev/null
@@ -0,0 +1,217 @@
+[% USE HTML %][% USE JavaScript %]<body onload="on_load();">
+
+ <script type="text/javascript">
+   <!--
+      warehouses = new Array();
+      warehouses[0] = new Array();
+      warehouses[0]['id'] = "0";
+      warehouses[0]['bins'] = new Array();
+      warehouses[0]['bins'][0] = new Array();
+      warehouses[0]['bins'][0]['description'] = "---";
+      warehouses[0]['bins'][0]['id'] = "";
+      [%- USE WAREHOUSES_it = Iterator(WAREHOUSES) %][%- FOREACH warehouse = WAREHOUSES_it %]
+      warehouses[[% WAREHOUSES_it.count %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['id'] = [% warehouse.id %];
+      warehouses[[% WAREHOUSES_it.count %]]['bins'] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0]['description'] = "---";
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0]['id'] = "";
+      [% USE BINS_it = Iterator(warehouse.BINS) %][% FOREACH bin = BINS_it %]
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]]['description'] = "[% JavaScript.escape(bin.description) %]";
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]]['id'] = [% bin.id %];
+      [% END %]
+      [% END %]
+
+      function warehouse_selected(warehouse_id, bin_id) {
+        var control = document.getElementById("bin_id");
+
+        for (var i = control.options.length - 1; i >= 0; i--) {
+          control.options[i] = null;
+        }
+
+        var warehouse_index = 0;
+
+        for (i = 0; i < warehouses.length; i++)
+          if (warehouses[i]['id'] == warehouse_id) {
+            warehouse_index = i;
+            break;
+          }
+
+        var warehouse = warehouses[warehouse_index];
+        var bin_index = 0;
+
+        for (i = 0; i < warehouse['bins'].length; i++)
+          if (warehouse['bins'][i]['id'] == bin_id) {
+            bin_index = i;
+            break;
+          }
+
+        for (i = 0; i < warehouse['bins'].length; i++) {
+          control.options[i] = new Option(warehouse['bins'][i]['description'], warehouse['bins'][i]['id']);
+        }
+
+
+        control.options[bin_index].selected = true;
+      }
+
+      function on_load() {
+        warehouse_selected(0, 0);
+        document.Form.partnumber.focus();
+      }
+     -->
+ </script>
+
+ <div class="listtop">Bericht &uuml;ber Lagerbewegungen</div>
+
+ <form method="post" name="Form" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="generate_journal">
+
+  <p>
+   <table>
+    <tr>
+     <th class="listheading" align="left" valign="top" colspan="6" nowrap>Filter</th>
+    </tr>
+
+    <tr>
+     <td>
+      <table>
+       <tr>
+        <th align="right" nowrap>Lager:</th>
+        <td>
+         <select name="warehouse_id" id="warehouse_id" onchange="warehouse_selected(warehouses[this.selectedIndex]['id'], 0)">
+          <option value="">---</option>
+          [%- FOREACH warehouse = WAREHOUSES %]
+          <option value="[% HTML.escape(warehouse.id) %]">[% warehouse.description %]</option>
+          [%- END %]
+         </select>
+        </td>
+       </tr>
+       <tr>
+        <th align="right" nowrap>Lagerplatz:</th>
+        <td><select name="bin_id" id="bin_id"></select></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap>Artikelnummer:</th>
+        <td><input name="partnumber" id="partnumber" size=20></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap>Artikelbeschreibung:</th>
+        <td><input name="description" size=40></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap>Chargennummer:</th>
+        <td><input name="chargenumber" size=40></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap>Umlagermenge:</th>
+        <td>
+         <select name="qty_op">
+          <option value="dontcare">---</option>
+          <option value="atleast">Mindestens</option>
+          <option value="atmost">H&ouml;chstens</option>
+          <option value="exact">Genau</option>
+         </select>
+         <input name="qty">
+         <select name="qty_unit">
+          [%- FOREACH unit = UNITS %]<option>[% unit.name %]</option>[% END %]
+         </select>
+        </td>
+       </tr>
+       <tr>
+        <th align="right" nowrap>Von</th>
+        <td>
+         <input name="fromdate" id="fromdate" size="11" title="[% myconfig_dateformat %]">
+         <input type="button" name="b_fromdate" id="fromdate_trigger" value="?">
+        </td>
+       </tr>
+       <tr>
+        <th align="right">Bis</th>
+        <td>
+         <input name="todate" id="todate" size="11" title="[% myconfig_dateformat %]">
+         <input type="button" name="b_todate" id="todate_trigger" value="?">
+        </td>
+       </tr>
+      </table>
+     </td>
+    </tr>
+
+    <tr height="5"><td>&nbsp;</td></tr>
+
+    <tr>
+     <th class="listheading" align="left" valign="top" colspan="6" nowrap>In Bericht aufnehmen</th>
+    </tr>
+
+    <tr>
+     <td>
+      <table>
+       <tr>
+        <td><input name="l_partdescription" id="l_partdescription" class="checkbox" type="hidden" value="Y" checked></td>
+        <td nowrap><label for="l_partdescription">Artikelbeschreibung</label></td>
+        <td><input name="l_qty" id="l_qty" class="checkbox" type="hidden" value="Y" checked></td>
+        <td nowrap><label for="l_qty">Menge</label></td>
+       </tr>
+       <tr>
+        <td align="right"><input name="l_date" id="l_date" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_date">Datum</label></td>
+        <td align="right"><input name="l_partnumber" id="l_partnumber" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_partnumber">Artikelnummer</label></td>
+        <td align="right"><input name="l_chargenumber" id="l_chargenumber" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_chargenumber">Chargennummer</label></td>
+       </tr>
+       <tr>
+        <td align="right"><input name="l_trans_id" id="l_trans_id" class="checkbox" type="checkbox" value="Y"></td>
+        <td nowrap><label for="l_trans_id">Trans-ID</label></td>
+        <td align="right"><input name="l_trans_type" id="l_trans_type" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_trans_type">Trasfertyp</label></td>
+        <td align="right"><input name="l_comment" id="l_comment" class="checkbox" type="checkbox" value="Y"></td>
+        <td nowrap><label for="l_comment">Kommentar</label></td>
+       </tr>
+       <tr>
+        <td align="right"><input name="l_warehouse_from" id="l_warehouse_from" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_warehouse_from">Quelllager</label></td>
+        <td align="right"><input name="l_bin_from" id="l_bin_from" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_bin_from">Quelllagerplatz</label></td>
+        <td align="right"><input name="l_warehouse_to" id="l_warehouse_to" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_warehouse_to">Ziellager</label></td>
+        <td align="right"><input name="l_bin_to" id="l_bin_to" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_bin_to">Ziellagerplatz</label></td>
+       </tr>
+       <tr>
+        <td align="right"><input name="l_employee" id="l_employee" class="checkbox" type="checkbox" value="Y"></td>
+        <td nowrap><label for="l_employee">Bearbeiter</label></td>
+        <td align="right"><input name="l_projectnumber" id="l_projectnumber" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_projectnumber">Projektnummer</label></td>
+       </tr>
+      </table>
+     </td>
+    </tr>
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="Weiter">
+  </p>
+ </form>
+
+  <script type="text/javascript">
+    <!--
+    Calendar.setup( {
+      inputField : "fromdate",
+      ifFormat :"[% myconfig_jsc_dateformat %]",
+      align : "BR",
+      button : "fromdate_trigger"
+    });
+
+     Calendar.setup( {
+      inputField : "todate",
+      ifFormat :"[% myconfig_jsc_dateformat %]",
+      align : "BL",
+      button : "todate_trigger"
+    });
+     //-->
+  </script>
+
+</body>
+</html>
diff --git a/templates/webpages/wh/journal_filter_master.html b/templates/webpages/wh/journal_filter_master.html
new file mode 100644 (file)
index 0000000..ea3c892
--- /dev/null
@@ -0,0 +1,217 @@
+[% USE HTML %][% USE JavaScript %]<body onload="on_load();">
+
+ <script type="text/javascript">
+   <!--
+      warehouses = new Array();
+      warehouses[0] = new Array();
+      warehouses[0]['id'] = "0";
+      warehouses[0]['bins'] = new Array();
+      warehouses[0]['bins'][0] = new Array();
+      warehouses[0]['bins'][0]['description'] = "---";
+      warehouses[0]['bins'][0]['id'] = "";
+      [%- USE WAREHOUSES_it = Iterator(WAREHOUSES) %][%- FOREACH warehouse = WAREHOUSES_it %]
+      warehouses[[% WAREHOUSES_it.count %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['id'] = [% warehouse.id %];
+      warehouses[[% WAREHOUSES_it.count %]]['bins'] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0]['description'] = "---";
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0]['id'] = "";
+      [% USE BINS_it = Iterator(warehouse.BINS) %][% FOREACH bin = BINS_it %]
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]]['description'] = "[% JavaScript.escape(bin.description) %]";
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]]['id'] = [% bin.id %];
+      [% END %]
+      [% END %]
+
+      function warehouse_selected(warehouse_id, bin_id) {
+        var control = document.getElementById("bin_id");
+
+        for (var i = control.options.length - 1; i >= 0; i--) {
+          control.options[i] = null;
+        }
+
+        var warehouse_index = 0;
+
+        for (i = 0; i < warehouses.length; i++)
+          if (warehouses[i]['id'] == warehouse_id) {
+            warehouse_index = i;
+            break;
+          }
+
+        var warehouse = warehouses[warehouse_index];
+        var bin_index = 0;
+
+        for (i = 0; i < warehouse['bins'].length; i++)
+          if (warehouse['bins'][i]['id'] == bin_id) {
+            bin_index = i;
+            break;
+          }
+
+        for (i = 0; i < warehouse['bins'].length; i++) {
+          control.options[i] = new Option(warehouse['bins'][i]['description'], warehouse['bins'][i]['id']);
+        }
+
+
+        control.options[bin_index].selected = true;
+      }
+
+      function on_load() {
+        warehouse_selected(0, 0);
+        document.Form.partnumber.focus();
+      }
+     -->
+ </script>
+
+ <div class="listtop"><translate>Report about wareouse transactions</translate></div>
+
+ <form method="post" name="Form" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="generate_journal">
+
+  <p>
+   <table>
+    <tr>
+     <th class="listheading" align="left" valign="top" colspan="6" nowrap><translate>Filter</translate></th>
+    </tr>
+
+    <tr>
+     <td>
+      <table>
+       <tr>
+        <th align="right" nowrap><translate>Warehouse</translate>:</th>
+        <td>
+         <select name="warehouse_id" id="warehouse_id" onchange="warehouse_selected(warehouses[this.selectedIndex]['id'], 0)">
+          <option value="">---</option>
+          [%- FOREACH warehouse = WAREHOUSES %]
+          <option value="[% HTML.escape(warehouse.id) %]">[% warehouse.description %]</option>
+          [%- END %]
+         </select>
+        </td>
+       </tr>
+       <tr>
+        <th align="right" nowrap><translate>Bin</translate>:</th>
+        <td><select name="bin_id" id="bin_id"></select></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap><translate>Part Number</translate>:</th>
+        <td><input name="partnumber" id="partnumber" size=20></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap><translate>Part Description</translate>:</th>
+        <td><input name="description" size=40></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap><translate>Charge Number</translate>:</th>
+        <td><input name="chargenumber" size=40></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap><translate>Transfer Quantity</translate>:</th>
+        <td>
+         <select name="qty_op">
+          <option value="dontcare">---</option>
+          <option value="atleast"><translate>At least</translate></option>
+          <option value="atmost"><translate>At most</translate></option>
+          <option value="exact"><translate>Exact</translate></option>
+         </select>
+         <input name="qty">
+         <select name="qty_unit">
+          [%- FOREACH unit = UNITS %]<option>[% unit.name %]</option>[% END %]
+         </select>
+        </td>
+       </tr>
+       <tr>
+        <th align="right" nowrap><translate>From Date</translate></th>
+        <td>
+         <input name="fromdate" id="fromdate" size="11" title="[% myconfig_dateformat %]">
+         <input type="button" name="b_fromdate" id="fromdate_trigger" value="?">
+        </td>
+       </tr>
+       <tr>
+        <th align="right"><translate>To Date</translate></th>
+        <td>
+         <input name="todate" id="todate" size="11" title="[% myconfig_dateformat %]">
+         <input type="button" name="b_todate" id="todate_trigger" value="?">
+        </td>
+       </tr>
+      </table>
+     </td>
+    </tr>
+
+    <tr height="5"><td>&nbsp;</td></tr>
+
+    <tr>
+     <th class="listheading" align="left" valign="top" colspan="6" nowrap><translate>Include in Report</translate></th>
+    </tr>
+
+    <tr>
+     <td>
+      <table>
+       <tr>
+        <td><input name="l_partdescription" id="l_partdescription" class="checkbox" type="hidden" value="Y" checked></td>
+        <td nowrap><label for="l_partdescription"><translate>Part Description</translate></label></td>
+        <td><input name="l_qty" id="l_qty" class="checkbox" type="hidden" value="Y" checked></td>
+        <td nowrap><label for="l_qty"><translate>Quantity</translate></label></td>
+       </tr>
+       <tr>
+        <td align="right"><input name="l_date" id="l_date" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_date"><translate>Date</translate></label></td>
+        <td align="right"><input name="l_partnumber" id="l_partnumber" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_partnumber"><translate>Part Number</translate></label></td>
+        <td align="right"><input name="l_chargenumber" id="l_chargenumber" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_chargenumber"><translate>Charge Number</translate></label></td>
+       </tr>
+       <tr>
+        <td align="right"><input name="l_trans_id" id="l_trans_id" class="checkbox" type="checkbox" value="Y"></td>
+        <td nowrap><label for="l_trans_id"><translate>Trans Id</translate></label></td>
+        <td align="right"><input name="l_trans_type" id="l_trans_type" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_trans_type"><translate>Trans Type</translate></label></td>
+        <td align="right"><input name="l_comment" id="l_comment" class="checkbox" type="checkbox" value="Y"></td>
+        <td nowrap><label for="l_comment"><translate>Comment</translate></label></td>
+       </tr>
+       <tr>
+        <td align="right"><input name="l_warehouse_from" id="l_warehouse_from" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_warehouse_from"><translate>Warehouse From</translate></label></td>
+        <td align="right"><input name="l_bin_from" id="l_bin_from" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_bin_from"><translate>Bin From</translate></label></td>
+        <td align="right"><input name="l_warehouse_to" id="l_warehouse_to" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_warehouse_to"><translate>Warehouse To</translate></label></td>
+        <td align="right"><input name="l_bin_to" id="l_bin_to" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_bin_to"><translate>Bin To</translate></label></td>
+       </tr>
+       <tr>
+        <td align="right"><input name="l_employee" id="l_employee" class="checkbox" type="checkbox" value="Y"></td>
+        <td nowrap><label for="l_employee"><translate>Employee</translate></label></td>
+        <td align="right"><input name="l_projectnumber" id="l_projectnumber" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_projectnumber"><translate>Project Number</translate></label></td>
+       </tr>
+      </table>
+     </td>
+    </tr>
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="<translate>Continue</translate>">
+  </p>
+ </form>
+
+  <script type="text/javascript">
+    <!--
+    Calendar.setup( {
+      inputField : "fromdate",
+      ifFormat :"[% myconfig_jsc_dateformat %]",
+      align : "BR",
+      button : "fromdate_trigger"
+    });
+
+     Calendar.setup( {
+      inputField : "todate",
+      ifFormat :"[% myconfig_jsc_dateformat %]",
+      align : "BL",
+      button : "todate_trigger"
+    });
+     //-->
+  </script>
+
+</body>
+</html>
diff --git a/templates/webpages/wh/removal_parts_selection_de.html b/templates/webpages/wh/removal_parts_selection_de.html
new file mode 100644 (file)
index 0000000..90c63c4
--- /dev/null
@@ -0,0 +1,76 @@
+[% USE HTML %][% USE JavaScript %]<body>
+
+ <form method="post" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="remove_parts">
+  <input type="hidden" name="warehouse_id" value="[% HTML.escape(warehouse_id) %]">
+
+  <div class="listtop">[% title %]</div>
+
+  <p>Entnahme aus Lager: [% warehouse_description %]</p>
+
+  <p>
+   <table>
+    <tr>
+     <td>Grund der Entnahme ausw&auml;hlen:</td>
+     <td>
+      <select name="transfer_type_id">
+       [%- FOREACH type = TRANSFER_TYPES %]<option value="[% HTML.escape(type.id) %]">[% HTML.escape(type.description) %]</option>[% END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <td>Optionaler Kommentar:</td>
+     <td><input name="comment" size="20"></td>
+    </tr>
+   </table>
+  </p>
+
+  <p>
+   <table>
+    <tr>
+     <th class="listheading">Lagerplatz</th>
+     <th class="listheading">Artikelnummer</th>
+     <th class="listheading">Artikelbeschreibung</th>
+     <th class="listheading">Chargennummer</th>
+     <th class="listheading">Lagerbestand</th>
+     <th class="listheading">Entnahmemenge</th>
+    </tr>
+
+    [% FOREACH row = CONTENTS %]
+    <tr class="listrow[% loop.count % 2 %]">
+     <input type="hidden" name="src_bin_id_[% loop.count %]" value="[% HTML.escape(row.binid) %]">
+     <input type="hidden" name="parts_id_[% loop.count %]" value="[% HTML.escape(row.parts_id) %]">
+     <input type="hidden" name="partnumber_[% loop.count %]" value="[% HTML.escape(row.partnumber) %]">
+     <input type="hidden" name="partdescription_[% loop.count %]" value="[% HTML.escape(row.partdescription) %]">
+     <input type="hidden" name="chargenumber_[% loop.count %]" value="[% HTML.escape(row.chargenumber) %]">
+     <td>[% HTML.escape(row.bindescription) %]</td>
+     <td>[% HTML.escape(row.partnumber) %]</td>
+     <td>[% HTML.escape(row.partdescription) %]</td>
+     <td>[% HTML.escape(row.chargenumber) %]</td>
+     <td>[% HTML.escape(row.qty) %]</td>
+     <td>
+      <input name="qty_[% loop.count %]">
+      <select name="unit_[% loop.count %]">
+       [% FOREACH unit = row.UNITS %]<option[% IF unit.selected %] selected[% END %]>[% HTML.escape(unit.name) %]</option>[% END %]
+      </select>
+     </td>
+    </tr>
+
+    [% END %]
+
+    <input type="hidden" name="rowcount" value="[% CONTENTS.size %]">
+
+    <tr><td colspan="7"><hr size="3" noshade></td></tr>
+
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="Weiter">
+  </p>
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/wh/removal_parts_selection_master.html b/templates/webpages/wh/removal_parts_selection_master.html
new file mode 100644 (file)
index 0000000..4136854
--- /dev/null
@@ -0,0 +1,76 @@
+[% USE HTML %][% USE JavaScript %]<body>
+
+ <form method="post" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="remove_parts">
+  <input type="hidden" name="warehouse_id" value="[% HTML.escape(warehouse_id) %]">
+
+  <div class="listtop">[% title %]</div>
+
+  <p><translate>Removal from warehouse</translate>: [% warehouse_description %]</p>
+
+  <p>
+   <table>
+    <tr>
+     <td><translate>Select type of removal</translate>:</td>
+     <td>
+      <select name="transfer_type_id">
+       [%- FOREACH type = TRANSFER_TYPES %]<option value="[% HTML.escape(type.id) %]">[% HTML.escape(type.description) %]</option>[% END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <td><translate>Optional comment</translate>:</td>
+     <td><input name="comment" size="20"></td>
+    </tr>
+   </table>
+  </p>
+
+  <p>
+   <table>
+    <tr>
+     <th class="listheading"><translate>Bin</translate></th>
+     <th class="listheading"><translate>Part Number</translate></th>
+     <th class="listheading"><translate>Part Description</translate></th>
+     <th class="listheading"><translate>Charge Number</translate></th>
+     <th class="listheading"><translate>Available qty</translate></th>
+     <th class="listheading"><translate>Removal qty</translate></th>
+    </tr>
+
+    [% FOREACH row = CONTENTS %]
+    <tr class="listrow[% loop.count % 2 %]">
+     <input type="hidden" name="src_bin_id_[% loop.count %]" value="[% HTML.escape(row.binid) %]">
+     <input type="hidden" name="parts_id_[% loop.count %]" value="[% HTML.escape(row.parts_id) %]">
+     <input type="hidden" name="partnumber_[% loop.count %]" value="[% HTML.escape(row.partnumber) %]">
+     <input type="hidden" name="partdescription_[% loop.count %]" value="[% HTML.escape(row.partdescription) %]">
+     <input type="hidden" name="chargenumber_[% loop.count %]" value="[% HTML.escape(row.chargenumber) %]">
+     <td>[% HTML.escape(row.bindescription) %]</td>
+     <td>[% HTML.escape(row.partnumber) %]</td>
+     <td>[% HTML.escape(row.partdescription) %]</td>
+     <td>[% HTML.escape(row.chargenumber) %]</td>
+     <td>[% HTML.escape(row.qty) %]</td>
+     <td>
+      <input name="qty_[% loop.count %]">
+      <select name="unit_[% loop.count %]">
+       [% FOREACH unit = row.UNITS %]<option[% IF unit.selected %] selected[% END %]>[% HTML.escape(unit.name) %]</option>[% END %]
+      </select>
+     </td>
+    </tr>
+
+    [% END %]
+
+    <input type="hidden" name="rowcount" value="[% CONTENTS.size %]">
+
+    <tr><td colspan="7"><hr size="3" noshade></td></tr>
+
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="<translate>Continue</translate>">
+  </p>
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/wh/report_filter_de.html b/templates/webpages/wh/report_filter_de.html
new file mode 100644 (file)
index 0000000..c59a874
--- /dev/null
@@ -0,0 +1,172 @@
+[% USE HTML %][% USE JavaScript %]<body onload="on_load();">
+
+ <script type="text/javascript">
+   <!--
+      warehouses = new Array();
+      warehouses[0] = new Array();
+      warehouses[0]['id'] = "0";
+      warehouses[0]['bins'] = new Array();
+      warehouses[0]['bins'][0] = new Array();
+      warehouses[0]['bins'][0]['description'] = "---";
+      warehouses[0]['bins'][0]['id'] = "";
+      [%- USE WAREHOUSES_it = Iterator(WAREHOUSES) %][%- FOREACH warehouse = WAREHOUSES_it %]
+      warehouses[[% WAREHOUSES_it.count %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['id'] = [% warehouse.id %];
+      warehouses[[% WAREHOUSES_it.count %]]['bins'] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0]['description'] = "---";
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0]['id'] = "";
+      [% USE BINS_it = Iterator(warehouse.BINS) %][% FOREACH bin = BINS_it %]
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]]['description'] = "[% JavaScript.escape(bin.description) %]";
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]]['id'] = [% bin.id %];
+      [% END %]
+      [% END %]
+
+      function warehouse_selected(warehouse_id, bin_id) {
+        var control = document.getElementById("bin_id");
+
+        for (var i = control.options.length - 1; i >= 0; i--) {
+          control.options[i] = null;
+        }
+
+        var warehouse_index = 0;
+
+        for (i = 0; i < warehouses.length; i++)
+          if (warehouses[i]['id'] == warehouse_id) {
+            warehouse_index = i;
+            break;
+          }
+
+        var warehouse = warehouses[warehouse_index];
+        var bin_index = 0;
+
+        for (i = 0; i < warehouse['bins'].length; i++)
+          if (warehouse['bins'][i]['id'] == bin_id) {
+            bin_index = i;
+            break;
+          }
+
+        for (i = 0; i < warehouse['bins'].length; i++) {
+          control.options[i] = new Option(warehouse['bins'][i]['description'], warehouse['bins'][i]['id']);
+        }
+
+
+        control.options[bin_index].selected = true;
+      }
+
+      function on_load() {
+        warehouse_selected(0, 0);
+        document.Form.partnumber.focus();
+      }
+     -->
+ </script>
+
+ <div class="listtop">Bericht &uuml;ber eingelagerte Waren</div>
+
+ <form method="post" name="Form" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="generate_report">
+
+  <p>
+   <table>
+    <tr>
+     <th class="listheading" align="left" valign="top" colspan="6" nowrap>Filter</th>
+    </tr>
+
+    <tr>
+     <td>
+      <table>
+       <tr>
+        <th align="right" nowrap>Lager:</th>
+        <td>
+         <select name="warehouse_id" id="warehouse_id" onchange="warehouse_selected(warehouses[this.selectedIndex]['id'], 0)">
+          <option value="">---</option>
+          [%- FOREACH warehouse = WAREHOUSES %]
+          <option value="[% HTML.escape(warehouse.id) %]">[% warehouse.description %]</option>
+          [%- END %]
+         </select>
+        </td>
+       </tr>
+       <tr>
+        <th align="right" nowrap>Lagerplatz:</th>
+        <td><select name="bin_id" id="bin_id"></select></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap>Artikelnummer:</th>
+        <td><input name="partnumber" size=20></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap>Artikelbeschreibung:</th>
+        <td><input name="description" size=40></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap>Chargennummer:</th>
+        <td><input name="chargenumber" size=40></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap>Lagerbestand:</th>
+        <td>
+         <select name="qty_op">
+          <option value="dontcare">---</option>
+          <option value="atleast">Mindestens</option>
+          <option value="atmost">H&ouml;chstens</option>
+          <option value="exact">Genau</option>
+         </select>
+         <input name="qty">
+         <select name="qty_unit">
+          [%- FOREACH unit = UNITS %]<option>[% unit.name %]</option>[% END %]
+         </select>
+        </td>
+       </tr>
+      </table>
+     </td>
+    </tr>
+
+    <tr height="5"><td>&nbsp;</td></tr>
+
+    <tr>
+     <th class="listheading" align="left" valign="top" colspan="6" nowrap>In Bericht aufnehmen</th>
+    </tr>
+
+    <tr>
+     <td>
+      <input name="l_partdescription" type="hidden" value="Y">
+      <input name="l_qty" type="hidden" value="Y">
+
+      <table>
+       <tr>
+        <td align="right"><input name="l_warehousedescription" id="l_warehousedescription" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_warehousedescription">Lager</label></td>
+        <td align="right"><input name="l_bindescription" id="l_bindescription" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_bindescription">Lagerplatz</label></td>
+       </tr>
+
+       <tr>
+        <td align="right"><input name="l_partnumber" id="l_partnumber" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_partnumber">Artikelnummer</label></td>
+        <td align="right"><input name="l_chargenumber" id="l_chargenumber" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_chargenumber">Chargennummer</label></td>
+       </tr>
+
+       <tr><td colspan="4"><hr noshade height="1"></td></tr>
+
+       <tr>
+        <td align="right"><input name="subtotal" id="subtotal" class="checkbox" type="checkbox" value="Y"></td>
+        <td nowrap><label for="subtotal">Zwischensumme</label></td>
+        <td align="right"><input name="include_empty_bins" id="include_empty_bins" class="checkbox" type="checkbox" value="Y"></td>
+        <td nowrap><label for="include_empty_bins">Leere Lagerpl&auml;tze anzeigen</label></td>
+       </tr>
+      </table>
+     </td>
+    </tr>
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="Weiter">
+  </p>
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/wh/report_filter_master.html b/templates/webpages/wh/report_filter_master.html
new file mode 100644 (file)
index 0000000..860b4e1
--- /dev/null
@@ -0,0 +1,172 @@
+[% USE HTML %][% USE JavaScript %]<body onload="on_load();">
+
+ <script type="text/javascript">
+   <!--
+      warehouses = new Array();
+      warehouses[0] = new Array();
+      warehouses[0]['id'] = "0";
+      warehouses[0]['bins'] = new Array();
+      warehouses[0]['bins'][0] = new Array();
+      warehouses[0]['bins'][0]['description'] = "---";
+      warehouses[0]['bins'][0]['id'] = "";
+      [%- USE WAREHOUSES_it = Iterator(WAREHOUSES) %][%- FOREACH warehouse = WAREHOUSES_it %]
+      warehouses[[% WAREHOUSES_it.count %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['id'] = [% warehouse.id %];
+      warehouses[[% WAREHOUSES_it.count %]]['bins'] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0]['description'] = "---";
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][0]['id'] = "";
+      [% USE BINS_it = Iterator(warehouse.BINS) %][% FOREACH bin = BINS_it %]
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]]['description'] = "[% JavaScript.escape(bin.description) %]";
+      warehouses[[% WAREHOUSES_it.count %]]['bins'][[% BINS_it.count %]]['id'] = [% bin.id %];
+      [% END %]
+      [% END %]
+
+      function warehouse_selected(warehouse_id, bin_id) {
+        var control = document.getElementById("bin_id");
+
+        for (var i = control.options.length - 1; i >= 0; i--) {
+          control.options[i] = null;
+        }
+
+        var warehouse_index = 0;
+
+        for (i = 0; i < warehouses.length; i++)
+          if (warehouses[i]['id'] == warehouse_id) {
+            warehouse_index = i;
+            break;
+          }
+
+        var warehouse = warehouses[warehouse_index];
+        var bin_index = 0;
+
+        for (i = 0; i < warehouse['bins'].length; i++)
+          if (warehouse['bins'][i]['id'] == bin_id) {
+            bin_index = i;
+            break;
+          }
+
+        for (i = 0; i < warehouse['bins'].length; i++) {
+          control.options[i] = new Option(warehouse['bins'][i]['description'], warehouse['bins'][i]['id']);
+        }
+
+
+        control.options[bin_index].selected = true;
+      }
+
+      function on_load() {
+        warehouse_selected(0, 0);
+        document.Form.partnumber.focus();
+      }
+     -->
+ </script>
+
+ <div class="listtop"><translate>Report about wareouse contents</translate></div>
+
+ <form method="post" name="Form" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="generate_report">
+
+  <p>
+   <table>
+    <tr>
+     <th class="listheading" align="left" valign="top" colspan="6" nowrap><translate>Filter</translate></th>
+    </tr>
+
+    <tr>
+     <td>
+      <table>
+       <tr>
+        <th align="right" nowrap><translate>Warehouse</translate>:</th>
+        <td>
+         <select name="warehouse_id" id="warehouse_id" onchange="warehouse_selected(warehouses[this.selectedIndex]['id'], 0)">
+          <option value="">---</option>
+          [%- FOREACH warehouse = WAREHOUSES %]
+          <option value="[% HTML.escape(warehouse.id) %]">[% warehouse.description %]</option>
+          [%- END %]
+         </select>
+        </td>
+       </tr>
+       <tr>
+        <th align="right" nowrap><translate>Bin</translate>:</th>
+        <td><select name="bin_id" id="bin_id"></select></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap><translate>Part Number</translate>:</th>
+        <td><input name="partnumber" size=20></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap><translate>Part Description</translate>:</th>
+        <td><input name="description" size=40></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap><translate>Charge Number</translate>:</th>
+        <td><input name="chargenumber" size=40></td>
+       </tr>
+       <tr>
+        <th align="right" nowrap><translate>Qty in stock</translate>:</th>
+        <td>
+         <select name="qty_op">
+          <option value="dontcare">---</option>
+          <option value="atleast"><translate>At least</translate></option>
+          <option value="atmost"><translate>At most</translate></option>
+          <option value="exact"><translate>Exact</translate></option>
+         </select>
+         <input name="qty">
+         <select name="qty_unit">
+          [%- FOREACH unit = UNITS %]<option>[% unit.name %]</option>[% END %]
+         </select>
+        </td>
+       </tr>
+      </table>
+     </td>
+    </tr>
+
+    <tr height="5"><td>&nbsp;</td></tr>
+
+    <tr>
+     <th class="listheading" align="left" valign="top" colspan="6" nowrap><translate>Include in Report</translate></th>
+    </tr>
+
+    <tr>
+     <td>
+      <input name="l_partdescription" type="hidden" value="Y">
+      <input name="l_qty" type="hidden" value="Y">
+
+      <table>
+       <tr>
+        <td align="right"><input name="l_warehousedescription" id="l_warehousedescription" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_warehousedescription"><translate>Warehouse</translate></label></td>
+        <td align="right"><input name="l_bindescription" id="l_bindescription" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_bindescription"><translate>Bin</translate></label></td>
+       </tr>
+
+       <tr>
+        <td align="right"><input name="l_partnumber" id="l_partnumber" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_partnumber"><translate>Part Number</translate></label></td>
+        <td align="right"><input name="l_chargenumber" id="l_chargenumber" class="checkbox" type="checkbox" value="Y" checked></td>
+        <td nowrap><label for="l_chargenumber"><translate>Charge Number</translate></label></td>
+       </tr>
+
+       <tr><td colspan="4"><hr noshade height="1"></td></tr>
+
+       <tr>
+        <td align="right"><input name="subtotal" id="subtotal" class="checkbox" type="checkbox" value="Y"></td>
+        <td nowrap><label for="subtotal"><translate>Subtotal</translate></label></td>
+        <td align="right"><input name="include_empty_bins" id="include_empty_bins" class="checkbox" type="checkbox" value="Y"></td>
+        <td nowrap><label for="include_empty_bins"><translate>Include empty bins</translate></label></td>
+       </tr>
+      </table>
+     </td>
+    </tr>
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="<translate>Continue</translate>">
+  </p>
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/wh/transfer_parts_selection_de.html b/templates/webpages/wh/transfer_parts_selection_de.html
new file mode 100644 (file)
index 0000000..45ae8c7
--- /dev/null
@@ -0,0 +1,116 @@
+[% USE HTML %][% USE JavaScript %]<body onload="on_load();">
+
+ <script type="text/javascript">
+  <!--
+      warehouses = new Array();
+      [% USE WAREHOUSES_it = Iterator(WAREHOUSES) %][% FOREACH wh = WAREHOUSES_it %]
+      warehouses[[% WAREHOUSES_it.count - 1 %]] = new Array();
+      [% USE BINS_it = Iterator(wh.BINS) %][% FOREACH bin = BINS_it %]warehouses[[% WAREHOUSES_it.count - 1 %]][[% BINS_it.count - 1 %]] = ["[% JavaScript.escape(bin.description) %]", "[% JavaScript.escape(bin.id) %]"];
+      [% END %]
+      [% END %]
+
+      function warehouse_selected(row, index) {
+        var cname = "dst_bin_id_" + row;
+        var control = document.getElementById(cname);
+
+        for (var i = control.options.length - 1; i >= 0; i--) {
+          control.options[i] = null;
+        }
+
+        for (i = 0; i < warehouses[index].length; i++) {
+          control.options[i] = new Option(warehouses[index][i][0], warehouses[index][i][1]);
+        }
+
+        control.options[0].selected = true;
+      }
+
+      function on_load() {
+        [% FOREACH row = CONTENTS %]
+        warehouse_selected([% loop.count %], [% initial_warehouse_idx %]);
+        [% END %]
+      }
+    -->
+ </script>
+
+ <form method="post" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="transfer_parts">
+  <input type="hidden" name="warehouse_id" value="[% HTML.escape(warehouse_id) %]">
+
+  <div class="listtop">[% title %]</div>
+
+  <p>Quelllager: [% warehouse_description %]</p>
+
+  <p>
+   <table>
+    <tr>
+     <td>Grund der Umlagerung ausw&auml;hlen:</td>
+     <td>
+      <select name="transfer_type_id">
+       [%- FOREACH type = TRANSFER_TYPES %]<option value="[% HTML.escape(type.id) %]">[% type.description %]</option>[% END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <td>Optionaler Kommentar:</td>
+     <td><input name="comment" size="20"></td>
+    </tr>
+   </table>
+  </p>
+
+  <p>
+   <table>
+    <tr>
+     <th class="listheading">Quelllagerplatz</th>
+     <th class="listheading">Artikelnummer</th>
+     <th class="listheading">Artikelbeschreibung</th>
+     <th class="listheading">Chargennummer</th>
+     <th class="listheading">Lagerbestand</th>
+     <th class="listheading" colspan="2">Umlagermenge</th>
+     <th class="listheading" colspan="2">Ziellager und -lagerplatz</th>
+    </tr>
+
+    [% FOREACH row = CONTENTS %]
+    <tr class="listrow[% loop.count % 2 %]">
+     <input type="hidden" name="src_bin_id_[% loop.count %]" value="[% HTML.escape(row.binid) %]">
+     <input type="hidden" name="parts_id_[% loop.count %]" value="[% HTML.escape(row.parts_id) %]">
+     <input type="hidden" name="partnumber_[% loop.count %]" value="[% HTML.escape(row.partnumber) %]">
+     <input type="hidden" name="partdescription_[% loop.count %]" value="[% HTML.escape(row.partdescription) %]">
+     <input type="hidden" name="chargenumber_[% loop.count %]" value="[% HTML.escape(row.chargenumber) %]">
+     <td>[% HTML.escape(row.bindescription) %]</td>
+     <td>[% HTML.escape(row.partnumber) %]</td>
+     <td>[% HTML.escape(row.partdescription) %]</td>
+     <td>[% HTML.escape(row.chargenumber) %]</td>
+     <td>[% HTML.escape(row.qty) %]</td>
+     <td><input name="qty_[% loop.count %]" size="8" style="text-align: right"></td>
+     <td>
+      <select name="unit_[% loop.count %]">
+       [% FOREACH unit = row.UNITS %]<option[% IF unit.selected %] selected[% END %]>[% HTML.escape(unit.name) %]</option>[% END %]
+      </select>
+     </td>
+
+     <td>
+      <select name="dst_warehouse_id_[% loop.count %]" onchange="warehouse_selected([% loop.count %], this.selectedIndex)">
+       [% FOREACH wh = WAREHOUSES %]<option value="[% HTML.escape(wh.id) %]"[% IF wh.selected %] selected[% END %]>[% HTML.escape(wh.description) %]</option>[% END %]
+      </select>
+     </td>
+     <td><select id="dst_bin_id_[% loop.count %]" name="dst_bin_id_[% loop.count %]"></select></td>
+    </tr>
+
+    [% END %]
+
+    <input type="hidden" name="rowcount" value="[% CONTENTS.size %]">
+
+   </table>
+  </p>
+
+  <hr size="3" noshade>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="Weiter">
+  </p>
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/wh/transfer_parts_selection_master.html b/templates/webpages/wh/transfer_parts_selection_master.html
new file mode 100644 (file)
index 0000000..a8da1a2
--- /dev/null
@@ -0,0 +1,116 @@
+[% USE HTML %][% USE JavaScript %]<body onload="on_load();">
+
+ <script type="text/javascript">
+  <!--
+      warehouses = new Array();
+      [% USE WAREHOUSES_it = Iterator(WAREHOUSES) %][% FOREACH wh = WAREHOUSES_it %]
+      warehouses[[% WAREHOUSES_it.count - 1 %]] = new Array();
+      [% USE BINS_it = Iterator(wh.BINS) %][% FOREACH bin = BINS_it %]warehouses[[% WAREHOUSES_it.count - 1 %]][[% BINS_it.count - 1 %]] = ["[% JavaScript.escape(bin.description) %]", "[% JavaScript.escape(bin.id) %]"];
+      [% END %]
+      [% END %]
+
+      function warehouse_selected(row, index) {
+        var cname = "dst_bin_id_" + row;
+        var control = document.getElementById(cname);
+
+        for (var i = control.options.length - 1; i >= 0; i--) {
+          control.options[i] = null;
+        }
+
+        for (i = 0; i < warehouses[index].length; i++) {
+          control.options[i] = new Option(warehouses[index][i][0], warehouses[index][i][1]);
+        }
+
+        control.options[0].selected = true;
+      }
+
+      function on_load() {
+        [% FOREACH row = CONTENTS %]
+        warehouse_selected([% loop.count %], [% initial_warehouse_idx %]);
+        [% END %]
+      }
+    -->
+ </script>
+
+ <form method="post" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="transfer_parts">
+  <input type="hidden" name="warehouse_id" value="[% HTML.escape(warehouse_id) %]">
+
+  <div class="listtop">[% title %]</div>
+
+  <p><translate>Transfer from warehouse</translate>: [% warehouse_description %]</p>
+
+  <p>
+   <table>
+    <tr>
+     <td><translate>Select type of transfer</translate>:</td>
+     <td>
+      <select name="transfer_type_id">
+       [%- FOREACH type = TRANSFER_TYPES %]<option value="[% HTML.escape(type.id) %]">[% type.description %]</option>[% END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <td><translate>Optional comment</translate>:</td>
+     <td><input name="comment" size="20"></td>
+    </tr>
+   </table>
+  </p>
+
+  <p>
+   <table>
+    <tr>
+     <th class="listheading"><translate>Source bin</translate></th>
+     <th class="listheading"><translate>Part Number</translate></th>
+     <th class="listheading"><translate>Part Description</translate></th>
+     <th class="listheading"><translate>Charge Number</translate></th>
+     <th class="listheading"><translate>Available qty</translate></th>
+     <th class="listheading" colspan="2"><translate>Transfer qty</translate></th>
+     <th class="listheading" colspan="2"><translate>Destination warehouse and bin</translate></th>
+    </tr>
+
+    [% FOREACH row = CONTENTS %]
+    <tr class="listrow[% loop.count % 2 %]">
+     <input type="hidden" name="src_bin_id_[% loop.count %]" value="[% HTML.escape(row.binid) %]">
+     <input type="hidden" name="parts_id_[% loop.count %]" value="[% HTML.escape(row.parts_id) %]">
+     <input type="hidden" name="partnumber_[% loop.count %]" value="[% HTML.escape(row.partnumber) %]">
+     <input type="hidden" name="partdescription_[% loop.count %]" value="[% HTML.escape(row.partdescription) %]">
+     <input type="hidden" name="chargenumber_[% loop.count %]" value="[% HTML.escape(row.chargenumber) %]">
+     <td>[% HTML.escape(row.bindescription) %]</td>
+     <td>[% HTML.escape(row.partnumber) %]</td>
+     <td>[% HTML.escape(row.partdescription) %]</td>
+     <td>[% HTML.escape(row.chargenumber) %]</td>
+     <td>[% HTML.escape(row.qty) %]</td>
+     <td><input name="qty_[% loop.count %]" size="8" style="text-align: right"></td>
+     <td>
+      <select name="unit_[% loop.count %]">
+       [% FOREACH unit = row.UNITS %]<option[% IF unit.selected %] selected[% END %]>[% HTML.escape(unit.name) %]</option>[% END %]
+      </select>
+     </td>
+
+     <td>
+      <select name="dst_warehouse_id_[% loop.count %]" onchange="warehouse_selected([% loop.count %], this.selectedIndex)">
+       [% FOREACH wh = WAREHOUSES %]<option value="[% HTML.escape(wh.id) %]"[% IF wh.selected %] selected[% END %]>[% HTML.escape(wh.description) %]</option>[% END %]
+      </select>
+     </td>
+     <td><select id="dst_bin_id_[% loop.count %]" name="dst_bin_id_[% loop.count %]"></select></td>
+    </tr>
+
+    [% END %]
+
+    <input type="hidden" name="rowcount" value="[% CONTENTS.size %]">
+
+   </table>
+  </p>
+
+  <hr size="3" noshade>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="<translate>Continue</translate>">
+  </p>
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/wh/warehouse_selection_de.html b/templates/webpages/wh/warehouse_selection_de.html
new file mode 100644 (file)
index 0000000..9d1e414
--- /dev/null
@@ -0,0 +1,127 @@
+[% USE HTML %][% USE JavaScript %]<body onload="on_load();">
+
+ <script type="text/javascript" src="js/common.js"></script>
+ <script type="text/javascript" src="js/part_selection.js"></script>
+ <script type="text/javascript">
+   <!--
+      warehouses = new Array();
+      [%- USE WAREHOUSES_it = Iterator(WAREHOUSES) %][%- FOREACH warehouse = WAREHOUSES_it %]
+      warehouses[[% WAREHOUSES_it.count - 1 %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['id'] = [% warehouse.id %];
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][0] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][0]['description'] = "---";
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][0]['id'] = "";
+      [% USE BINS_it = Iterator(warehouse.BINS) %][% FOREACH bin = BINS_it %]
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][[% BINS_it.count %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][[% BINS_it.count %]]['description'] = "[% JavaScript.escape(bin.description) %]";
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][[% BINS_it.count %]]['id'] = [% bin.id %];
+      [% END %]
+      [% END %]
+
+      function warehouse_selected(warehouse_id, bin_id) {
+        var control = document.getElementById("bin_id");
+
+        for (var i = control.options.length - 1; i >= 0; i--) {
+          control.options[i] = null;
+        }
+
+        var warehouse_index = 0;
+
+        for (i = 0; i < warehouses.length; i++)
+          if (warehouses[i]['id'] == warehouse_id) {
+            warehouse_index = i;
+            break;
+          }
+
+        var warehouse = warehouses[warehouse_index];
+        var bin_index = 0;
+
+        for (i = 0; i < warehouse['bins'].length; i++)
+          if (warehouse['bins'][i]['id'] == bin_id) {
+            bin_index = i;
+            break;
+          }
+
+        for (i = 0; i < warehouse['bins'].length; i++) {
+          control.options[i] = new Option(warehouse['bins'][i]['description'], warehouse['bins'][i]['id']);
+        }
+
+
+        control.options[bin_index].selected = true;
+      }
+
+      function on_load() {
+        warehouse_selected(0, 0);
+        document.Form.partnumber.focus();
+      }
+     -->
+ </script>
+
+ <form name="Form" method="post" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="[% HTML.escape(nextsub) %]">
+
+  [% IF saved_message %]
+  <p>[% saved_message %]</p>
+  [% END %]
+
+  <div class="listtop">[% title %]</div>
+
+  <p>
+   Wenn Sie f&uuml;r die Artikelnummer und / oder die Beschreibung etwas eingeben, so werden nur die Lagerpl&auml;tze angezeigt, in denen Waren eingelagert sind, die Ihre Suchbegriffe enthalten.
+  </p>
+
+  <p>
+   <table>
+    <tr>
+     <th align="right" nowrap>Quelllager:</th>
+     <td>
+      <select name="warehouse_id" id="warehouse_id" onchange="warehouse_selected(warehouses[this.selectedIndex]['id'], 0)">
+       [%- FOREACH warehouse = WAREHOUSES %]
+       <option value="[% HTML.escape(warehouse.id) %]">[% warehouse.description %]</option>
+       [%- END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap>Lagerplatz:</th>
+     <td><select id="bin_id" name="bin_id"></select></td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap>Artikelauswahl eingrenzen:</th>
+     <td></td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap>Artikelnummer</th>
+     <td>
+      <input type="hidden" name="parts_id" id="parts_id">
+      <input name="partnumber" id="partnumber" size="30">
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap>Artikelbeschreibung</th>
+     <td>
+      <input name="description" size="30">
+      <input type="button" onclick="part_selection_window('partnumber', 'description', 'parts_id', 0, 'Form', 'no_services:no_assemblies')" value="?">
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap>Chargennummer</th>
+     <td><input name="chargenumber" size="30"></td>
+    </tr>
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="Weiter">
+  </p>
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/wh/warehouse_selection_master.html b/templates/webpages/wh/warehouse_selection_master.html
new file mode 100644 (file)
index 0000000..465d806
--- /dev/null
@@ -0,0 +1,130 @@
+[% USE HTML %][% USE JavaScript %]<body onload="on_load();">
+
+ <script type="text/javascript" src="js/common.js"></script>
+ <script type="text/javascript" src="js/part_selection.js"></script>
+ <script type="text/javascript">
+   <!--
+      warehouses = new Array();
+      [%- USE WAREHOUSES_it = Iterator(WAREHOUSES) %][%- FOREACH warehouse = WAREHOUSES_it %]
+      warehouses[[% WAREHOUSES_it.count - 1 %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['id'] = [% warehouse.id %];
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][0] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][0]['description'] = "---";
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][0]['id'] = "";
+      [% USE BINS_it = Iterator(warehouse.BINS) %][% FOREACH bin = BINS_it %]
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][[% BINS_it.count %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][[% BINS_it.count %]]['description'] = "[% JavaScript.escape(bin.description) %]";
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'][[% BINS_it.count %]]['id'] = [% bin.id %];
+      [% END %]
+      [% END %]
+
+      function warehouse_selected(warehouse_id, bin_id) {
+        var control = document.getElementById("bin_id");
+
+        for (var i = control.options.length - 1; i >= 0; i--) {
+          control.options[i] = null;
+        }
+
+        var warehouse_index = 0;
+
+        for (i = 0; i < warehouses.length; i++)
+          if (warehouses[i]['id'] == warehouse_id) {
+            warehouse_index = i;
+            break;
+          }
+
+        var warehouse = warehouses[warehouse_index];
+        var bin_index = 0;
+
+        for (i = 0; i < warehouse['bins'].length; i++)
+          if (warehouse['bins'][i]['id'] == bin_id) {
+            bin_index = i;
+            break;
+          }
+
+        for (i = 0; i < warehouse['bins'].length; i++) {
+          control.options[i] = new Option(warehouse['bins'][i]['description'], warehouse['bins'][i]['id']);
+        }
+
+
+        control.options[bin_index].selected = true;
+      }
+
+      function on_load() {
+        warehouse_selected(0, 0);
+        document.Form.partnumber.focus();
+      }
+     -->
+ </script>
+
+ <form name="Form" method="post" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="[% HTML.escape(nextsub) %]">
+
+  [% IF saved_message %]
+  <p>[% saved_message %]</p>
+  [% END %]
+
+  <div class="listtop">[% title %]</div>
+
+  <p>
+   <translate>If you enter values for the part number and / or part
+    description then only those bins containing parts whose part
+    number or part description match your input will be
+    shown.</translate>
+  </p>
+
+  <p>
+   <table>
+    <tr>
+     <th align="right" nowrap><translate>Transfer from warehouse</translate>:</th>
+     <td>
+      <select name="warehouse_id" id="warehouse_id" onchange="warehouse_selected(warehouses[this.selectedIndex]['id'], 0)">
+       [%- FOREACH warehouse = WAREHOUSES %]
+       <option value="[% HTML.escape(warehouse.id) %]">[% warehouse.description %]</option>
+       [%- END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap><translate>Bin</translate>:</th>
+     <td><select id="bin_id" name="bin_id"></select></td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap><translate>Limit part selection</translate>:</th>
+     <td></td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap><translate>Part Number</translate></th>
+     <td>
+      <input type="hidden" name="parts_id" id="parts_id">
+      <input name="partnumber" id="partnumber" size="30">
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap><translate>Part Description</translate></th>
+     <td>
+      <input name="description" size="30">
+      <input type="button" onclick="part_selection_window('partnumber', 'description', 'parts_id', 0, 'Form', 'no_services:no_assemblies')" value="?">
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap><translate>Charge number</translate></th>
+     <td><input name="chargenumber" size="30"></td>
+    </tr>
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="<translate>Continue</translate>">
+  </p>
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/wh/warehouse_selection_stock_de.html b/templates/webpages/wh/warehouse_selection_stock_de.html
new file mode 100644 (file)
index 0000000..ace8564
--- /dev/null
@@ -0,0 +1,135 @@
+[% USE HTML %][% USE JavaScript %][% USE LxERP %]<body onload="on_load(); [% onload %]">
+
+ <script type="text/javascript" src="js/common.js"></script>
+ <script type="text/javascript" src="js/part_selection.js"></script>
+ <script type="text/javascript">
+  <!--
+      warehouses = new Array();
+      [%- USE WAREHOUSES_it = Iterator(WAREHOUSES) %][%- FOREACH warehouse = WAREHOUSES_it %]
+      warehouses[[% WAREHOUSES_it.count - 1 %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['id'] = [% warehouse.id %];
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'] = new Array();
+      [% USE BINS_it = Iterator(warehouse.BINS) %][% FOREACH bin = BINS_it %]
+      warehouses[[% WAREHOUSES_it.count - 1%]]['bins'][[% BINS_it.count - 1 %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1%]]['bins'][[% BINS_it.count - 1 %]]['description'] = "[% JavaScript.escape(bin.description) %]";
+      warehouses[[% WAREHOUSES_it.count - 1%]]['bins'][[% BINS_it.count - 1 %]]['id'] = [% bin.id %];
+      [% END %]
+      [% END %]
+
+      function warehouse_selected(warehouse_id, bin_id) {
+        var control = document.getElementById("bin_id");
+
+        for (var i = control.options.length - 1; i >= 0; i--) {
+          control.options[i] = null;
+        }
+
+        var warehouse_index = 0;
+
+        for (i = 0; i < warehouses.length; i++)
+          if (warehouses[i]['id'] == warehouse_id) {
+            warehouse_index = i;
+            break;
+          }
+
+        var warehouse = warehouses[warehouse_index];
+        var bin_index = 0;
+
+        for (i = 0; i < warehouse['bins'].length; i++)
+          if (warehouse['bins'][i]['id'] == bin_id) {
+            bin_index = i;
+            break;
+          }
+
+        for (i = 0; i < warehouse['bins'].length; i++) {
+          control.options[i] = new Option(warehouse['bins'][i]['description'], warehouse['bins'][i]['id']);
+        }
+
+
+        control.options[bin_index].selected = true;
+      }
+
+      function on_load() {
+        warehouse_selected([% warehouse_id %], [% bin_id %]);
+      }
+    -->
+ </script>
+
+ <form name="Form" method="post" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="transfer_stock">
+  <input type="hidden" name="update_nextsub" value="transfer_stock_update_part">
+
+  [% IF saved_message %]
+  <p>[% saved_message %]</p>
+  [% END %]
+
+  <div class="listtop">[% title %]</div>
+
+  <p>
+   <table>
+    <tr>
+     <th align="right" nowrap>Ziellager</th>
+     <td>
+      <select name="warehouse_id" onchange="warehouse_selected(warehouses[this.selectedIndex]['id'], 0)">
+       [%- FOREACH warehouse = WAREHOUSES %]
+       <option value="[% HTML.escape(warehouse.id) %]"[% IF warehouse_id == warehouse.id %] selected[% END %]>[% warehouse.description %]</option>
+       [%- END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap>Ziellagerplatz:</th>
+     <td><select id="bin_id" name="bin_id"></select></td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap>Artikelnummer</th>
+     <td>
+      <input type="hidden" name="parts_id" id="parts_id" value="[% HTML.escape(parts_id) %]">
+      <input type="hidden" name="old_partnumber" id="old_partnumber" value="[% HTML.escape(partnumber) %]">
+      <input name="partnumber" size="30" value="[% HTML.escape(partnumber) %]">
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap>Artikelbeschreibung</th>
+     <td>
+      <input name="description" size="30" value="[% HTML.escape(description) %]">
+      <input type="button" onclick="part_selection_window('partnumber', 'description', 'parts_id', 0, 'Form', 'no_services:no_assemblies:stockable')" value="?">
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap>Chargennummer</th>
+     <td><input name="chargenumber" size="30" value="[% HTML.escape(chargenumber) %]"></td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap>Menge</th>
+     <td>
+      <input name="qty" size="10" value="[% HTML.escape(LxERP.format_amount(qty)) %]">
+      <select name="unit">
+       [%- FOREACH unit = UNITS %]<option[% IF unit.selected %] selected[% END %]>[% HTML.escape(unit.name) %]</option>[% END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap>Optionaler Kommentar</th>
+     <td><input name="comment" size="30" value="[% HTML.escape(comment) %]"></td>
+    </tr>
+
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="Erneuern">
+   [%- IF parts_id %]
+   <input type="submit" class="submit" name="action" value="Einlagern">
+   [%- END %]
+  </p>
+ </form>
+
+</body>
+</html>
diff --git a/templates/webpages/wh/warehouse_selection_stock_master.html b/templates/webpages/wh/warehouse_selection_stock_master.html
new file mode 100644 (file)
index 0000000..eac293c
--- /dev/null
@@ -0,0 +1,135 @@
+[% USE HTML %][% USE JavaScript %][% USE LxERP %]<body onload="on_load(); [% onload %]">
+
+ <script type="text/javascript" src="js/common.js"></script>
+ <script type="text/javascript" src="js/part_selection.js"></script>
+ <script type="text/javascript">
+  <!--
+      warehouses = new Array();
+      [%- USE WAREHOUSES_it = Iterator(WAREHOUSES) %][%- FOREACH warehouse = WAREHOUSES_it %]
+      warehouses[[% WAREHOUSES_it.count - 1 %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['id'] = [% warehouse.id %];
+      warehouses[[% WAREHOUSES_it.count - 1 %]]['bins'] = new Array();
+      [% USE BINS_it = Iterator(warehouse.BINS) %][% FOREACH bin = BINS_it %]
+      warehouses[[% WAREHOUSES_it.count - 1%]]['bins'][[% BINS_it.count - 1 %]] = new Array();
+      warehouses[[% WAREHOUSES_it.count - 1%]]['bins'][[% BINS_it.count - 1 %]]['description'] = "[% JavaScript.escape(bin.description) %]";
+      warehouses[[% WAREHOUSES_it.count - 1%]]['bins'][[% BINS_it.count - 1 %]]['id'] = [% bin.id %];
+      [% END %]
+      [% END %]
+
+      function warehouse_selected(warehouse_id, bin_id) {
+        var control = document.getElementById("bin_id");
+
+        for (var i = control.options.length - 1; i >= 0; i--) {
+          control.options[i] = null;
+        }
+
+        var warehouse_index = 0;
+
+        for (i = 0; i < warehouses.length; i++)
+          if (warehouses[i]['id'] == warehouse_id) {
+            warehouse_index = i;
+            break;
+          }
+
+        var warehouse = warehouses[warehouse_index];
+        var bin_index = 0;
+
+        for (i = 0; i < warehouse['bins'].length; i++)
+          if (warehouse['bins'][i]['id'] == bin_id) {
+            bin_index = i;
+            break;
+          }
+
+        for (i = 0; i < warehouse['bins'].length; i++) {
+          control.options[i] = new Option(warehouse['bins'][i]['description'], warehouse['bins'][i]['id']);
+        }
+
+
+        control.options[bin_index].selected = true;
+      }
+
+      function on_load() {
+        warehouse_selected([% warehouse_id %], [% bin_id %]);
+      }
+    -->
+ </script>
+
+ <form name="Form" method="post" action="wh.pl">
+
+  <input type="hidden" name="nextsub" value="transfer_stock">
+  <input type="hidden" name="update_nextsub" value="transfer_stock_update_part">
+
+  [% IF saved_message %]
+  <p>[% saved_message %]</p>
+  [% END %]
+
+  <div class="listtop">[% title %]</div>
+
+  <p>
+   <table>
+    <tr>
+     <th align="right" nowrap><translate>Destination warehouse</translate></th>
+     <td>
+      <select name="warehouse_id" onchange="warehouse_selected(warehouses[this.selectedIndex]['id'], 0)">
+       [%- FOREACH warehouse = WAREHOUSES %]
+       <option value="[% HTML.escape(warehouse.id) %]"[% IF warehouse_id == warehouse.id %] selected[% END %]>[% warehouse.description %]</option>
+       [%- END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap><translate>Destination bin</translate>:</th>
+     <td><select id="bin_id" name="bin_id"></select></td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap><translate>Part Number</translate></th>
+     <td>
+      <input type="hidden" name="parts_id" id="parts_id" value="[% HTML.escape(parts_id) %]">
+      <input type="hidden" name="old_partnumber" id="old_partnumber" value="[% HTML.escape(partnumber) %]">
+      <input name="partnumber" size="30" value="[% HTML.escape(partnumber) %]">
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap><translate>Part Description</translate></th>
+     <td>
+      <input name="description" size="30" value="[% HTML.escape(description) %]">
+      <input type="button" onclick="part_selection_window('partnumber', 'description', 'parts_id', 0, 'Form', 'no_services:no_assemblies:stockable')" value="?">
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap><translate>Charge number</translate></th>
+     <td><input name="chargenumber" size="30" value="[% HTML.escape(chargenumber) %]"></td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap><translate>Quantity</translate></th>
+     <td>
+      <input name="qty" size="10" value="[% HTML.escape(LxERP.format_amount(qty)) %]">
+      <select name="unit">
+       [%- FOREACH unit = UNITS %]<option[% IF unit.selected %] selected[% END %]>[% HTML.escape(unit.name) %]</option>[% END %]
+      </select>
+     </td>
+    </tr>
+
+    <tr>
+     <th align="right" nowrap><translate>Optional comment</translate></th>
+     <td><input name="comment" size="30" value="[% HTML.escape(comment) %]"></td>
+    </tr>
+
+   </table>
+  </p>
+
+  <p>
+   <input type="submit" class="submit" name="action" value="<translate>Update</translate>">
+   [%- IF parts_id %]
+   <input type="submit" class="submit" name="action" value="<translate>Stock</translate>">
+   [%- END %]
+  </p>
+ </form>
+
+</body>
+</html>
diff --git a/wh.pl b/wh.pl
new file mode 120000 (symlink)
index 0000000..385000d
--- /dev/null
+++ b/wh.pl
@@ -0,0 +1 @@
+am.pl
\ No newline at end of file