Revision 21437d97
Von Bernd Bleßmann vor 8 Monaten hinzugefügt
SL/Controller/StockCounting.pm | ||
---|---|---|
use SL::DB::StockCounting;
|
||
use SL::DB::StockCountingItem;
|
||
|
||
use SL::Helper::Flash qw(flash);
|
||
use SL::Helper::Number qw(_format_total);
|
||
use SL::Locale::String qw(t8);
|
||
use SL::ReportGenerator;
|
||
... | ... | |
sub action_select_counting {
|
||
my ($self) = @_;
|
||
|
||
if (!$::request->is_mobile) {
|
||
$self->setup_select_counting_action_bar;
|
||
}
|
||
|
||
$self->render('stock_counting/select_counting');
|
||
}
|
||
|
||
sub action_start_counting {
|
||
my ($self) = @_;
|
||
|
||
if (!$::request->is_mobile) {
|
||
$self->setup_count_action_bar;
|
||
}
|
||
|
||
$self->render('stock_counting/count');
|
||
}
|
||
|
||
sub action_count {
|
||
my ($self) = @_;
|
||
|
||
if (!$::request->is_mobile) {
|
||
$self->setup_count_action_bar;
|
||
}
|
||
|
||
my @errors;
|
||
push @errors, t8('EAN is missing') if !$::form->{ean};
|
||
|
||
return $self->render('stock_counting/count', errors => \@errors) if @errors;
|
||
return $self->render_count_error(\@errors) if @errors;
|
||
|
||
my $parts = SL::DB::Manager::Part->get_all(where => [ean => $::form->{ean},
|
||
or => [obsolete => 0, obsolete => undef]]);
|
||
push @errors, t8 ('Part not found') if scalar(@$parts) == 0;
|
||
push @errors, t8 ('Part is ambiguous') if scalar(@$parts) > 1;
|
||
|
||
return $self->render('stock_counting/count', errors => \@errors) if @errors;
|
||
return $self->render_count_error(\@errors) if @errors;
|
||
|
||
$self->stock_counting_item->part($parts->[0]);
|
||
|
||
my @validation_errors = $self->stock_counting_item->validate;
|
||
push @errors, @validation_errors if @validation_errors;
|
||
|
||
return $self->render('stock_counting/count', errors => \@errors) if @errors;
|
||
return $self->render_count_error(\@errors) if @errors;
|
||
|
||
$self->stock_counting_item->qty(1);
|
||
$self->stock_counting_item->save;
|
||
|
||
$self->render('stock_counting/count', successfully_counted => 1);
|
||
if ($::request->is_mobile) {
|
||
$self->render('stock_counting/count', successfully_counted => 1);
|
||
} else {
|
||
flash('info', t8('Part successfully counted'));
|
||
$self->render('stock_counting/count');
|
||
}
|
||
}
|
||
|
||
sub action_list {
|
||
... | ... | |
$_->{stocked} = $_->part->get_stock(bin_id => $_->bin_id) for @$objects;
|
||
}
|
||
|
||
sub render_count_error {
|
||
my ($self, $errors) = @_;
|
||
|
||
if ($::request->is_mobile) {
|
||
$self->render('stock_counting/count', errors => $errors);
|
||
} else {
|
||
flash('error', @{$errors || [] });
|
||
$self->render('stock_counting/count');
|
||
}
|
||
}
|
||
|
||
sub setup_select_counting_action_bar {
|
||
my ($self) = @_;
|
||
|
||
for my $bar ($::request->layout->get('actionbar')) {
|
||
$bar->add(
|
||
action => [
|
||
t8('Start Counting'),
|
||
submit => [ '#count_form', { action => 'StockCounting/start_counting' } ],
|
||
accesskey => 'enter',
|
||
],
|
||
);
|
||
}
|
||
}
|
||
|
||
sub setup_count_action_bar {
|
||
my ($self) = @_;
|
||
for my $bar ($::request->layout->get('actionbar')) {
|
||
$bar->add(
|
||
action => [
|
||
t8('Do count'),
|
||
checks => [ ['kivi.validate_form', '#count_form'] ],
|
||
submit => [ '#count_form', { action => 'StockCounting/count' } ],
|
||
accesskey => 'enter',
|
||
],
|
||
);
|
||
}
|
||
}
|
||
|
||
1;
|
SL/Presenter/Warehouse.pm | ||
---|---|---|
: $with_empty ? undef
|
||
: $all_warehouses->[0]->bins_sorted_naturally;
|
||
|
||
my $data_validate = delete $attributes{'data-validate'};
|
||
my %div_attributes = (
|
||
name => $div_name,
|
||
id => $div_id,
|
||
... | ... | |
onchange => 'kivi.Warehouse.wh_changed(this);',
|
||
'data-bin-dom-name' => $bin_name,
|
||
'data-bin-dom-id' => $bin_id,
|
||
('data-validate' => $data_validate)x!!$data_validate,
|
||
%attributes
|
||
);
|
||
|
||
my %bin_attributes = (
|
||
name => $bin_name,
|
||
id => $bin_id,
|
||
default => $bin_default,
|
||
title_key => 'description',
|
||
name => $bin_name,
|
||
id => $bin_id,
|
||
default => $bin_default,
|
||
title_key => 'description',
|
||
('data-validate' => $data_validate)x!!$data_validate,
|
||
%attributes
|
||
);
|
||
|
menus/user/00-erp.yaml | ||
---|---|---|
access: warehouse_management
|
||
params:
|
||
action: Inventory/stocktaking
|
||
- parent: warehouse
|
||
id: warehouse_stock_counting
|
||
name: Stock Counting
|
||
order: 470
|
||
access: warehouse_management
|
||
params:
|
||
action: StockCounting/select_counting
|
||
- parent: warehouse
|
||
id: warehouse_stock_counting_reconciliation
|
||
name: Stock Counting Reconciliations
|
templates/design40_webpages/stock_counting/count.html | ||
---|---|---|
[%- USE T8 %]
|
||
[%- USE LxERP %]
|
||
[%- USE P %]
|
||
|
||
[%- INCLUDE 'common/flash.html' %]
|
||
|
||
<h1>[% 'Stock Counting' | $T8 %]</h1>
|
||
|
||
<div class="wrapper">
|
||
<table class='tbl-horizontal'>
|
||
<tbody>
|
||
<tr>
|
||
<th>[% 'Stock Counting' | $T8 %]</th>
|
||
<td><span class="data">[% SELF.stock_counting_item.counting.name %]</span></td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% 'Description' | $T8 %]</th>
|
||
<td><span class="data">[% SELF.stock_counting_item.counting.description %]</span></td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% 'Part' | $T8 %]</th>
|
||
<td><span class="data">[% SELF.stock_counting_item.counting.part.displayable_name %]</span></td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% 'Partsgroup' | $T8 %]</th>
|
||
<td><span class="data">[% SELF.stock_counting_item.counting.partsgroup.displayable_name %]</span></td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% 'Vendor' | $T8 %]</th>
|
||
<td><span class="data">[% SELF.stock_counting_item.counting.vendor.displayable_name %]</span></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="wrapper">
|
||
<form method="post" name="count_form" id="count_form" action="controller.pl">
|
||
[% P.hidden_tag('stock_counting_item.counting_id', SELF.stock_counting_item.counting_id) %]
|
||
<table class='tbl-horizontal'>
|
||
<tbody>
|
||
<tr>
|
||
<th>[% 'Bin' | $T8 %]</th>
|
||
<td>
|
||
[% IF SELF.stock_counting_item.counting.bin_id %]
|
||
<span class="data">[% SELF.stock_counting_item.counting.bin.full_description %]</span>
|
||
[% P.hidden_tag('stock_counting_item.bin_id', SELF.stock_counting_item.counting.bin_id) %]
|
||
[% ELSE %]
|
||
[% P.warehouse.wh_bin_select('dummy_wh', bin_name='stock_counting_item.bin_id', with_empty=1, 'data-validate'='required') %]
|
||
[% END %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% 'EAN' | $T8 %]</th>
|
||
<td>[% P.input_tag('ean', '', placeholder=last_ean || LxERP.t8('EAN'), 'data-validate'='required') %]</td>
|
||
</tr>
|
||
</table>
|
||
</form>
|
||
</div>
|
templates/design40_webpages/stock_counting/select_counting.html | ||
---|---|---|
[%- USE T8 %]
|
||
[%- USE LxERP %]
|
||
[%- USE P %]
|
||
|
||
<h1>[% 'Select Stock Counting' | $T8 %]</h1>
|
||
|
||
<div class="wrapper">
|
||
<form method="post" id="count_form" action="controller.pl">
|
||
[% P.select_tag('stock_counting_item.counting_id', SELF.countings, title_key='name') %]
|
||
</form>
|
||
</div>
|
templates/webpages/stock_counting/count.html | ||
---|---|---|
[%- USE T8 %]
|
||
[%- USE LxERP %]
|
||
[%- USE P %]
|
||
|
||
[%- INCLUDE 'common/flash.html' %]
|
||
|
||
<h1>[% 'Stock Counting' | $T8 %]</h1>
|
||
|
||
<table>
|
||
<tbody>
|
||
<tr>
|
||
<th align="right">[% 'Stock Counting' | $T8 %]</th>
|
||
<td>[% SELF.stock_counting_item.counting.name %]</td>
|
||
</tr>
|
||
<tr>
|
||
<th align="right">[% 'Description' | $T8 %]</th>
|
||
<td>[% SELF.stock_counting_item.counting.description %]</td>
|
||
</tr>
|
||
<tr>
|
||
<th align="right">[% 'Part' | $T8 %]</th>
|
||
<td>[% SELF.stock_counting_item.counting.part.displayable_name %]</td>
|
||
</tr>
|
||
<tr>
|
||
<th align="right">[% 'Partsgroup' | $T8 %]</th>
|
||
<td>[% SELF.stock_counting_item.counting.partsgroup.displayable_name %]</td>
|
||
</tr>
|
||
<tr>
|
||
<th align="right">[% 'Vendor' | $T8 %]</th>
|
||
<td>[% SELF.stock_counting_item.counting.vendor.displayable_name %]</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<form method="post" name="count_form" id="count_form" action="controller.pl">
|
||
[% P.hidden_tag('stock_counting_item.counting_id', SELF.stock_counting_item.counting_id) %]
|
||
<table>
|
||
<tbody>
|
||
<tr>
|
||
<th align="right">[% 'Bin' | $T8 %]</th>
|
||
<td>
|
||
[% IF SELF.stock_counting_item.counting.bin_id %]
|
||
[% SELF.stock_counting_item.counting.bin.full_description %]
|
||
[% P.hidden_tag('stock_counting_item.bin_id', SELF.stock_counting_item.counting.bin_id) %]
|
||
[% ELSE %]
|
||
[% P.warehouse.wh_bin_select('dummy_wh', bin_name='stock_counting_item.bin_id', with_empty=1, 'data-validate'='required') %]
|
||
[% END %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th align="right">[% 'EAN' | $T8 %]</th>
|
||
<td>[% P.input_tag('ean', '', placeholder=last_ean || LxERP.t8('EAN'), 'data-validate'='required') %]</td>
|
||
</tr>
|
||
</table>
|
||
</form>
|
templates/webpages/stock_counting/select_counting.html | ||
---|---|---|
[%- USE T8 %]
|
||
[%- USE LxERP %]
|
||
[%- USE P %]
|
||
|
||
<h1>[% 'Select Stock Counting' | $T8 %]</h1>
|
||
|
||
<form method="post" id="count_form" action="controller.pl">
|
||
[% P.select_tag('stock_counting_item.counting_id', SELF.countings, title_key='name') %]
|
||
</form>
|
Auch abrufbar als: Unified diff
Zwischeninventur: Zähl-Maske auch für Nicht-Mobil