[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
SF.net SVN: ledger-smb:[5518] trunk/LedgerSMB
- Subject: SF.net SVN: ledger-smb:[5518] trunk/LedgerSMB
- From: ..hidden..
- Date: Tue, 08 Jan 2013 10:15:16 +0000
Revision: 5518
http://ledger-smb.svn.sourceforge.net/ledger-smb/?rev=5518&view=rev
Author: einhverfr
Date: 2013-01-08 10:15:15 +0000 (Tue, 08 Jan 2013)
Log Message:
-----------
New code object model for inventory adjustments
Added Paths:
-----------
trunk/LedgerSMB/Inventory/
trunk/LedgerSMB/Inventory/Adjust.pm
trunk/LedgerSMB/Inventory/Adjust_Line.pm
Added: trunk/LedgerSMB/Inventory/Adjust.pm
===================================================================
--- trunk/LedgerSMB/Inventory/Adjust.pm (rev 0)
+++ trunk/LedgerSMB/Inventory/Adjust.pm 2013-01-08 10:15:15 UTC (rev 5518)
@@ -0,0 +1,192 @@
+=head1 NAME
+
+LedgerSMB::Inventory::Adjust - Inventory Adjustments for LedgerSMB
+
+=head1 SYNPOSIS
+
+ my $adjustment = LedgerSMB::Inventory::Adjust->new(%$request);
+ $adjustment->add_line({parts_id => 1024, expected => 37, counted => 42});
+ $adjustment->lines_from_request($request);
+ $adjustment->save;
+
+=cut
+
+package LedgerSMB::Inventory::Adjust;
+use Moose;
+with 'LedgerSMB::DBObject_Moose';
+use LedgerSMB::MooseTypes;
+use LedgerSMB::Inventory::Adjust_Line;
+
+=head1 DESCRIPTION
+
+This module includes the basic routines for importing inventory adjustments,
+initial inventory and the like. Inventory adjustments follow the following
+rules:
+
+=over
+
+=item Shrinkage and Loss
+
+If the counted is less than expected (the normal case) then an we sell the
+goods to ourselves at a 100% discount thus recording cost of goods sold for the
+missing parts.
+
+=item More than Expected
+
+In the case where more is counted than expected we purchase the difference
+from ourselves at last cost. This invoice would be expected to be paid using an
+equity account, though this is not currently automated.
+
+=back
+
+The process of counting inventory is a periodic one and therefore this needs to handle both initial inventory import and periodic corrections.
+
+=head1 PROPERTIES
+
+=over
+
+=item id int
+
+This is the id of the report, only valid once stored
+
+=cut
+
+has id => (is => 'rw', isa => 'Int', required => '0');
+
+=item transdate date
+
+This is the date the inventory was counted at. The invoices take effect on
+this date. Required.
+
+=cut
+
+has transdate => (is => 'ro', isa => 'LedgerSMB::Moose::Date',
+ coerce => '1', required => '1');
+
+=item source text
+
+This is the reference number or description of the count, may be the username
+of the individual or the like.
+
+=cut
+
+has source => (is => 'ro', isa => 'Str', required => '1');
+
+=item rows arrayref[LedgerSMB::Inventory::Adjust_Line]
+
+This is a an array of journal entry lines to be added (lines are added one at
+a time.)
+
+=cut
+
+has rows => (is => 'rw',
+ isa => 'ArrayRef[LedgerSMB::Inventory::Adjust_Line]',
+ required => '0');
+
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item add_line($hashref)
+
+This function adds a line from a hashref. Typically used by automatic import
+routines and the like.
+
+=cut
+
+sub add_line{
+ my ($self, $hashref) = @_;
+ return if !$hashref->{partnumber} and !$hashref->{parts_id};
+ my $line = LedgerSMB::Inventory::Adjust_Line->new(%$hashref);
+ my @lines = @{$self->rows};
+ push @lines, $line;
+ $self->rows(..hidden..);
+}
+
+=item lines_from_form
+
+This function flattens a form. It loops from 1 to $hashref->{rowcount}, and
+for each item found, checks for parts_id_$_ and partnumber_$_. If either is
+found and counted_$_ is found, it creates a new line with the indexed keys of
+parts_id, partnumber, counted, and expected.
+
+Note that expected is optional and if not defined gets calculated based on the
+date of the report. This happens during the save process.
+
+This then appends the lines onto the current report's @rows in order to ensure
+that many differnet sources could be combined together in this way.
+
+=cut
+
+sub lines_from_form {
+ my ($self, $hashref) = @_;
+ my @lines;
+ for my $ln (1 .. $hashref->{rowcount}){
+ next if !$hashref->{"counted_$ln"};
+ next if !$hashref->{"partnumber_$ln"} and !$hashref->{"parts_id_$ln"};
+ my $line = LedgerSMB::Inventory::Adjust_Line->new(
+ {parts_id => $hashref->{"parts_id_$ln"},
+ partnumber => $hashref->{"partnumber_$ln"},
+ counted => $hashref->{"counted_$ln"},
+ expected => $hashref->{"expected_$ln"}});
+ push @lines, $line;
+ }
+ my $rows = $self->rows;
+ push @$rows, @lines;
+ $self->rows($rows);
+}
+
+=item save
+
+This saves the report. In the process we run every line through a variance
+check which allows the expected number of parts to be looked up if not provided.
+
+=cut
+
+sub save {
+ my ($self) = @_;
+ my ($ref) = $self->exec_method({funcname => 'inventory_adjust__save_info'});
+ $self->id($ref->{id});
+ for my $row(@{$self->rows}){
+ $row->check_variance($self->transdate);
+ $row->save($self->id);
+ }
+}
+
+=item approve
+
+Approves the inventory adjustment and creates the (draft) AR/AP invoices.
+These can then be approved, adjusted, have payment lines recorded, and the like.
+
+=cut
+
+sub approve {
+ my ($self) = @_;
+ my ($ref) = $self->exec_method({funcname => 'inventory_adjust__approve'});
+};
+
+
+=item delete
+
+Deletes the inventory adjustment. This can only be done if the inventory
+adjustment is not approved.
+
+=cut
+
+sub delete {
+ my ($self) = @_;
+ my ($ref) = $self->exec_method({funcname => 'inventory_adjust__delete'});
+}
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2013 The LedgerSMB Core Team. This file may be re-used under the
+terms of the LedgerSMB General Public License version 2 or at your option any
+later version. Please see enclosed LICENSE file for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
Added: trunk/LedgerSMB/Inventory/Adjust_Line.pm
===================================================================
--- trunk/LedgerSMB/Inventory/Adjust_Line.pm (rev 0)
+++ trunk/LedgerSMB/Inventory/Adjust_Line.pm 2013-01-08 10:15:15 UTC (rev 5518)
@@ -0,0 +1,173 @@
+=head1 NAME
+
+LedgerSMB::Inventory::Adjust_Line - Inventory Adjustemnt Lines for LedgerSMB
+
+=head1 SYNPOSIS
+
+ my $line = LedgerSMB::Inventory::Adjust_Line->new(%$hashref);
+ $line->check_variance($date);
+ $line->save($adjustment_set_id);
+
+=cut
+
+package LedgerSMB::Inventory::Adjust_Line;
+use Moose;
+use LedgerSMB::MooseTypes;
+with 'LedgerSMB::DBObject_Moose';
+
+=head1 DESCRIPTION
+
+This module provides the actual inventory check routines for inventory
+adjustments. This module handles things like checking expected values and the
+like.
+
+=head1 PROPERTIES
+
+=over
+
+=item parts_id int
+
+This is the id of the part. It is required on saving but not before then as
+it may be looked up.
+
+=cut
+
+has parts_id => (is => 'rw', isa => 'Int', required => 0);
+
+=item partnumber
+
+This matches either the barcode or partnumber of the part. If there is a
+conflict, partnumber wins. Note that this is an exact match, not a prefix
+search.
+
+=cut
+
+has partnumber => (is => 'rw', isa => 'Str', required => 0);
+
+=item expected
+
+This is the number expected. If blank we will look up the expected amount from
+the database during the check_variance method.
+
+=cut
+
+has expected => (is => 'rw', isa => 'LedgerSMB::Moose::Number', coerce => 1,
+ required => 0);
+
+=item counted
+
+The number counted. Obviously for a valid inventory count, we need to have
+this....
+
+=cut
+
+has counted => (is => 'ro', isa => 'LedgerSMB::Moose::Number', coerce => 1,
+ required => 1);
+
+=item variance
+
+This is the variance. It is usually calculated during the variance check
+or, if expected is set and variance not, on save.
+
+=cut
+
+has variance => (is => 'rw', isa => 'LedgerSMB::Moose::Number', coerce => 1,
+ required => 1);
+
+=item adjust_id int
+
+This is the adjustment set id, usually set during the save process.
+
+=cut
+
+has adjust_id => (is => 'rw', isa => 'Int', required => 0);
+
+=item counted_date date
+
+This is the counted date, usually set during the variance check.
+
+=cut
+
+has counted_date => (is => 'rw', isa => 'LedgerSMB::Moose::Date', coerce => 1,
+ required => 0);
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item search_part($partnumber, $count_on)
+
+This routine searches for a part based on partnumber and returns a hashref with
+the parts_id and counted if it is found. The $count_on parameter provides an
+optional date which to use to calculate. If none is provided, current date is
+used.
+
+=cut
+
+sub search_part{
+ my ($self, $partnumber, $count_on) = @_;
+ my $ref;
+ if ($partnumber){
+ ($ref) = $self->exec_method(
+ {funcname => 'inventory__search_part',
+ args => [$partnumber, $count_on]}
+ );
+ } else {
+ die 'Bad call for search_part' if !$self->{parts_id};
+ ($ref) = $self->exec_method({funcname => 'inventory__search_part'});
+ }
+ return $ref;
+}
+
+=item check_variance($date)
+
+This routine calculates the variance and sets it as of the date provided. Note
+that if $self->expected is set, then that value is used instead of calculating
+the value from the database.
+
+=cut
+
+sub check_variance {
+ my ($self, $date) = @_;
+ $self->counted_date($date);
+ if (defined $self->expected){
+ $self->variance($self->counted - $self->expected);
+ return $self->variance;
+ }
+ my $ref;
+ if ($self->parts_id){
+ $ref = $self->search_part;
+ } else {
+ $ref = $self->search_part($self->partnumber, $date);
+ $self->parts_id($ref->{parts_id});
+ }
+ $self->expected($ref->{expected});
+ $self->variance($self->counted - $self->expected);
+ return $self->variance;
+}
+
+=item save($adjustment_id)
+
+Saves the adjustment to the report indicated.
+
+=cut
+
+sub save {
+ my ($self, $adjustment_id) = @_;
+ $self->adjust_id($adjustment_id);
+ die 'No part specified' unless $self->parts_id;
+ $self->check_variance unless defined $self->variance;
+ $self->exec_method({funcname => 'inventory__save_adjust_line'});
+}
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2013 The LedgerSMB Core Team. This file may be re-used under the
+terms of the LedgerSMB General Public License version 2 or at your option any
+later version. Please see enclosed LICENSE file for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.