$self->class('SL::DB::Inventory');
}
+sub set_profile_defaults {
+};
+
sub init_profile {
my ($self) = @_;
my $profile = $self->SUPER::init_profile;
- delete @{$profile}{qw(trans_id oe_id delivery_order_items_stock_id bestbefore trans_type_id project_id)};
+ delete @{$profile}{qw(trans_id oe_id delivery_order_items_stock_id trans_type_id project_id)};
+ delete @{$profile}{qw(bestbefore)} if !$::instance_conf->get_show_bestbefore;
return $profile;
}
my ($self) = @_;
my $all_parts = SL::DB::Manager::Part->get_all;
- return { map { my $col = $_; ( $col => { map { ( $_->$col => $_ ) } @{ $all_parts } } ) } qw(id partnumber ean description) };
+ return { map { my $col = $_; ( $col =>
+ { map { ( $_->$col => $_ ) } grep { defined $_->$col } @{ $all_parts } } ) } qw(id partnumber ean description) };
}
sub init_warehouses_by {
my $bins_by;
$bins_by->{_wh_id_and_id_ident()} = { map { ( _wh_id_and_id_maker($_->warehouse_id, $_->id) => $_ ) } @{ $all_bins } };
$bins_by->{_wh_id_and_description_ident()} = { map { ( _wh_id_and_description_maker($_->warehouse_id, $_->description) => $_ ) } @{ $all_bins } };
-
return $bins_by;
}
$self->controller->track_progress(phase => 'building data', progress => 0);
- my $i;
+ my $i = 0;
my $num_data = scalar @{ $self->controller->data };
foreach my $entry (@{ $self->controller->data }) {
$self->controller->track_progress(progress => $i/$num_data * 100) if $i % 100 == 0;
{ name => 'warehouse', description => $::locale->text('Warehouse') },
{ name => 'warehouse_id', description => $::locale->text('Warehouse (database ID)') },
);
+ if ($::instance_conf->get_show_bestbefore) {
+ $self->add_displayable_columns({ name => 'bestbefore', description => $::locale->text('Best Before') });
+ }
}
sub check_warehouse {
my $object = $entry->{object};
+ $self->settings->{apply_warehouse} ||= ''; # avoid warnings if undefined
+
# If warehouse from front-end is enforced for all transfers, use this, if valid.
if ($self->settings->{apply_warehouse} eq 'all') {
$object->warehouse_id(undef);
$object->warehouse_id($wh->id);
}
- # Check wether or not warehouse ID is valid.
+ # Check whether or not warehouse ID is valid.
if ($object->warehouse_id && !$self->warehouses_by->{id}->{ $object->warehouse_id }) {
push @{ $entry->{errors} }, $::locale->text('Error: Invalid warehouse');
return 0;
my $object = $entry->{object};
+ $self->settings->{apply_bin} ||= ''; # avoid warnings if undefined
+
# If bin from front-end is enforced for all transfers, use this, if valid.
if ($self->settings->{apply_bin} eq 'all') {
$object->bin_id(undef);
$object->bin_id($bin->id);
}
- # Check wether or not bin ID is valid.
+ # Check whether or not bin ID is valid.
if ($object->bin_id && !$self->bins_by->{_wh_id_and_id_ident()}->{ _wh_id_and_id_maker($object->warehouse_id, $object->bin_id) }) {
push @{ $entry->{errors} }, $::locale->text('Error: Invalid bin');
return 0;
}
-
+
# Map description to ID if given.
- if (!$object->bin_id && $entry->{raw_data}->{bin}) {
+ if (!$object->bin_id && $entry->{raw_data}->{bin} && $object->warehouse_id) {
my $bin = $self->bins_by->{_wh_id_and_description_ident()}->{ _wh_id_and_description_maker($object->warehouse_id, $entry->{raw_data}->{bin}) };
if (!$bin) {
push @{ $entry->{errors} }, $::locale->text('Error: Invalid bin');
my $object = $entry->{object};
- # Check wether or non part ID is valid.
+ # Check whether or not part ID is valid.
if ($object->parts_id && !$self->parts_by->{id}->{ $object->parts_id }) {
push @{ $entry->{errors} }, $::locale->text('Error: Invalid part');
return 0;
# This imports inventories when target_qty is given, transfers else.
# So we get the actual qty in stock and transfer the difference in case of
# a given target_qty
-sub check_qty{
+sub check_qty {
my ($self, $entry) = @_;
my $object = $entry->{object};
+ # parse qty (may be float values)
+ if (exists $entry->{raw_data}->{target_qty}) {
+ $entry->{raw_data}->{target_qty} = $::form->parse_amount(\%::myconfig, $entry->{raw_data}->{target_qty});
+ # $object->target_qty($entry->{raw_data}->{target_qty});
+ }
+ if (exists $entry->{raw_data}->{qty}) {
+ $entry->{raw_data}->{qty} = $::form->parse_amount(\%::myconfig, $entry->{raw_data}->{qty});
+ $object->qty($entry->{raw_data}->{qty});
+ }
if (! exists $entry->{raw_data}->{target_qty} && ! exists $entry->{raw_data}->{qty}) {
push @{ $entry->{errors} }, $::locale->text('Error: A quantity or a target quantity must be given.');
return 0;
}
# Actual quantity is read from stock or is the result of transfers for the
- # same part, warehouse and bin done before.
- my $key = join '+', $object->parts_id, $object->warehouse_id, $object->bin_id;
+ # same part, warehouse, bin, chargenumber and bestbefore date (if
+ # show_bestbefore is enabled) done before.
+ my $key = join '+', $object->parts_id, $object->warehouse_id, $object->bin_id, $object->chargenumber;
+ $key .= join '+', $key, $object->bestbefore if $::instance_conf->get_show_bestbefore;
+
if (!exists $self->{resulting_quantities}->{$key}) {
- my $stock = $object->part->get_simple_stock;
- my @stocked = grep { $_->{warehouse_id} == $object->warehouse_id && $_->{bin_id} == $object->bin_id } @$stock;
- my $stocked_qty = 0;
- foreach (@stocked) {
- $stocked_qty += $stocked[0]->{sum} * 1;
- }
- $self->{resulting_quantities}->{$key} = $stocked_qty;
+ $self->{resulting_quantities}->{$key} = _get_stocked_qty($object);
}
my $actual_qty = $self->{resulting_quantities}->{$key};
# employee from login if not given
if (!$object->employee_id) {
- $object->employee_id(SL::DB::Manager::Employee->find_by(login => $::myconfig{login})->id);
+ $object->employee_id(SL::DB::Manager::Employee->current->id) if SL::DB::Manager::Employee->current;
}
if ($object->employee_id) {
my $data = $params{data} || $self->controller->data;
foreach my $entry (@{ $data }) {
- my ($trans_id) = selectrow_query($::form, $::form->get_standard_dbh, qq|SELECT nextval('id')|);
+ my ($trans_id) = selectrow_query($::form,$entry->{object}->db->dbh, qq|SELECT nextval('id')|);
$entry->{object}->trans_id($trans_id);
}
$self->SUPER::save_objects(%params);
}
+sub _get_stocked_qty {
+ my ($object) = @_;
+
+ my $bestbefore_filter = '';
+ my $bestbefore_val_cnt = 0;
+ if ($::instance_conf->get_show_bestbefore) {
+ $bestbefore_filter = ($object->bestbefore) ? 'AND bestbefore = ?' : 'AND bestbefore IS NULL';
+ $bestbefore_val_cnt = ($object->bestbefore) ? 1 : 0;
+ }
+
+ my $query = <<SQL;
+ SELECT sum(qty) FROM inventory
+ WHERE parts_id = ? AND warehouse_id = ? AND bin_id = ? AND chargenumber = ? $bestbefore_filter
+ GROUP BY warehouse_id, bin_id, chargenumber
+SQL
+
+ my @values = ($object->parts_id,
+ $object->warehouse_id,
+ $object->bin_id,
+ $object->chargenumber);
+ push @values, $object->bestbefore if $bestbefore_val_cnt;
+
+ my ($stocked_qty) = selectrow_query($::form, $object->db->dbh, $query, @values);
+
+ return $stocked_qty;
+}
+
sub _wh_id_and_description_ident {
return 'wh_id+description';
}
sub _wh_id_and_description_maker {
- return join '+', $_[0], $_[1]
+ return join '+', $_[0], $_[1]
}
sub _wh_id_and_id_ident {
}
sub _wh_id_and_id_maker {
- return join '+', $_[0], $_[1]
+ return join '+', $_[0], $_[1]
}
1;