Revision a0e9a20c
Von Bernd Bleßmann vor 28 Tagen hinzugefügt
SL/Controller/StockCounting.pm | ||
---|---|---|
3 | 3 |
use strict; |
4 | 4 |
use parent qw(SL::Controller::Base); |
5 | 5 |
|
6 |
use POSIX qw(strftime); |
|
7 |
|
|
8 |
use SL::Controller::Helper::GetModels; |
|
9 |
use SL::Controller::Helper::ReportGenerator; |
|
10 |
|
|
6 | 11 |
use SL::DB::Employee; |
7 | 12 |
use SL::DB::StockCounting; |
8 | 13 |
use SL::DB::StockCountingItem; |
9 | 14 |
|
15 |
use SL::Helper::Number qw(_format_total); |
|
10 | 16 |
use SL::Locale::String qw(t8); |
17 |
use SL::ReportGenerator; |
|
11 | 18 |
|
12 | 19 |
use Rose::Object::MakeMethods::Generic( |
13 | 20 |
#scalar => [ qw() ], |
14 |
'scalar --get_set_init' => [ qw(is_developer countings stock_counting_item) ], |
|
21 |
'scalar --get_set_init' => [ qw(is_developer countings stock_counting_item models) ],
|
|
15 | 22 |
); |
16 | 23 |
|
17 | 24 |
# check permissions |
18 | 25 |
__PACKAGE__->run_before(sub { $::auth->assert('warehouse_management'); }); |
19 | 26 |
|
20 | 27 |
# load js |
21 |
__PACKAGE__->run_before(sub { $::request->layout->add_javascripts('kivi.Validator.js', 'kivi.StockCounting.js'); }); |
|
28 |
__PACKAGE__->run_before(sub { $::request->layout->add_javascripts('kivi.Validator.js', 'kivi.StockCounting.js'); }, |
|
29 |
except => [ qw(list) ]); |
|
30 |
|
|
31 |
|
|
32 |
my %sort_columns = ( |
|
33 |
counting => t8('Stock Counting'), |
|
34 |
counted_at => t8('Counted At'), |
|
35 |
qty => t8('Qty'), |
|
36 |
part => t8('Article'), |
|
37 |
bin => t8('Bin'), |
|
38 |
employee => t8('Employee'), |
|
39 |
); |
|
40 |
|
|
22 | 41 |
|
23 | 42 |
################ actions ################# |
24 | 43 |
|
... | ... | |
62 | 81 |
$self->render('stock_counting/count', successfully_counted => 1); |
63 | 82 |
} |
64 | 83 |
|
84 |
sub action_list { |
|
85 |
my ($self, %params) = @_; |
|
86 |
|
|
87 |
$self->make_filter_summary; |
|
88 |
$self->prepare_report; |
|
89 |
|
|
90 |
my $objects = $self->models->get; |
|
91 |
|
|
92 |
if ($::form->{group_counting_items}) { |
|
93 |
my $grouped_objects_by; |
|
94 |
my @grouped_objects; |
|
95 |
foreach my $object (@$objects) { |
|
96 |
my $group_object; |
|
97 |
if (!$grouped_objects_by->{$object->counting_id}->{$object->part_id}->{$object->bin_id}) { |
|
98 |
$group_object = SL::DB::StockCountingItem->new( |
|
99 |
counting => $object->counting, part => $object->part, bin => $object->bin, qty => 0); |
|
100 |
push @grouped_objects, $group_object; |
|
101 |
$grouped_objects_by->{$object->counting_id}->{$object->part_id}->{$object->bin_id} = $group_object; |
|
102 |
|
|
103 |
} else { |
|
104 |
$group_object = $grouped_objects_by->{$object->counting_id}->{$object->part_id}->{$object->bin_id} |
|
105 |
} |
|
106 |
|
|
107 |
$group_object->id($group_object->id ? ($group_object->id . ',' . $object->id) : $object->id); |
|
108 |
$group_object->qty($group_object->qty + $object->qty); |
|
109 |
} |
|
110 |
|
|
111 |
$objects = \@grouped_objects; |
|
112 |
} |
|
113 |
|
|
114 |
$self->get_stocked($objects); |
|
115 |
|
|
116 |
$self->setup_list_action_bar; |
|
117 |
$self->report_generator_list_objects(report => $self->{report}, objects => $objects); |
|
118 |
} |
|
119 |
|
|
65 | 120 |
sub init_is_developer { |
66 | 121 |
!!$::auth->assert('developer', 'may_fail') |
67 | 122 |
} |
... | ... | |
75 | 130 |
employee => SL::DB::Manager::Employee->current); |
76 | 131 |
} |
77 | 132 |
|
133 |
sub init_models { |
|
134 |
my ($self) = @_; |
|
135 |
|
|
136 |
SL::Controller::Helper::GetModels->new( |
|
137 |
controller => $_[0], |
|
138 |
model => 'StockCountingItem', |
|
139 |
sorted => \%sort_columns, |
|
140 |
disable_plugin => 'paginated', |
|
141 |
with_objects => [ 'counting', 'employee', 'part' ], |
|
142 |
); |
|
143 |
} |
|
144 |
|
|
145 |
sub prepare_report { |
|
146 |
my ($self) = @_; |
|
147 |
|
|
148 |
my $report = SL::ReportGenerator->new(\%::myconfig, $::form); |
|
149 |
$self->{report} = $report; |
|
150 |
|
|
151 |
my @columns = $::form->{group_counting_items} ? qw(counting part bin qty stocked) |
|
152 |
: qw(counting counted_at part bin qty stocked employee); |
|
153 |
|
|
154 |
my %column_defs = ( |
|
155 |
counting => { text => t8('Stock Counting'), sub => sub { $_[0]->counting->name }, }, |
|
156 |
counted_at => { text => t8('Counted At'), sub => sub { $_[0]->counted_at_as_timestamp }, }, |
|
157 |
qty => { text => t8('Qty'), sub => sub { $_[0]->qty_as_number }, align => 'right' }, |
|
158 |
part => { text => t8('Article'), sub => sub { $_[0]->part && $_[0]->part->displayable_name } }, |
|
159 |
bin => { text => t8('Bin'), sub => sub { $_[0]->bin->full_description } }, |
|
160 |
employee => { text => t8('Employee'), sub => sub { $_[0]->employee ? $_[0]->employee->safe_name : '---'} }, |
|
161 |
stocked => { text => t8('Stocked Qty'), sub => sub { _format_total($_[0]->{stocked}) }, align => 'right'}, |
|
162 |
); |
|
163 |
|
|
164 |
# remove columns from defs which are not in @columns |
|
165 |
foreach my $column (keys %column_defs) { |
|
166 |
delete $column_defs{$column} if !grep { $column eq $_ } @columns; |
|
167 |
} |
|
168 |
|
|
169 |
my $title = t8('Stock Counting Items'); |
|
170 |
$report->{title} = $title; # for browser titlebar (title-tag) |
|
171 |
|
|
172 |
$report->set_options( |
|
173 |
controller_class => 'StockCountingItem', |
|
174 |
std_column_visibility => 1, |
|
175 |
output_format => 'HTML', |
|
176 |
title => $title, # for heading |
|
177 |
allow_pdf_export => 1, |
|
178 |
allow_csv_export => 1, |
|
179 |
); |
|
180 |
|
|
181 |
$report->set_columns(%column_defs); |
|
182 |
$report->set_column_order(@columns); |
|
183 |
$report->set_export_options(qw(list filter group_counting_items)); |
|
184 |
$report->set_options_from_form; |
|
185 |
|
|
186 |
$self->models->disable_plugin('paginated') if $report->{options}{output_format} =~ /^(pdf|csv)$/i; |
|
187 |
$self->models->add_additional_url_params(filter => $::form->{filter}, group_counting_items => $::form->{group_counting_items}); |
|
188 |
$self->models->finalize; |
|
189 |
$self->models->set_report_generator_sort_options(report => $report, sortable_columns => [keys %sort_columns]); |
|
190 |
|
|
191 |
$report->set_options( |
|
192 |
raw_top_info_text => $self->render('stock_counting/report_top', { output => 0 }), |
|
193 |
raw_bottom_info_text => $self->render('stock_counting/report_bottom', { output => 0 }, models => $self->models), |
|
194 |
attachment_basename => t8('stock_countings') . strftime('_%Y%m%d', localtime time), |
|
195 |
); |
|
196 |
} |
|
197 |
|
|
198 |
sub make_filter_summary { |
|
199 |
my ($self) = @_; |
|
200 |
|
|
201 |
my @filter_strings; |
|
202 |
|
|
203 |
push @filter_strings, t8('Group Counting Items') if $::form->{group_counting_items}; |
|
204 |
|
|
205 |
my $filter = $::form->{filter} || {}; |
|
206 |
|
|
207 |
my $counting = $filter->{counting_id} ? SL::DB::StockCounting->new(id => $filter->{counting_id})->load->name : ''; |
|
208 |
|
|
209 |
my @filters = ( |
|
210 |
[ $counting, t8('Stock Counting') ], |
|
211 |
); |
|
212 |
|
|
213 |
for (@filters) { |
|
214 |
push @filter_strings, "$_->[1]: $_->[0]" if $_->[0]; |
|
215 |
} |
|
216 |
|
|
217 |
$self->{filter_summary} = join ', ', @filter_strings; |
|
218 |
} |
|
219 |
|
|
220 |
sub setup_list_action_bar { |
|
221 |
my ($self) = @_; |
|
222 |
|
|
223 |
for my $bar ($::request->layout->get('actionbar')) { |
|
224 |
$bar->add( |
|
225 |
action => [ |
|
226 |
t8('Update'), |
|
227 |
submit => [ '#filter_form', { action => 'StockCounting/list' } ], |
|
228 |
accesskey => 'enter', |
|
229 |
], |
|
230 |
); |
|
231 |
} |
|
232 |
} |
|
233 |
|
|
234 |
sub get_stocked { |
|
235 |
my ($self, $objects) = @_; |
|
236 |
|
|
237 |
$_->{stocked} = $_->part->get_stock(bin_id => $_->bin_id) for @$objects; |
|
238 |
} |
|
239 |
|
|
78 | 240 |
1; |
Auch abrufbar als: Unified diff
S:C:StockCounting: Bericht für Zählungen