+sub prepare_stocktaking_report {
+ my ($self, %params) = @_;
+
+ my $callback = $self->stocktaking_models->get_callback;
+
+ my $report = SL::ReportGenerator->new(\%::myconfig, $::form);
+ $self->{report} = $report;
+
+ my @columns = qw(itime employee ean partnumber part qty unit bin chargenumber comment cutoff_date);
+ my @sortable = qw(itime employee ean partnumber part qty bin chargenumber comment cutoff_date);
+
+ my %column_defs = (
+ itime => { sub => sub { $_[0]->itime_as_timestamp },
+ text => t8('Insert Date'), },
+ employee => { sub => sub { $_[0]->employee->safe_name },
+ text => t8('Employee'), },
+ ean => { sub => sub { $_[0]->part->ean },
+ text => t8('EAN'), },
+ partnumber => { sub => sub { $_[0]->part->partnumber },
+ text => t8('Part Number'), },
+ part => { sub => sub { $_[0]->part->description },
+ text => t8('Part Description'), },
+ qty => { sub => sub { $_[0]->qty_as_number },
+ text => t8('Target Qty'),
+ align => 'right', },
+ unit => { sub => sub { $_[0]->part->unit },
+ text => t8('Unit'), },
+ bin => { sub => sub { $_[0]->bin->full_description },
+ text => t8('Bin'), },
+ chargenumber => { text => t8('Charge Number'), },
+ comment => { text => t8('Comment'), },
+ cutoff_date => { sub => sub { $_[0]->cutoff_date_as_date },
+ text => t8('Cutoff Date'), },
+ );
+
+ $report->set_options(
+ std_column_visibility => 1,
+ controller_class => 'Inventory',
+ output_format => 'HTML',
+ title => (!!$params{full})? $::locale->text('Stocktaking Journal') : $::locale->text('Stocktaking History'),
+ allow_pdf_export => !!$params{full},
+ allow_csv_export => !!$params{full},
+ );
+ $report->set_columns(%column_defs);
+ $report->set_column_order(@columns);
+ $report->set_export_options(qw(stocktaking_journal filter));
+ $report->set_options_from_form;
+ $self->stocktaking_models->disable_plugin('paginated') if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
+ $self->stocktaking_models->set_report_generator_sort_options(report => $report, sortable_columns => \@sortable) if !!$params{full};
+ if (!!$params{full}) {
+ $report->set_options(
+ raw_top_info_text => $self->render('inventory/stocktaking/full_report_top', { output => 0 }),
+ );
+ }
+ $report->set_options(
+ raw_bottom_info_text => $self->render('inventory/stocktaking/report_bottom', { output => 0 }),
+ );
+}
+
+sub _get_stocked_qty {
+ my ($part, %params) = @_;
+
+ my $bestbefore_filter = '';
+ my $bestbefore_val_cnt = 0;
+ if ($::instance_conf->get_show_bestbefore) {
+ $bestbefore_filter = ($params{bestbefore}) ? 'AND bestbefore = ?' : 'AND bestbefore IS NULL';
+ $bestbefore_val_cnt = ($params{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 = ($part->id,
+ $params{warehouse_id},
+ $params{bin_id},
+ $params{chargenumber});
+ push @values, $params{bestbefore} if $bestbefore_val_cnt;
+
+ my ($stocked_qty) = selectrow_query($::form, $::form->get_standard_dbh, $query, @values);
+
+ return 1*($stocked_qty || 0);
+}
+
+sub _already_counted {
+ my ($part, %params) = @_;
+
+ my %bestbefore_filter;
+ if ($::instance_conf->get_show_bestbefore) {
+ %bestbefore_filter = (bestbefore => $params{bestbefore});
+ }
+
+ SL::DB::Manager::Stocktaking->get_all(query => [and => [parts_id => $part->id,
+ warehouse_id => $params{warehouse_id},
+ bin_id => $params{bin_id},
+ cutoff_date => $params{cutoff_date},
+ chargenumber => $params{chargenumber},
+ %bestbefore_filter]],
+ sort_by => ['itime DESC']);
+}
+