marei: tl2019 compat
[kivitendo-erp.git] / SL / Dev / Inventory.pm
index fa80f77..5789b49 100644 (file)
@@ -2,7 +2,12 @@ package SL::Dev::Inventory;
 
 use strict;
 use base qw(Exporter);
 
 use strict;
 use base qw(Exporter);
-our @EXPORT = qw(create_warehouse_and_bins set_stock transfer_stock transfer_sales_delivery_order transfer_purchase_delivery_order transfer_delivery_order_item transfer_in transfer_out);
+our @EXPORT_OK = qw(
+  create_warehouse_and_bins set_stock transfer_stock
+  transfer_sales_delivery_order transfer_purchase_delivery_order
+  transfer_delivery_order_item transfer_in transfer_out
+);
+our %EXPORT_TAGS = (ALL => \@EXPORT_OK);
 
 use SL::DB::Warehouse;
 use SL::DB::Bin;
 
 use SL::DB::Warehouse;
 use SL::DB::Bin;
@@ -30,7 +35,9 @@ sub create_warehouse_and_bins {
 sub set_stock {
   my (%params) = @_;
 
 sub set_stock {
   my (%params) = @_;
 
-  die "param part is missing or not an SL::DB::Part object" unless ref($params{part}) eq 'SL::DB::Part';
+  die "param part is missing or not an SL::DB::Part object"
+    unless ref($params{part}) eq 'SL::DB::Part';
+
   my $part = delete $params{part};
   die "qty is missing" unless $params{qty} or $params{abs_qty};
   die "need a bin or default bin" unless $part->warehouse_id or $part->bin_id or $params{bin} or $params{bin_id};
   my $part = delete $params{part};
   die "qty is missing" unless $params{qty} or $params{abs_qty};
   die "need a bin or default bin" unless $part->warehouse_id or $part->bin_id or $params{bin} or $params{bin_id};
@@ -191,7 +198,8 @@ sub _transfer {
 
   my $transfer_type = delete $params{transfer_type};
 
 
   my $transfer_type = delete $params{transfer_type};
 
-  die "param transfer_type is not a SL::DB::TransferType object: " . Dumper($transfer_type) unless ref($transfer_type) eq 'SL::DB::TransferType';
+  die "param transfer_type is not a SL::DB::TransferType object: " . Dumper($transfer_type)
+    unless ref($transfer_type) eq 'SL::DB::TransferType';
 
   my $shippingdate  = delete $params{shippingdate}  // DateTime->today;
 
 
   my $shippingdate  = delete $params{shippingdate}  // DateTime->today;
 
@@ -224,7 +232,10 @@ sub transfer_in {
 
   my $transfer_type = delete $params{transfer_type} // 'stock';
 
 
   my $transfer_type = delete $params{transfer_type} // 'stock';
 
-  my $transfer_type_obj = SL::DB::Manager::TransferType->find_by( direction => 'in', description => $transfer_type ) or die "Can't find transfer_type with direction in and descriptin " . $params{transfer_type};
+  my $transfer_type_obj = SL::DB::Manager::TransferType->find_by(
+    direction   => 'in',
+    description => $transfer_type,
+  ) or die "Can't find transfer_type with direction in and description " . $params{transfer_type};
 
   $params{transfer_type} = $transfer_type_obj;
 
 
   $params{transfer_type} = $transfer_type_obj;
 
@@ -236,7 +247,10 @@ sub transfer_out {
 
   my $transfer_type = delete $params{transfer_type} // 'shipped';
 
 
   my $transfer_type = delete $params{transfer_type} // 'shipped';
 
-  my $transfer_type_obj = SL::DB::Manager::TransferType->find_by( direction => 'out', description => $transfer_type ) or die "Can't find transfer_type with direction in and descriptin " . $params{transfer_type};
+  my $transfer_type_obj = SL::DB::Manager::TransferType->find_by(
+    direction   => 'out',
+    description => $transfer_type,
+  ) or die "Can't find transfer_type with direction in and description " . $params{transfer_type};
 
   $params{transfer_type} = $transfer_type_obj;
 
 
   $params{transfer_type} = $transfer_type_obj;
 
@@ -245,7 +259,9 @@ sub transfer_out {
 
 sub transfer_sales_delivery_order {
   my ($sales_delivery_order) = @_;
 
 sub transfer_sales_delivery_order {
   my ($sales_delivery_order) = @_;
-  die "first argument must be a sales delivery order Rose DB object" unless ref($sales_delivery_order) eq 'SL::DB::DeliveryOrder' and $sales_delivery_order->is_sales;
+  die "first argument must be a sales delivery order Rose DB object"
+    unless ref($sales_delivery_order) eq 'SL::DB::DeliveryOrder'
+           and $sales_delivery_order->is_sales;
 
   die "the delivery order has already been delivered" if $sales_delivery_order->delivered;
 
 
   die "the delivery order has already been delivered" if $sales_delivery_order->delivered;
 
@@ -266,7 +282,9 @@ sub transfer_sales_delivery_order {
 
 sub transfer_purchase_delivery_order {
   my ($purchase_delivery_order) = @_;
 
 sub transfer_purchase_delivery_order {
   my ($purchase_delivery_order) = @_;
-  die "first argument must be a purchase delivery order Rose DB object" unless ref($purchase_delivery_order) eq 'SL::DB::DeliveryOrder' and not $purchase_delivery_order->is_sales;
+  die "first argument must be a purchase delivery order Rose DB object"
+   unless ref($purchase_delivery_order) eq 'SL::DB::DeliveryOrder'
+          and not $purchase_delivery_order->is_sales;
 
   my ($wh, $bin, $trans_type);
 
 
   my ($wh, $bin, $trans_type);
 
@@ -338,14 +356,19 @@ defaults
 
 Creates a new warehouse and bins, and immediately saves them. Returns the
 warehouse and the first bin object.
 
 Creates a new warehouse and bins, and immediately saves them. Returns the
 warehouse and the first bin object.
+
   my ($wh, $bin) = SL::Dev::Inventory::create_warehouse_and_bins();
 
 Create named warehouse with 10 bins:
   my ($wh, $bin) = SL::Dev::Inventory::create_warehouse_and_bins();
 
 Create named warehouse with 10 bins:
-  my ($wh, $bin) = SL::Dev::Inventory::create_warehouse_and_bins(warehouse_description => 'Testlager',
-                                                                 bin_description       => 'Testlagerplatz',
-                                                                 number_of_bins        => 10,
-                                                                );
+
+  my ($wh, $bin) = SL::Dev::Inventory::create_warehouse_and_bins(
+    warehouse_description => 'Test warehouse',
+    bin_description       => 'Test bin',
+    number_of_bins        => 10,
+  );
+
 To access the second bin:
 To access the second bin:
+
   my $bin2 = $wh->bins->[1];
 
 =head2 C<set_stock %PARAMS>
   my $bin2 = $wh->bins->[1];
 
 =head2 C<set_stock %PARAMS>
@@ -353,55 +376,107 @@ To access the second bin:
 Change the stock level of a certain part by creating an inventory event.
 To access the updated onhand the part object needs to be loaded afterwards.
 
 Change the stock level of a certain part by creating an inventory event.
 To access the updated onhand the part object needs to be loaded afterwards.
 
-Mandatory params:
-  part - an SL::DB::Part object or a parts_id
-  qty | abs_qty
-    qty     : the qty to increase of decrease the stock level by
-    abs_qty : sets stock level for a certain part to abs_qty by creating
-              a stock event with the current difference
+Parameter:
+
+=over 4
+
+=item C<part>
+
+Mandatory. An SL::DB::Part object or a parts_id.
+
+=item C<qty>
+
+The qty to increase of decrease the stock level by.
+
+Exactly one of C<qty> and C<abs_qty> is mandatory.
+
+=item C<abs_qty>
+
+Sets stock level for a certain part to abs_qty by creating a stock event with
+the current difference.
+
+Exactly one of C<qty> and C<abs_qty> is mandatory.
 
 
-Optional params:
-  bin_id | bin
-  shippingdate : may be a DateTime object or a string that needs to be parsed by parse_date_to_object.
-  unit         : SL::DB::Unit object, or the name of an SL::DB::Unit object
+=item C<bin_id>
+
+=item C<bin>
+
+Optional. The bin for inventory entry.
 
 If no bin is passed the default bin of the part is used, if that doesn't exist
 either there will be an error.
 
 
 If no bin is passed the default bin of the part is used, if that doesn't exist
 either there will be an error.
 
+=item C<shippingdate>
+
+Optional. May be a DateTime object or a string that needs to be parsed by
+parse_date_to_object.
+
+=item C<unit>
+
+Optional. SL::DB::Unit object, or the name of an SL::DB::Unit object.
+
+=back
+
 C<set_stock> creates the SL::DB::Inventory object from scratch, rather
 than passing params to WH->transfer_in or WH->transfer_out.
 
 Examples:
 C<set_stock> creates the SL::DB::Inventory object from scratch, rather
 than passing params to WH->transfer_in or WH->transfer_out.
 
 Examples:
+
   my $part = SL::DB::Manager::Part->find_by(partnumber => '1');
   my $part = SL::DB::Manager::Part->find_by(partnumber => '1');
-  SL::Dev::Inventory::set_stock(part => $part, qty =>  5);
+  SL::Dev::Inventory::set_stock(part => $part, abs_qty => 5);
   SL::Dev::Inventory::set_stock(part => $part, qty => -2);
   $part->load;
   $part->onhand; # 3
 
 Set stock level of a part in a certain bin_id to 10:
   SL::Dev::Inventory::set_stock(part => $part, qty => -2);
   $part->load;
   $part->onhand; # 3
 
 Set stock level of a part in a certain bin_id to 10:
+
   SL::Dev::Inventory::set_stock(part => $part, bin_id => 99, abs_qty => 10);
 
 Create 10 warehouses with 5 bins each, then create 100 parts and increase the
 stock qty in a random bin by a random positive qty for each of the parts:
 
   SL::Dev::Inventory::set_stock(part => $part, bin_id => 99, abs_qty => 10);
 
 Create 10 warehouses with 5 bins each, then create 100 parts and increase the
 stock qty in a random bin by a random positive qty for each of the parts:
 
-  SL::Dev::Inventory::create_warehouse_and_bins(warehouse_description => "Testlager $_") for ( 1 .. 10 );
-  SL::Dev::Part::create_part(description => "Testpart $_")->save for ( 1 .. 100 );
+  SL::Dev::Inventory::create_warehouse_and_bins(
+    warehouse_description => "Test Warehouse $_"
+  ) for 1 .. 10;
+  SL::Dev::Part::create_part(
+    description => "Test Part $_"
+  )->save for 1 .. 100;
   my $bins = SL::DB::Manager::Bin->get_all;
   my $bins = SL::DB::Manager::Bin->get_all;
-  SL::Dev::Inventory::set_stock(part => $_,
-                                qty  => int(rand(99))+1,
-                                bin  => $bins->[ rand @{$bins} ],
-                               ) foreach @{ SL::DB::Manager::Part->get_all() };
+  SL::Dev::Inventory::set_stock(
+    part => $_,
+    qty  => int(rand(99))+1,
+    bin  => $bins->[ rand @{$bins} ],
+  ) for @{ SL::DB::Manager::Part->get_all };
 
 =head2 C<transfer_stock %PARAMS>
 
 Transfers parts from one bin to another.
 
 
 =head2 C<transfer_stock %PARAMS>
 
 Transfers parts from one bin to another.
 
-Mandatory params:
-  part | parts_id    - an SL::DB::Part object or a parts_id
-  from_bin           - an SL::DB::Bin object
-  to_bin qty         - an SL::DB::Bin object
+Parameters:
+
+=over 4
+
+=item C<part>
+
+=item C<part_id>
+
+Mandatory. An SL::DB::Part object or a parts_id.
+
+=item C<from_bin>
 
 
-Optional params: shippingdate
+=item C<to_bin>
+
+Mandatory. SL::DB::Bin objects.
+
+=item C<qty>
+
+Mandatory.
+
+=item C<shippingdate>
+
+Optional.
+
+=back
 
 The unit is always base_unit and there is no check for negative stock values.
 
 
 The unit is always base_unit and there is no check for negative stock values.
 
@@ -410,12 +485,17 @@ of the stock to a different bin inside the same warehouse:
 
   my ($wh, $bin) = SL::Dev::Inventory::create_warehouse_and_bins();
   my $part = SL::Dev::Part::create_part->save;
 
   my ($wh, $bin) = SL::Dev::Inventory::create_warehouse_and_bins();
   my $part = SL::Dev::Part::create_part->save;
-  SL::Dev::Inventory::set_stock(part => $part, bin_id => $wh->bins->[2]->id, qty => 5);
-  SL::Dev::Inventory::transfer_stock(part     => $part,
-                                     from_bin => $wh->bins->[2],
-                                     to_bin   => $wh->bins->[4],
-                                     qty      => 3
-                                    );
+  SL::Dev::Inventory::set_stock(
+    part   => $part,
+    bin_id => $wh->bins->[2]->id,
+    qty    => 5,
+  );
+  SL::Dev::Inventory::transfer_stock(
+    part     => $part,
+    from_bin => $wh->bins->[2],
+    to_bin   => $wh->bins->[4],
+    qty      => 3,
+  );
   $part->get_stock(bin_id => $wh->bins->[4]->id); # 3.00000
   $part->get_stock(bin_id => $wh->bins->[2]->id); # 2.00000
 
   $part->get_stock(bin_id => $wh->bins->[4]->id); # 3.00000
   $part->get_stock(bin_id => $wh->bins->[2]->id); # 2.00000
 
@@ -434,6 +514,7 @@ works on database objects.
 As this is just Dev it doesn't check for negative stocks etc.
 
 Usage:
 As this is just Dev it doesn't check for negative stocks etc.
 
 Usage:
+
   my $sales_delivery_order = SL::DB::Manager::DeliveryOrder->find_by(donumber => 112);
   SL::Dev::Inventory::transfer_sales_delivery_order($sales_delivery_order1);
 
   my $sales_delivery_order = SL::DB::Manager::DeliveryOrder->find_by(donumber => 112);
   SL::Dev::Inventory::transfer_sales_delivery_order($sales_delivery_order1);
 
@@ -449,6 +530,7 @@ Transfers a delivery order item from a delivery order. The whole qty is transfer
 Doesn't check for available qty.
 
 Usage:
 Doesn't check for available qty.
 
 Usage:
+
   SL::Dev::Inventory::transfer_delivery_order_item($doi, $wh, $bin, $trans_type);
 
 =head2 C<transfer_in %PARAMS>
   SL::Dev::Inventory::transfer_delivery_order_item($doi, $wh, $bin, $trans_type);
 
 =head2 C<transfer_in %PARAMS>
@@ -458,31 +540,69 @@ is entered via the web interface.
 
 Does some param checking, sets some defaults, but otherwise uses WH->transfer.
 
 
 Does some param checking, sets some defaults, but otherwise uses WH->transfer.
 
-Mandatory params:
-  part               - an SL::DB::Part object
-  qty                - a number
+Parameters:
+
+=over 4
+
+=item C<part>
+
+Mandatory. An SL::DB::Part object.
+
+=item C<qty>
+
+Mandatory.
+
+=item C<bin>
 
 
-Optional params: shippingdate
-  bin           - an SL::DB::Bin object, defaults to $part->bin
-  wh            - an SL::DB::Bin object, defaults to $part->warehouse
-  unit          - a string such as 't', 'Stck', defaults to $part->unit->name
-  shippingdate  - a DateTime object, defaults to today
-  transfer_type - a string such as 'correction', defaults to 'stock'
-  comment
+Optional. An SL::DB::Bin object, defaults to $part->bin.
+
+=item C<wh>
+
+Optional. An SL::DB::Bin object, defaults to $part->warehouse.
+
+=item C<unit>
+
+Optional. A string such as 't', 'Stck', defaults to $part->unit->name.
+
+=item C<shippingdate>
+
+Optional. A DateTime object, defaults to today.
+
+=item C<transfer_type>
+
+Optional. A string such as 'correction', defaults to 'stock'.
+
+=item C<comment>
+
+Optional.
+
+=back
 
 Example minimal usage using part default warehouse and bin:
 
 Example minimal usage using part default warehouse and bin:
+
   my ($wh, $bin) = SL::Dev::Inventory::create_warehouse_and_bins();
   my ($wh, $bin) = SL::Dev::Inventory::create_warehouse_and_bins();
-  my $part       = SL::Dev::Part::create_part(unit => 'kg', warehouse => $wh, bin => $bin)->save;
-  SL::Dev::Inventory::transfer_in(part => $part, qty => '0.9', unit => 't', comment => '900 kg in t');
+  my $part       = SL::Dev::Part::create_part(
+    unit      => 'kg',
+    warehouse => $wh,
+    bin       => $bin,
+  )->save;
+  SL::Dev::Inventory::transfer_in(
+    part    => $part,
+    qty     => 0.9,
+    unit    => 't',
+    comment => '900 kg in t',
+  );
 
 Example with specific transfer_type and warehouse and bin and shipping_date:
 
 Example with specific transfer_type and warehouse and bin and shipping_date:
+
   my $shipping_date = DateTime->today->subtract( days => 20 );
   my $shipping_date = DateTime->today->subtract( days => 20 );
-  SL::Dev::Inventory::transfer_in(part          => $part,
-                                  qty           => 5,
-                                  transfer_type => 'correction',
-                                  bin           => $bin,
-                                  shipping_date => $shipping_date,
-                                 );
+  SL::Dev::Inventory::transfer_in(
+    part          => $part,
+    qty           => 5,
+    transfer_type => 'correction',
+    bin           => $bin,
+    shipping_date => $shipping_date,
+  );
 
 =head2 C<transfer_out %PARAMS>
 
 
 =head2 C<transfer_out %PARAMS>