Business::Inventory::Valuation - Calculate inventory value/unit price (using LIFO/FIFO/weighted average)
This document describes version 0.007 of Business::Inventory::Valuation (from Perl distribution Business-Inventory-Valuation), released on 2018-03-17.
use Business::Inventory::Valuation; my $biv = Business::Inventory::Valuation->new( method => 'LIFO', # required. choose LIFO/FIFO/weighted average #allow_negative_inventory => 0, # optional, default 0 ); my @inv; # buy: 100 units @1500 $biv->buy(100, 1500); @inv = $biv->inventory; # => ([100, 1500]) say $biv->units; # 100 say $biv->average_purchase_price; # 1500 # buy more: 150 units @1600 $biv->buy(150, 1600); @inv = $biv->inventory; # => ([100, 1500], [150, 1600]) say $biv->units; # 250 say $biv->average_purchase_price; # 1560 # sell: 50 units @1700. with LIFO method, the most recently purchased units are sold first. $biv->sell( 50, 1700); # returns two versions of realized profit & actual units sold: (7000, 5000, 50) @inv = $biv->inventory; # => ([100, 1500], [100, 1600]) say $biv->units; # 200 say $biv->average_purchase_price; # 1550 # buy: 200 units @1500 $biv->buy(200, 1500); @inv = $biv->inventory; # => ([100, 1500], [100, 1600], [200, 1500]) say $biv->units; # 400 say $biv->average_purchase_price; # 1550 # sell: 350 units @1800 $biv->sell(350, 1800); # returns two versions of realized profit & actual units sold: (96250, 95000, 350) @inv = $biv->inventory; # => ([50, 1500]) say $biv->units; # 50 say $biv->average_purchase_price; # 1500 ($units, $avgprice) = $biv->summary; # => (50, 1500) # sell: 60 units @1700 $biv->sell(60, 1700); # dies! tried to oversell more than available in inventory.
With FIFO method, the most anciently purchased units are sold first:
my $biv = Business::Inventory::Valuation->new(method => 'FIFO'); $biv->buy(100, 1500); $biv->buy(150, 1600); $biv->sell(50, 1700); # returns two versions of realized profit & actual units sold: (7000, 10000, 50) @inv = $biv->inventory; # => ([50, 1500], [150, 1600]) say $biv->units; # 200 say $biv->average_purchase_price; # 1575
With weighted average method, each purchase will be pooled into a single group with purchase price set to average purchase price:
weighted average
my $biv = Business::Inventory::Valuation->new(method => 'weighted average'); $biv->buy(100, 1500); @inv = $biv->inventory; # => ([100, 1500]) say $biv->units; # 100 say $biv->average_purchase_price; # 1500 $biv->buy(150, 1600); @inv = $biv->inventory; # => ([250, 1560]) say $biv->units; # 250 say $biv->average_purchase_price; # 1560 $biv->sell( 50, 1700); # returns: (7000, 7000, 50) @inv = $biv->inventory; # => ([200, 1560]) say $biv->units; # 200 say $biv->average_purchase_price; # 1560
Overselling is allowed when allow_negative_inventory is set to true. Amount sold is set to the available inventory and inventory becomes empty:
allow_negative_inventory
my $biv = Business::Inventory::Valuation->new( method => 'LIFO', allow_negative_inventory => 1, ); $biv->buy(100, 1500); $biv->buy(150, 1600); $biv->sell(300, 1700); # returns two versions of realized profit & actual units sold: (35000, 35000, 250) @inv = $biv->inventory; # => () say $biv->units; # 0 say $biv->average_purchase_price; # undef
This class can be used if you want to calculate average purchase price from a series of purchases each with different prices (like when buying stocks or cryptocurrencies) or want to value your inventory using LIFO/FIFO method.
Keywords: average purchase price, inventory, inventory valuation, cost accounting, FIFO, LIFO, weighted average, COGS, cost of goods sold.
Usage: Business::Inventory::Valuation->new(%args) => obj
Known arguments (* denotes required argument):
*
method* => str ("LIFO"|"FIFO"|"weighted average")
When the method is LIFO or FIFO, the class will keep track of each purchase at different prices. Then when there is a selling, the units that are most recently purchased (in the case of FIFO) or most anciently purchased (in the case of LIFO) will be subtracted first.
LIFO
FIFO
When the method is weighted average, each purchase will be mixed into a single pool with the purchase price being calculated at average purchase price.
allow_negative_inventory => bool (default: 0)
By default, when you try to sell() more amount than you have bought, the method will die. When this argument is set to true, the method will not die but will simply ignore then excess amount sold (see "sell" for more details).
sell()
Usage: $biv->buy($units, $unit_price) => num
Add units to inventory. Will return average purchase price, which is calculated as the weighted average from all purchases.
Usage: $biv->sell($units, $unit_price) => ($profit1, $profit2, $actual_units_sold)
Take units from inventory. If method is FIFO, will take the units according to the order of purchase (units bought earlier will be taken first). If method is LIFO, will take the units according to the reverse order of purchase (units bought later will be taken first).
Will die if $units exceeds the number of units in inventory (overselling), unless when allow_negative_inventory constructor argument is set to true (see "new") which will just take the inventory up to the amount of inventory and set the inventory to zero.
$units
$unit_price is the unit selling price.
$unit_price
Will return a list containing two versions of realized profits as well actual units sold. The first element is profit calculated using weighted average method: ($unit_price - average-purchase-price) x units-sold. The second element is profit calculated by the actual purchase price of the taken units (in the case of LIFO or FIFO). When method is `weighted average', the first element and second element will be the same. Actual units sold can be different from $units if there is overselling, since we subtract only with the available units in inventory.
To calculate the COGS (cost of goods sold), you can use:
$units*$unit_price - $profit2
Usage: $biv->units => num
Return the current number of units in the inventory.
If you want to know each number of units bought at different prices, use "inventory".
Usage: $biv->average_purchase_price => num
Return the average purchase price, which is calculated by weighted average.
If there is no inventory, will return undef.
Usage: $biv->inventory => @ary
Return the current inventory, which is a list of [units, price] arrays. For example if you buy 500 units @10 then buy another 1000 units @12.5, inventory() will return: ([500, 10], [1000, 12.5]).
[units, price]
inventory()
([500, 10], [1000, 12.5])
Please visit the project's homepage at https://metacpan.org/release/Business-Inventory-Valuation.
Source repository is at https://github.com/perlancar/perl-Business-Inventory-Valuation.
Please report any bugs or feature requests on the bugtracker website https://rt.cpan.org/Public/Dist/Display.html?Name=Business-Inventory-Valuation
When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.
perlancar <perlancar@cpan.org>
This software is copyright (c) 2018 by perlancar@cpan.org.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Business::Inventory::Valuation, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Business::Inventory::Valuation
CPAN shell
perl -MCPAN -e shell install Business::Inventory::Valuation
For more information on module installation, please visit the detailed CPAN module installation guide.