+sub action_stocktaking {
+ my ($self) = @_;
+
+ $::request->{layout}->use_javascript("${_}.js") for qw(kivi.Inventory);
+ $::request->layout->focus('#part_id_name');
+ $self->setup_stock_stocktaking_action_bar;
+ $self->render('inventory/stocktaking/form', title => t8('Stocktaking'));
+}
+
+sub action_save_stocktaking {
+ my ($self) = @_;
+
+ return $self->js->flash('error', t8('Please choose a part.'))->render()
+ if !$::form->{part_id};
+
+ return $self->js->flash('error', t8('A target quantitiy has to be given'))->render()
+ if $::form->{target_qty} eq '';
+
+ my $target_qty = $::form->parse_amount(\%::myconfig, $::form->{target_qty});
+
+ return $self->js->flash('error', t8('Error: A negative target quantity is not allowed.'))->render()
+ if $target_qty < 0;
+
+ my $stocked_qty = _get_stocked_qty($self->part,
+ warehouse_id => $self->warehouse->id,
+ bin_id => $self->bin->id,
+ chargenumber => $::form->{chargenumber},
+ bestbefore => $::form->{bestbefore},);
+
+ my $stocked_qty_in_form_units = $self->part->unit_obj->convert_to($stocked_qty, $self->unit);
+
+ if (!$::form->{dont_check_already_counted}) {
+ my $already_counted = _already_counted($self->part,
+ warehouse_id => $self->warehouse->id,
+ bin_id => $self->bin->id,
+ cutoff_date => $::form->{cutoff_date_as_date},
+ chargenumber => $::form->{chargenumber},
+ bestbefore => $::form->{bestbefore});
+ if (scalar @$already_counted) {
+ my $reply = $self->js->dialog->open({
+ html => $self->render('inventory/stocktaking/_already_counted_dialog',
+ { output => 0 },
+ already_counted => $already_counted,
+ stocked_qty => $stocked_qty,
+ stocked_qty_in_form_units => $stocked_qty_in_form_units),
+ id => 'already_counted_dialog',
+ dialog => {
+ title => t8('Already counted'),
+ },
+ })->render;
+
+ return $reply;
+ }
+ }
+
+ # - target_qty is in units given in form ($self->unit)
+ # - WH->transfer expects qtys in given unit (here: unit from form (unit -> $self->unit))
+ # Therefore use stocked_qty in form units for calculation.
+ my $qty = $target_qty - $stocked_qty_in_form_units;
+ my $src_or_dst = $qty < 0? 'src' : 'dst';
+ $qty = abs($qty);
+
+ my $transfer_error;
+ # do stock
+ $::form->throw_on_error(sub {
+ eval {
+ WH->transfer({
+ parts => $self->part,
+ $src_or_dst.'_bin' => $self->bin,
+ $src_or_dst.'_wh' => $self->warehouse,
+ qty => $qty,
+ unit => $self->unit,
+ transfer_type => 'stocktaking',
+ chargenumber => $::form->{chargenumber},
+ bestbefore => $::form->{bestbefore},
+ ean => $::form->{ean},
+ comment => $::form->{comment},
+ record_stocktaking => 1,
+ stocktaking_qty => $target_qty,
+ stocktaking_cutoff_date => $::form->{cutoff_date_as_date},
+ });
+ 1;
+ } or do { $transfer_error = $EVAL_ERROR->error; }
+ });
+
+ return $self->js->flash('error', $transfer_error)->render()
+ if $transfer_error;
+
+ flash_later('info', $::locale->text('Part successful counted'));
+ $self->redirect_to(action => 'stocktaking',
+ warehouse_id => $self->warehouse->id,
+ bin_id => $self->bin->id,
+ cutoff_date_as_date => $self->stocktaking_cutoff_date->to_kivitendo);
+}
+
+sub action_reload_stocktaking_history {
+ my ($self) = @_;
+
+ $::form->{filter}{'cutoff_date:date'} = $self->stocktaking_cutoff_date->to_kivitendo;
+ $::form->{filter}{'employee_id'} = SL::DB::Manager::Employee->current->id;
+
+ $self->prepare_stocktaking_report;
+ $self->report_generator_list_objects(report => $self->{report}, objects => $self->stocktaking_models->get, layout => 0, header => 0);
+}
+
+sub action_stocktaking_part_changed {
+ my ($self) = @_;
+
+ $self->js
+ ->replaceWith('#unit_id', $self->build_unit_select)
+ ->focus('#target_qty')
+ ->render;
+}
+
+sub action_stocktaking_journal {
+ my ($self) = @_;
+
+ $self->prepare_stocktaking_report(full => 1);
+ $self->report_generator_list_objects(report => $self->{report}, objects => $self->stocktaking_models->get);
+}
+
+sub action_stocktaking_get_warn_qty_threshold {
+ my ($self) = @_;
+
+ return $_[0]->render(\ !!0, { type => 'text' }) if !$::form->{part_id};
+ return $_[0]->render(\ !!0, { type => 'text' }) if $::form->{target_qty} eq '';
+ return $_[0]->render(\ !!0, { type => 'text' }) if 0 == $::instance_conf->get_stocktaking_qty_threshold;
+
+ my $target_qty = $::form->parse_amount(\%::myconfig, $::form->{target_qty});
+ my $stocked_qty = _get_stocked_qty($self->part,
+ warehouse_id => $self->warehouse->id,
+ bin_id => $self->bin->id,
+ chargenumber => $::form->{chargenumber},
+ bestbefore => $::form->{bestbefore},);
+ my $stocked_qty_in_form_units = $self->part->unit_obj->convert_to($stocked_qty, $self->unit);
+ my $qty = $target_qty - $stocked_qty_in_form_units;
+ $qty = abs($qty);
+
+ my $warn;
+ if ($qty > $::instance_conf->get_stocktaking_qty_threshold) {
+ $warn = t8('The target quantity of #1 differs more than the threshold quantity of #2.',
+ $::form->{target_qty} . " " . $self->unit->name,
+ $::form->format_amount(\%::myconfig, $::instance_conf->get_stocktaking_qty_threshold, 2));
+ $warn .= "\n";
+ $warn .= t8('Choose "continue" if you want to use this value. Choose "cancel" otherwise.');
+ }
+ return $_[0]->render(\ $warn, { type => 'text' });
+}
+