X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FController%2FInventory.pm;h=13246387265d7afcc1a5084cd2aa2bd196f07105;hb=4874214f33115e49dce29501d615848fa9df11ce;hp=e317381f0d696b6c63dfbcd3793388b496aa0255;hpb=8736e198c8c28a0257fc850a80b4dace85b4e9e3;p=kivitendo-erp.git diff --git a/SL/Controller/Inventory.pm b/SL/Controller/Inventory.pm index e317381f0..132463872 100644 --- a/SL/Controller/Inventory.pm +++ b/SL/Controller/Inventory.pm @@ -20,6 +20,7 @@ use SL::DBUtils; use SL::Helper::Flash; use SL::Controller::Helper::ReportGenerator; use SL::Controller::Helper::GetModels; +use List::MoreUtils qw(uniq); use English qw(-no_match_vars); @@ -44,6 +45,12 @@ sub action_stock_in { $::form->{title} = t8('Stock'); + # Sometimes we want to open stock_in with a part already selected, but only + # the parts_id is passed in the url (and not also warehouse, bin and unit). + # Setting select_default_bin in the form will make sure the default warehouse + # and bin of that part will already be preselected, as normally + # set_target_from_part is only called when a part is changed. + $self->set_target_from_part if $::form->{select_default_bin}; $::request->layout->focus('#part_id_name'); my $transfer_types = WH->retrieve_transfer_types('in'); map { $_->{description} = $main::locale->text($_->{description}) } @{ $transfer_types }; @@ -58,7 +65,6 @@ sub action_stock_usage { $::form->get_lists('warehouses' => { 'key' => 'WAREHOUSES', 'bins' => 'BINS', }); - $::request->layout->use_javascript("${_}.js") for qw(kivi.PartsWarehouse); $self->setup_stock_usage_action_bar; $self->render('inventory/warehouse_usage', @@ -411,13 +417,13 @@ sub action_stock { qty => $qty, unit => $self->unit, transfer_type => 'stock', + transfer_type_id => $::form->{transfer_type_id}, chargenumber => $::form->{chargenumber}, bestbefore => $::form->{bestbefore}, - ean => $::form->{ean}, comment => $::form->{comment}, }); 1; - } or do { $transfer_error = $EVAL_ERROR->getMessage; } + } or do { $transfer_error = $EVAL_ERROR->error; } }); if (!$transfer_error) { @@ -568,7 +574,7 @@ sub action_save_stocktaking { stocktaking_cutoff_date => $::form->{cutoff_date_as_date}, }); 1; - } or do { $transfer_error = $EVAL_ERROR->getMessage; } + } or do { $transfer_error = $EVAL_ERROR->error; } }); return $self->js->flash('error', $transfer_error)->render() @@ -698,7 +704,7 @@ sub init_stocktaking_cutoff_date { my $now = DateTime->now_local; my $cutoff = DateTime->new(year => $now->year, month => 12, day => 31); if ($now->month < 1) { - $cutoff->substract(years => 1); + $cutoff->subtract(years => 1); } return $cutoff; } @@ -782,22 +788,55 @@ sub build_unit_select { sub mini_journal { my ($self) = @_; - # get last 10 transaction ids - my $query = 'SELECT trans_id, max(itime) FROM inventory GROUP BY trans_id ORDER BY max(itime) DESC LIMIT 10'; - my @ids = selectall_array_query($::form, $::form->get_standard_dbh, $query); + # We want to fetch the last 10 inventory events (inventory rows with the same trans_id) + # To prevent a Seq Scan on inventory set an index on inventory.itime + # Each event may have one (transfer_in/out) or two (transfer) inventory rows + # So fetch the last 20, group by trans_id, limit to the last 10 trans_ids, + # and then extract the inventory ids from those 10 trans_ids + # By querying Inventory->get_all via the id instead of trans_id we can make + # use of the existing index on id - my $objs; - $objs = SL::DB::Manager::Inventory->get_all(query => [ trans_id => \@ids ]) if @ids; + # inventory ids of the most recent 10 inventory trans_ids + my $query = <get_all( + query => [ id => [ \"$query" ] ], # " make emacs happy + with_objects => [ 'parts', 'trans_type', 'bin', 'bin.warehouse' ], # prevent lazy loading in template + sort_by => 'itime DESC', + ); + # remember order of trans_ids from query, for ordering hash later + my @sorted_trans_ids = uniq map { $_->trans_id } @$objs; + + # at most 2 of them belong to a transaction and the qty determines in or out. my %transactions; for (@$objs) { $transactions{ $_->trans_id }{ $_->qty > 0 ? 'in' : 'out' } = $_; $transactions{ $_->trans_id }{base} = $_; } - # and get them into order again - my @sorted = map { $transactions{$_} } @ids; + + # because the inventory transactions were built in a hash, we need to sort the + # hash by using the original sort order of the trans_ids + my @sorted = map { $transactions{$_} } @sorted_trans_ids; return \@sorted; } @@ -914,7 +953,7 @@ sub _already_counted { my %bestbefore_filter; if ($::instance_conf->get_show_bestbefore) { - %bestbefore_filter = (bestbefore => $params{bestbefore}); + %bestbefore_filter = (bestbefore => ($params{bestbefore} || undef)); } SL::DB::Manager::Stocktaking->get_all(query => [and => [parts_id => $part->id,