Revision 34035b33
Von Martin Helmling martin.helmling@octosoft.eu vor etwa 8 Jahren hinzugefügt
SL/Controller/Inventory.pm | ||
---|---|---|
2 | 2 |
|
3 | 3 |
use strict; |
4 | 4 |
use warnings; |
5 |
use POSIX qw(strftime); |
|
5 | 6 |
|
6 | 7 |
use parent qw(SL::Controller::Base); |
7 | 8 |
|
... | ... | |
10 | 11 |
use SL::DB::Warehouse; |
11 | 12 |
use SL::DB::Unit; |
12 | 13 |
use SL::WH; |
14 |
use SL::ReportGenerator; |
|
13 | 15 |
use SL::Locale::String qw(t8); |
14 | 16 |
use SL::Presenter; |
15 | 17 |
use SL::DBUtils; |
16 | 18 |
use SL::Helper::Flash; |
19 |
use SL::Controller::Helper::ReportGenerator; |
|
17 | 20 |
|
18 | 21 |
use English qw(-no_match_vars); |
19 | 22 |
|
... | ... | |
30 | 33 |
__PACKAGE__->run_before('load_bin_from_form', only => [ qw(stock_in stock) ]); |
31 | 34 |
__PACKAGE__->run_before('set_target_from_part', only => [ qw(part_changed) ]); |
32 | 35 |
__PACKAGE__->run_before('mini_stock', only => [ qw(stock_in mini_stock) ]); |
33 |
__PACKAGE__->run_before('sanitize_target', only => [ qw(stock_in warehouse_changed part_changed) ]); |
|
36 |
__PACKAGE__->run_before('sanitize_target', only => [ qw(stock_usage stock_in warehouse_changed part_changed) ]);
|
|
34 | 37 |
__PACKAGE__->run_before('set_layout'); |
35 | 38 |
|
36 | 39 |
sub action_stock_in { |
... | ... | |
44 | 47 |
$self->render('inventory/warehouse_selection_stock', title => $::form->{title}, TRANSFER_TYPES => $transfer_types ); |
45 | 48 |
} |
46 | 49 |
|
50 |
sub action_stock_usage { |
|
51 |
my ($self) = @_; |
|
52 |
|
|
53 |
$::form->{title} = t8('UsageE'); |
|
54 |
|
|
55 |
$::form->get_lists('warehouses' => { 'key' => 'WAREHOUSES', |
|
56 |
'bins' => 'BINS', }); |
|
57 |
$::request->layout->use_javascript("${_}.js") for qw(kivi.PartsWarehouse); |
|
58 |
|
|
59 |
$self->render('inventory/warehouse_usage', |
|
60 |
title => $::form->{title}, |
|
61 |
year => DateTime->today->year, |
|
62 |
# PARTSCLASSIFICATIONS => SL::DB:Manager::PartsClassification->get_all_classifications_by_name() , |
|
63 |
WAREHOUSES => $::form->{WAREHOUSES}, |
|
64 |
WAREHOUSE_FILTER => 1, |
|
65 |
warehouse_id => 0, |
|
66 |
bin_id => 0 |
|
67 |
); |
|
68 |
|
|
69 |
} |
|
70 |
|
|
71 |
sub getnumcolumns { |
|
72 |
my ($self) = @_; |
|
73 |
return qw(stock incorrection found insum back outcorrection disposed |
|
74 |
missing shipped used outsum consumed averconsumed); |
|
75 |
} |
|
76 |
|
|
77 |
sub action_usage { |
|
78 |
my ($self) = @_; |
|
79 |
|
|
80 |
$main::lxdebug->enter_sub(); |
|
81 |
|
|
82 |
my $form = $main::form; |
|
83 |
my %myconfig = %main::myconfig; |
|
84 |
my $locale = $main::locale; |
|
85 |
|
|
86 |
$form->{title} = t8('UsageE'); |
|
87 |
$form->{report_generator_output_format} = 'HTML' if !$form->{report_generator_output_format}; |
|
88 |
|
|
89 |
my $report = SL::ReportGenerator->new(\%myconfig, $form); |
|
90 |
|
|
91 |
my @columns = qw(partnumber partdescription); |
|
92 |
|
|
93 |
push @columns , qw(ptype unit) if $form->{report_generator_output_format} eq 'HTML'; |
|
94 |
|
|
95 |
my @numcolumns = qw(stock incorrection found insum back outcorrection disposed |
|
96 |
missing shipped used outsum consumed averconsumed); |
|
97 |
|
|
98 |
push @columns , $self->getnumcolumns(); |
|
99 |
|
|
100 |
my @hidden_variables = qw(reporttype year duetyp fromdate todate |
|
101 |
warehouse_id bin_id partnumber description bestbefore chargenumber partstypes_id); |
|
102 |
my %column_defs = ( |
|
103 |
'partnumber' => { 'text' => $locale->text('Part Number'), }, |
|
104 |
# 'partclass' => { 'text' => $locale->text('Part Classification'), }, |
|
105 |
'partdescription' => { 'text' => $locale->text('Part_br_Description'), }, |
|
106 |
'unit' => { 'text' => $locale->text('Unit'), }, |
|
107 |
'stock' => { 'text' => $locale->text('stock_br'), }, |
|
108 |
'incorrection' => { 'text' => $locale->text('correction_br'), }, |
|
109 |
'found' => { 'text' => $locale->text('found_br'), }, |
|
110 |
'insum' => { 'text' => $locale->text('sum'), }, |
|
111 |
'back' => { 'text' => $locale->text('back_br'), }, |
|
112 |
'outcorrection' => { 'text' => $locale->text('correction_br'), }, |
|
113 |
'disposed' => { 'text' => $locale->text('disposed_br'), }, |
|
114 |
'missing' => { 'text' => $locale->text('missing_br'), }, |
|
115 |
'shipped' => { 'text' => $locale->text('shipped_br'), }, |
|
116 |
'used' => { 'text' => $locale->text('used_br'), }, |
|
117 |
'outsum' => { 'text' => $locale->text('sum'), }, |
|
118 |
'consumed' => { 'text' => $locale->text('consumed'), }, |
|
119 |
'averconsumed' => { 'text' => $locale->text('averconsumed_br'), }, |
|
120 |
); |
|
121 |
|
|
122 |
|
|
123 |
map { $column_defs{$_}->{visible} = 1 } @columns; |
|
124 |
#map { $column_defs{$_}->{visible} = $form->{"l_${_}"} ? 1 : 0 } @columns; |
|
125 |
map { $column_defs{$_}->{align} = 'right' } @numcolumns; |
|
126 |
|
|
127 |
my @custom_headers = (); |
|
128 |
# Zeile 1: |
|
129 |
push @custom_headers, [ |
|
130 |
{ 'text' => $locale->text('Part'), |
|
131 |
'colspan' => ($form->{report_generator_output_format} eq 'HTML'?4:2), 'align' => 'center'}, |
|
132 |
{ 'text' => $locale->text('Into bin'), 'colspan' => 4, 'align' => 'center'}, |
|
133 |
{ 'text' => $locale->text('From bin'), 'colspan' => 7, 'align' => 'center'}, |
|
134 |
{ 'text' => $locale->text('UsageWithout'), 'colspan' => 2, 'align' => 'center'}, |
|
135 |
]; |
|
136 |
|
|
137 |
# Zeile 2: |
|
138 |
my @line_2 = (); |
|
139 |
map { push @line_2 , $column_defs{$_} } @columns; |
|
140 |
push @custom_headers, [ @line_2 ]; |
|
141 |
|
|
142 |
$report->set_custom_headers(@custom_headers); |
|
143 |
$report->set_columns( %column_defs ); |
|
144 |
$report->set_column_order(@columns); |
|
145 |
|
|
146 |
$report->set_export_options('usage', @hidden_variables ); |
|
147 |
|
|
148 |
$report->set_sort_indicator($form->{sort}, $form->{order}); |
|
149 |
$report->set_options('output_format' => 'HTML', |
|
150 |
'controller_class' => 'Inventory', |
|
151 |
'title' => $form->{title}, |
|
152 |
# 'html_template' => 'inventory/usage_report', |
|
153 |
'attachment_basename' => strftime($locale->text('warehouse_usage_list') . '_%Y%m%d', localtime time)); |
|
154 |
$report->set_options_from_form; |
|
155 |
|
|
156 |
my %searchparams ; |
|
157 |
# form vars |
|
158 |
# reporttype = custom |
|
159 |
# year = 2014 |
|
160 |
# duetyp = 7 |
|
161 |
|
|
162 |
my $start = DateTime->now_local; |
|
163 |
my $end = DateTime->now_local; |
|
164 |
my $actualepoch = $end->epoch(); |
|
165 |
my $days = 365; |
|
166 |
my $mdays=30; |
|
167 |
$searchparams{reporttype} = $form->{reporttype}; |
|
168 |
if ($form->{reporttype} eq "custom") { |
|
169 |
my $smon = 1; |
|
170 |
my $emon = 12; |
|
171 |
my $sday = 1; |
|
172 |
my $eday = 31; |
|
173 |
#forgotten the year --> thisyear |
|
174 |
if ($form->{year} !~ m/^\d\d\d\d$/) { |
|
175 |
$locale->date(\%myconfig, $form->current_date(\%myconfig), 0) =~ |
|
176 |
/(\d\d\d\d)/; |
|
177 |
$form->{year} = $1; |
|
178 |
} |
|
179 |
my $leapday = ($form->{year} % 4 == 0) ? 1:0; |
|
180 |
#yearly report |
|
181 |
if ($form->{duetyp} eq "13") { |
|
182 |
$days += $leapday; |
|
183 |
} |
|
184 |
|
|
185 |
#Quater reports |
|
186 |
if ($form->{duetyp} eq "A") { |
|
187 |
$emon = 3; |
|
188 |
$days = 90 + $leapday; |
|
189 |
} |
|
190 |
if ($form->{duetyp} eq "B") { |
|
191 |
$smon = 4; |
|
192 |
$emon = 6; |
|
193 |
$eday = 30; |
|
194 |
$days = 91; |
|
195 |
} |
|
196 |
if ($form->{duetyp} eq "C") { |
|
197 |
$smon = 7; |
|
198 |
$emon = 9; |
|
199 |
$eday = 30; |
|
200 |
$days = 92; |
|
201 |
} |
|
202 |
if ($form->{duetyp} eq "D") { |
|
203 |
$smon = 10; |
|
204 |
$days = 92; |
|
205 |
} |
|
206 |
#Monthly reports |
|
207 |
if ($form->{duetyp} eq "1" || $form->{duetyp} eq "3" || $form->{duetyp} eq "5" || |
|
208 |
$form->{duetyp} eq "7" || $form->{duetyp} eq "8" || $form->{duetyp} eq "10" || |
|
209 |
$form->{duetyp} eq "12") { |
|
210 |
$smon = $emon = $form->{duetyp}*1; |
|
211 |
$mdays=$days = 31; |
|
212 |
} |
|
213 |
if ($form->{duetyp} eq "2" || $form->{duetyp} eq "4" || $form->{duetyp} eq "6" || |
|
214 |
$form->{duetyp} eq "9" || $form->{duetyp} eq "11" ) { |
|
215 |
$smon = $emon = $form->{duetyp}*1; |
|
216 |
$eday = 30; |
|
217 |
if ($form->{duetyp} eq "2" ) { |
|
218 |
#this works from 1901 to 2099, 1900 and 2100 fail. |
|
219 |
$eday = ($form->{year} % 4 == 0) ? 29 : 28; |
|
220 |
} |
|
221 |
$mdays=$days = $eday; |
|
222 |
} |
|
223 |
$searchparams{year} = $form->{year}; |
|
224 |
$searchparams{duetyp} = $form->{duetyp}; |
|
225 |
$start->set_month($smon); |
|
226 |
$start->set_day($sday); |
|
227 |
$start->set_year($form->{year}*1); |
|
228 |
$end->set_month($emon); |
|
229 |
$end->set_day($eday); |
|
230 |
$end->set_year($form->{year}*1); |
|
231 |
} else { |
|
232 |
$searchparams{fromdate} = $form->{fromdate}; |
|
233 |
$searchparams{todate} = $form->{todate}; |
|
234 |
# reporttype = free |
|
235 |
# fromdate = 01.01.2014 |
|
236 |
# todate = 31.05.2014 |
|
237 |
my ($yy, $mm, $dd) = $locale->parse_date(\%myconfig,$form->{fromdate}); |
|
238 |
$start->set_year($yy); |
|
239 |
$start->set_month($mm); |
|
240 |
$start->set_day($dd); |
|
241 |
($yy, $mm, $dd) = $locale->parse_date(\%myconfig,$form->{todate}); |
|
242 |
$end->set_year($yy); |
|
243 |
$end->set_month($mm); |
|
244 |
$end->set_day($dd); |
|
245 |
my $dur = $start->delta_md($end); |
|
246 |
$days = $dur->delta_months()*30 + $dur->delta_days() ; |
|
247 |
} |
|
248 |
$start->set_second(0); |
|
249 |
$start->set_minute(0); |
|
250 |
$start->set_hour(0); |
|
251 |
$end->set_second(59); |
|
252 |
$end->set_minute(59); |
|
253 |
$end->set_hour(23); |
|
254 |
if ( $end->epoch() > $actualepoch ) { |
|
255 |
$end = DateTime->now_local; |
|
256 |
my $dur = $start->delta_md($end); |
|
257 |
$days = $dur->delta_months()*30 + $dur->delta_days() ; |
|
258 |
} |
|
259 |
if ( $start->epoch() > $end->epoch() ) { $start = $end;$days = 1;} |
|
260 |
$days = $mdays if $days < $mdays; |
|
261 |
#$main::lxdebug->message(LXDebug->DEBUG2(), "start=".$start->epoch()); |
|
262 |
#$main::lxdebug->message(LXDebug->DEBUG2(), " end=".$end->epoch()); |
|
263 |
#$main::lxdebug->message(LXDebug->DEBUG2(), " days=".$days); |
|
264 |
my @andfilter = (shippingdate => { ge => $start }, shippingdate => { le => $end } ); |
|
265 |
if ( $form->{warehouse_id} ) { |
|
266 |
push @andfilter , ( warehouse_id => $form->{warehouse_id}); |
|
267 |
$searchparams{warehouse_id} = $form->{warehouse_id}; |
|
268 |
if ( $form->{bin_id} ) { |
|
269 |
push @andfilter , ( bin_id => $form->{bin_id}); |
|
270 |
$searchparams{bin_id} = $form->{bin_id}; |
|
271 |
} |
|
272 |
} |
|
273 |
# alias class t2 entspricht parts |
|
274 |
if ( $form->{partnumber} ) { |
|
275 |
push @andfilter , ( 't2.partnumber' => { ilike => '%'. $form->{partnumber} .'%' }); |
|
276 |
$searchparams{partnumber} = $form->{partnumber}; |
|
277 |
} |
|
278 |
if ( $form->{description} ) { |
|
279 |
push @andfilter , ( 't2.description' => { ilike => '%'. $form->{description} .'%' }); |
|
280 |
$searchparams{description} = $form->{description}; |
|
281 |
} |
|
282 |
if ( $form->{bestbefore} ) { |
|
283 |
push @andfilter , ( bestbefore => { eq => $form->{bestbefore} }); |
|
284 |
$searchparams{bestbefore} = $form->{bestbefore}; |
|
285 |
} |
|
286 |
if ( $form->{chargenumber} ) { |
|
287 |
push @andfilter , ( chargenumber => { ilike => '%'.$form->{chargenumber}.'%' }); |
|
288 |
$searchparams{chargenumber} = $form->{chargenumber}; |
|
289 |
} |
|
290 |
if ( $form->{partstypes_id} ) { |
|
291 |
push @andfilter , ( 't2.partstypes_id' => $form->{partstypes_id} ); |
|
292 |
$searchparams{partstypes_id} = $form->{partstypes_id}; |
|
293 |
} |
|
294 |
|
|
295 |
my @filter = (and => [ @andfilter ] ); |
|
296 |
|
|
297 |
my $objs = SL::DB::Manager::Inventory->get_all(with_objects => ['parts'], where => [ @filter ] , sort_by => 'parts.partnumber ASC'); |
|
298 |
#my $objs = SL::DB::Inventory->_get_manager_class->get_all(...); |
|
299 |
|
|
300 |
# manual paginating, yuck |
|
301 |
my $page = $::form->{page} || 1; |
|
302 |
my $pages = {}; |
|
303 |
$pages->{per_page} = $::form->{per_page} || 20; |
|
304 |
my $first_nr = ($page - 1) * $pages->{per_page}; |
|
305 |
my $last_nr = $first_nr + $pages->{per_page}; |
|
306 |
|
|
307 |
my $last_partid = 0; |
|
308 |
my $last_row = { }; |
|
309 |
my $row_ind = 0; |
|
310 |
my $allrows = 0; |
|
311 |
$allrows = 1 if $form->{report_generator_output_format} ne 'HTML' ; |
|
312 |
#$main::lxdebug->message(LXDebug->DEBUG2(), "first_nr=".$first_nr." last_nr=".$last_nr); |
|
313 |
foreach my $entry (@{ $objs } ) { |
|
314 |
if ( $entry->parts_id != $last_partid ) { |
|
315 |
if ( $last_partid > 0 ) { |
|
316 |
if ( $allrows || ($row_ind >= $first_nr && $row_ind < $last_nr )) { |
|
317 |
$self->make_row_result($last_row,$days,$last_partid); |
|
318 |
$report->add_data($last_row); |
|
319 |
} |
|
320 |
$row_ind++ ; |
|
321 |
} |
|
322 |
$last_partid = $entry->parts_id; |
|
323 |
$last_row = { }; |
|
324 |
$last_row->{partnumber}->{data} = $entry->part->partnumber; |
|
325 |
$last_row->{partdescription}->{data} = $entry->part->description; |
|
326 |
$last_row->{unit}->{data} = $entry->part->unit; |
|
327 |
$last_row->{stock}->{data} = 0; |
|
328 |
$last_row->{incorrection}->{data} = 0; |
|
329 |
$last_row->{found}->{data} = 0; |
|
330 |
$last_row->{back}->{data} = 0; |
|
331 |
$last_row->{outcorrection}->{data} = 0; |
|
332 |
$last_row->{disposed}->{data} = 0; |
|
333 |
$last_row->{missing}->{data} = 0; |
|
334 |
$last_row->{shipped}->{data} = 0; |
|
335 |
$last_row->{used}->{data} = 0; |
|
336 |
$last_row->{insum}->{data} = 0; |
|
337 |
$last_row->{outsum}->{data} = 0; |
|
338 |
$last_row->{consumed}->{data} = 0; |
|
339 |
$last_row->{averconsumed}->{data} = 0; |
|
340 |
} |
|
341 |
if ( !$allrows && $row_ind >= $last_nr ) { |
|
342 |
next; |
|
343 |
} |
|
344 |
my $prefix=''; |
|
345 |
if ( $entry->trans_type->description eq 'correction' ) { |
|
346 |
$prefix = $entry->trans_type->direction; |
|
347 |
} |
|
348 |
$last_row->{$prefix.$entry->trans_type->description}->{data} += |
|
349 |
( $entry->trans_type->direction eq 'out' ? -$entry->qty : $entry->qty ); |
|
350 |
} |
|
351 |
if ( $last_partid > 0 && ( $allrows || ($row_ind >= $first_nr && $row_ind < $last_nr ))) { |
|
352 |
$self->make_row_result($last_row,$days,$last_partid); |
|
353 |
$report->add_data($last_row); |
|
354 |
$row_ind++ ; |
|
355 |
} |
|
356 |
my $num_rows = @{ $report->{data} } ; |
|
357 |
#$main::lxdebug->message(LXDebug->DEBUG2(), "count=".$row_ind." rows=".$num_rows); |
|
358 |
|
|
359 |
if ( ! $allrows ) { |
|
360 |
$pages->{max} = SL::DB::Helper::Paginated::ceil($row_ind, $pages->{per_page}) || 1; |
|
361 |
$pages->{page} = $page < 1 ? 1: $page > $pages->{max} ? $pages->{max}: $page; |
|
362 |
$pages->{common} = [ grep { $_->{visible} } @{ SL::DB::Helper::Paginated::make_common_pages($pages->{page}, $pages->{max}) } ]; |
|
363 |
$self->{pages} = $pages; |
|
364 |
$searchparams{action} = "usage"; |
|
365 |
$self->{base_url} = $self->url_for(\%searchparams ); |
|
366 |
#$main::lxdebug->message(LXDebug->DEBUG2(), "page=".$pages->{page}." url=".$self->{base_url}); |
|
367 |
|
|
368 |
$report->set_options('raw_bottom_info_text' => $self->render('inventory/report_bottom', { output => 0 }) ); |
|
369 |
} |
|
370 |
$report->generate_with_headers(); |
|
371 |
|
|
372 |
$main::lxdebug->leave_sub(); |
|
373 |
|
|
374 |
} |
|
375 |
|
|
376 |
sub make_row_result { |
|
377 |
my ($self,$row,$days,$partid) = @_; |
|
378 |
my $form = $main::form; |
|
379 |
my $myconfig = \%main::myconfig; |
|
380 |
|
|
381 |
$row->{insum}->{data} = $row->{stock}->{data} + $row->{incorrection}->{data} + $row->{found}->{data}; |
|
382 |
$row->{outsum}->{data} = $row->{back}->{data} + $row->{outcorrection}->{data} + $row->{disposed}->{data} + |
|
383 |
$row->{missing}->{data} + $row->{shipped}->{data} + $row->{used}->{data}; |
|
384 |
$row->{consumed}->{data} = $row->{outsum}->{data} - |
|
385 |
$row->{outcorrection}->{data} - $row->{incorrection}->{data}; |
|
386 |
$row->{averconsumed}->{data} = $row->{consumed}->{data}*30/$days ; |
|
387 |
map { $row->{$_}->{data} = $form->format_amount($myconfig,$row->{$_}->{data},2); } $self->getnumcolumns(); |
|
388 |
# $row->{partclass}->{data} = ''; |
|
389 |
$row->{partnumber}->{link} = 'ic.pl?action=edit&id='.$partid; |
|
390 |
# $row->{partdescription}->{link} = 'ic.pl?action=edit&id='.$partid; |
|
391 |
} |
|
392 |
|
|
47 | 393 |
sub action_stock { |
48 | 394 |
my ($self) = @_; |
49 | 395 |
|
... | ... | |
153 | 499 |
SL::DB::Manager::Warehouse->get_all(query => [ or => [ invalid => 0, invalid => undef ]]); |
154 | 500 |
} |
155 | 501 |
|
502 |
#sub init_bins { |
|
503 |
# SL::DB::Manager::Bin->get_all(); |
|
504 |
#} |
|
505 |
|
|
156 | 506 |
sub init_units { |
157 | 507 |
SL::DB::Manager::Unit->get_all; |
158 | 508 |
} |
... | ... | |
175 | 525 |
|
176 | 526 |
$self->warehouse($self->warehouses->[0]) if !$self->warehouse || !$self->warehouse->id; |
177 | 527 |
$self->bin ($self->warehouse->bins->[0]) if !$self->bin || !$self->bin->id; |
528 |
# foreach my $warehouse ( $self->warehouses ) { |
|
529 |
# $warehouse->{BINS} = []; |
|
530 |
# foreach my $bin ( $self->bins ) { |
|
531 |
# if ( $bin->warehouse_id == $warehouse->id ) { |
|
532 |
# push @{ $warehouse->{BINS} }, $bin; |
|
533 |
# } |
|
534 |
# } |
|
535 |
# } |
|
178 | 536 |
} |
179 | 537 |
|
180 | 538 |
sub load_part_from_form { |
bin/mozilla/wh.pl | ||
---|---|---|
674 | 674 |
$form->{title} = $locale->text("WHJournal"); |
675 | 675 |
$form->{sort} ||= 'date'; |
676 | 676 |
|
677 |
$form->{report_generator_output_format} = 'HTML' if !$form->{report_generator_output_format}; |
|
678 |
|
|
677 | 679 |
my %filter; |
678 | 680 |
my @columns = qw(trans_id date warehouse_from bin_from warehouse_to bin_to partnumber partdescription chargenumber bestbefore trans_type comment qty employee oe_id projectnumber); |
679 | 681 |
|
... | ... | |
709 | 711 |
'chargenumber' => { 'text' => $locale->text('Charge Number'), }, |
710 | 712 |
'bestbefore' => { 'text' => $locale->text('Best Before'), }, |
711 | 713 |
'qty' => { 'text' => $locale->text('Qty'), }, |
714 |
'unit' => { 'text' => $locale->text('Part Unit'), }, |
|
715 |
'partunit' => { 'text' => $locale->text('Unit'), }, |
|
712 | 716 |
'employee' => { 'text' => $locale->text('Employee'), }, |
713 | 717 |
'projectnumber' => { 'text' => $locale->text('Project Number'), }, |
714 | 718 |
'oe_id' => { 'text' => $locale->text('Document'), }, |
715 | 719 |
); |
716 | 720 |
|
717 | 721 |
my $href = build_std_url('action=generate_journal', grep { $form->{$_} } @hidden_variables); |
718 |
map { $column_defs{$_}->{link} = $href . "&sort=${_}&order=" . Q($_ eq $form->{sort} ? 1 - $form->{order} : $form->{order}) } @columns; |
|
722 |
my $page = $::form->{page} || 1; |
|
723 |
map { $column_defs{$_}->{link} = $href ."&page=".$page. "&sort=${_}&order=" . Q($_ eq $form->{sort} ? 1 - $form->{order} : $form->{order}) } @columns; |
|
719 | 724 |
|
720 | 725 |
my %column_alignment = map { $_ => 'right' } qw(qty); |
721 | 726 |
|
... | ... | |
747 | 752 |
'purchase_invoice' => { script => 'ir', title => $locale->text('Purchase Invoice') }, |
748 | 753 |
); |
749 | 754 |
|
755 |
my $allrows = 0; |
|
756 |
$allrows = 1 if $form->{report_generator_output_format} ne 'HTML' ; |
|
757 |
|
|
758 |
# manual paginating |
|
759 |
my $pages = {}; |
|
760 |
$pages->{per_page} = $::form->{per_page} || 15; |
|
761 |
my $first_nr = ($page - 1) * $pages->{per_page}; |
|
762 |
my $last_nr = $first_nr + $pages->{per_page}; |
|
763 |
my $idx = 0; |
|
764 |
|
|
750 | 765 |
foreach my $entry (@contents) { |
751 | 766 |
$entry->{qty} = $form->format_amount_units('amount' => $entry->{qty}, |
752 | 767 |
'part_unit' => $entry->{partunit}, |
... | ... | |
774 | 789 |
} |
775 | 790 |
} |
776 | 791 |
|
777 |
$report->add_data($row); |
|
792 |
if ( $allrows || ($idx >= $first_nr && $idx < $last_nr )) { |
|
793 |
$report->add_data($row); |
|
794 |
} |
|
795 |
$idx++; |
|
778 | 796 |
} |
779 | 797 |
|
798 |
if ( ! $allrows ) { |
|
799 |
$pages->{max} = SL::DB::Helper::Paginated::ceil($idx, $pages->{per_page}) || 1; |
|
800 |
$pages->{page} = $page < 1 ? 1: $page > $pages->{max} ? $pages->{max}: $page; |
|
801 |
$pages->{common} = [ grep { $_->{visible} } @{ SL::DB::Helper::Paginated::make_common_pages($pages->{page}, $pages->{max}) } ]; |
|
802 |
|
|
803 |
$report->set_options('raw_bottom_info_text' => $form->parse_html_template('common/paginate', |
|
804 |
{ 'pages' => $pages , 'base_url' => $href}) ); |
|
805 |
} |
|
780 | 806 |
$report->generate_with_headers(); |
781 | 807 |
|
782 | 808 |
$main::lxdebug->leave_sub(); |
... | ... | |
822 | 848 |
|
823 | 849 |
$form->{title} = $locale->text("Report about warehouse contents"); |
824 | 850 |
$form->{sort} ||= 'partnumber'; |
851 |
$form->{sort} ||= 'partunit'; |
|
825 | 852 |
my $sort_col = $form->{sort}; |
826 | 853 |
|
827 | 854 |
my %filter; |
828 | 855 |
my @columns = qw(warehousedescription bindescription partnumber partdescription chargenumber bestbefore qty stock_value); |
829 | 856 |
|
830 | 857 |
# filter stuff |
831 |
map { $filter{$_} = $form->{$_} if ($form->{$_}) } qw(warehouse_id bin_id partnumber description chargenumber bestbefore date include_invalid_warehouses); |
|
858 |
map { $filter{$_} = $form->{$_} if ($form->{$_}) } qw(warehouse_id bin_id partstypes_id partnumber description chargenumber bestbefore date include_invalid_warehouses);
|
|
832 | 859 |
|
833 | 860 |
# show filter stuff also in report |
834 | 861 |
my @options; |
... | ... | |
862 | 889 |
|
863 | 890 |
$form->{subtotal} = '' if (!first { $_ eq $sort_col } qw(partnumber partdescription)); |
864 | 891 |
|
892 |
$form->{report_generator_output_format} = 'HTML' if !$form->{report_generator_output_format}; |
|
865 | 893 |
my $report = SL::ReportGenerator->new(\%myconfig, $form); |
866 | 894 |
|
867 | 895 |
my @hidden_variables = map { "l_${_}" } @columns; |
868 |
push @hidden_variables, qw(warehouse_id bin_id partnumber description chargenumber bestbefore qty_op qty qty_unit l_warehousedescription l_bindescription);
|
|
896 |
push @hidden_variables, qw(warehouse_id bin_id partnumber partstypes_id description chargenumber bestbefore qty_op qty qty_unit partunit l_warehousedescription l_bindescription);
|
|
869 | 897 |
push @hidden_variables, qw(include_empty_bins subtotal include_invalid_warehouses date); |
870 | 898 |
|
871 | 899 |
my %column_defs = ( |
... | ... | |
876 | 904 |
'chargenumber' => { 'text' => $locale->text('Charge Number'), }, |
877 | 905 |
'bestbefore' => { 'text' => $locale->text('Best Before'), }, |
878 | 906 |
'qty' => { 'text' => $locale->text('Qty'), }, |
907 |
'partunit' => { 'text' => $locale->text('Unit'), }, |
|
879 | 908 |
'stock_value' => { 'text' => $locale->text('Stock value'), }, |
880 | 909 |
); |
881 | 910 |
|
882 | 911 |
my $href = build_std_url('action=generate_report', grep { $form->{$_} } @hidden_variables); |
883 |
map { $column_defs{$_}->{link} = $href . "&sort=${_}&order=" . Q($_ eq $sort_col ? 1 - $form->{order} : $form->{order}) } @columns; |
|
912 |
my $page = $::form->{page} || 1; |
|
913 |
map { $column_defs{$_}->{link} = $href . "&page=".$page."&sort=${_}&order=" . Q($_ eq $sort_col ? 1 - $form->{order} : $form->{order}) } @columns; |
|
884 | 914 |
|
885 | 915 |
my %column_alignment = map { $_ => 'right' } qw(qty stock_value); |
886 | 916 |
|
... | ... | |
910 | 940 |
|
911 | 941 |
my $total_stock_value = 0; |
912 | 942 |
|
943 |
my $allrows = 0; |
|
944 |
$allrows = 1 if $form->{report_generator_output_format} ne 'HTML' ; |
|
945 |
|
|
946 |
# manual paginating |
|
947 |
my $pages = {}; |
|
948 |
$pages->{per_page} = $::form->{per_page} || 20; |
|
949 |
my $first_nr = ($page - 1) * $pages->{per_page}; |
|
950 |
my $last_nr = $first_nr + $pages->{per_page}; |
|
951 |
|
|
913 | 952 |
foreach my $entry (@contents) { |
914 | 953 |
map { $subtotals{$_} += $entry->{$_} } @subtotals_columns; |
915 | 954 |
$total_stock_value += $entry->{stock_value} * 1; |
916 |
|
|
917 |
$entry->{qty} = $form->format_amount_units('amount' => $entry->{qty}, |
|
918 |
'part_unit' => $entry->{partunit}, |
|
919 |
'conv_units' => 'convertible'); |
|
955 |
$entry->{qty} = $form->format_amount(\%myconfig, $entry->{qty}); |
|
956 |
# $entry->{qty} = $form->format_amount_units('amount' => $entry->{qty},
|
|
957 |
# 'part_unit' => $entry->{partunit},
|
|
958 |
# 'conv_units' => 'convertible');
|
|
920 | 959 |
$entry->{stock_value} = $form->format_amount(\%myconfig, $entry->{stock_value} * 1, 2); |
921 | 960 |
|
922 | 961 |
my $row_set = [ { map { $_ => { 'data' => $entry->{$_}, 'align' => $column_alignment{$_} } } @columns } ]; |
... | ... | |
926 | 965 |
|| ($entry->{$sort_col} ne $contents[$idx + 1]->{$sort_col}))) { |
927 | 966 |
|
928 | 967 |
my $row = { map { $_ => { 'data' => '', 'class' => 'listsubtotal', 'align' => $column_alignment{$_}, } } @columns }; |
929 |
$row->{qty}->{data} = $form->format_amount_units('amount' => $subtotals{qty} * 1, |
|
930 |
'part_unit' => $entry->{partunit}, |
|
931 |
'conv_units' => 'convertible'); |
|
968 |
$row->{qty}->{data} = $form->format_amount(\%myconfig, $subtotals{qty}); |
|
969 |
# $row->{qty}->{data} = $form->format_amount_units('amount' => $subtotals{qty} * 1, |
|
970 |
# 'part_unit' => $entry->{partunit}, |
|
971 |
# 'conv_units' => 'convertible'); |
|
932 | 972 |
$row->{stock_value}->{data} = $form->format_amount(\%myconfig, $subtotals{stock_value} * 1, 2); |
933 | 973 |
|
934 | 974 |
%subtotals = map { $_ => 0 } @subtotals_columns; |
... | ... | |
936 | 976 |
push @{ $row_set }, $row; |
937 | 977 |
} |
938 | 978 |
|
939 |
$report->add_data($row_set); |
|
940 |
|
|
979 |
if ( $allrows || ($idx >= $first_nr && $idx < $last_nr )) { |
|
980 |
$report->add_data($row_set); |
|
981 |
} |
|
941 | 982 |
$idx++; |
942 | 983 |
} |
943 | 984 |
|
doc/changelog | ||
---|---|---|
6 | 6 |
|
7 | 7 |
kleinere neue Features und Detailverbesserungen: |
8 | 8 |
|
9 |
- Weiterer Bericht in der Rubrik Lager: Lagerentnahme |
|
10 |
Gibt eine Statistik über Lagerbewegungen, pro Monat/Quartal/Jahr. |
|
11 |
|
|
9 | 12 |
- Für UStVA Voranmeldung über Elster gibt es die Anbindung über Geierlein (Installation/Config siehe Commit) |
10 | 13 |
|
11 | 14 |
- CSV-Import von Artikel hat nun für existierende Artikel folgende Optionen: |
locale/de/all | ||
---|---|---|
1330 | 1330 |
'Fristsetzung' => 'Fristsetzung', |
1331 | 1331 |
'From' => 'Von', |
1332 | 1332 |
'From Date' => 'Von', |
1333 |
'From bin' => 'Ausgelagert', |
|
1333 | 1334 |
'From this version on a new feature is available.' => 'Ab dieser Version ist ein neues Feature verfügbar.', |
1334 | 1335 |
'From this version on it is necessary to name a default value.' => 'Ab dieser Version benötigt kivitendo eine Standardwährung.', |
1335 | 1336 |
'From this version on the partnumber of services, articles and assemblies have to be unique.' => 'Ab dieser Version müssen Artikelnummern eindeutig vergeben werden.', |
... | ... | |
1494 | 1495 |
'Internal Phone List' => 'Interne Telefonliste', |
1495 | 1496 |
'Internal comment' => 'Interne Bemerkungen', |
1496 | 1497 |
'Internet' => 'Internet', |
1498 |
'Into bin' => 'Eingelagert', |
|
1497 | 1499 |
'Intra-Community supply' => 'Gelangensbestätigung', |
1498 | 1500 |
'Introduction of clients' => 'Einführung von Mandanten', |
1499 | 1501 |
'Inv. Duedate' => 'Rg. Fälligkeit', |
... | ... | |
1985 | 1987 |
'Part' => 'Ware', |
1986 | 1988 |
'Part "#1" has chargenumber or best before date set. So it cannot be transfered automatically.' => 'Bei Artikel "#1" ist eine Chargenummer oder ein Mindesthaltbarkeitsdatum vergeben. Deshalb kann dieser Artikel nicht automatisch ausgelagert werden.', |
1987 | 1989 |
'Part (database ID)' => 'Artikel (Datenbank-ID)', |
1990 |
'Part Classification' => '', |
|
1988 | 1991 |
'Part Description' => 'Artikelbeschreibung', |
1989 | 1992 |
'Part Description missing!' => 'Artikelbezeichnung fehlt!', |
1990 | 1993 |
'Part Notes' => 'Bemerkungen', |
1991 | 1994 |
'Part Number' => 'Artikelnummer', |
1992 | 1995 |
'Part Number missing!' => 'Artikelnummer fehlt!', |
1996 |
'Part Unit' => '', |
|
1993 | 1997 |
'Part picker' => 'Artikelauswahl', |
1998 |
'Part_br_Description' => 'Beschreibung', |
|
1994 | 1999 |
'Partial invoices' => 'Teilrechnungen', |
1995 | 2000 |
'Partnumber' => 'Artikelnummer', |
1996 | 2001 |
'Partnumber must not be set to empty!' => 'Die Artikelnummer darf nicht auf leer geändert werden.', |
... | ... | |
3281 | 3286 |
'Updating the client fields in the database "#1" on host "#2:#3" failed.' => 'Die Aktualisierung der Mandantenfelder in der Datenbank "#1" auf Host "#2:#3" schlug fehl.', |
3282 | 3287 |
'Uploaded at' => 'Hochgeladen um', |
3283 | 3288 |
'Uploaded on #1, size #2 kB' => 'Am #1 hochgeladen, Größe #2 kB', |
3289 |
'UsageE' => 'Lagerentnahme', |
|
3290 |
'UsageWithout' => 'Entnommen (ohne Korr.)', |
|
3284 | 3291 |
'Use As New' => 'Als neu verwenden', |
3285 | 3292 |
'Use Balance Sheet' => 'Bilanz verwenden', |
3286 | 3293 |
'Use Datevautomatik' => 'Datev-Automatik verwenden', |
... | ... | |
3355 | 3362 |
'View/edit all employees sales documents' => 'Bearbeiten/ansehen der Verkaufsdokumente aller Mitarbeiter', |
3356 | 3363 |
'Von Konto: ' => 'von Konto: ', |
3357 | 3364 |
'WHJournal' => 'Lagerbuchungen', |
3365 |
'WHUsage' => 'Lagerentnahme', |
|
3358 | 3366 |
'Warehouse' => 'Lager', |
3359 | 3367 |
'Warehouse (database ID)' => 'Lager (Datenbank-ID)', |
3360 | 3368 |
'Warehouse (name)' => 'Lager (Name)', |
... | ... | |
3472 | 3480 |
'assembly' => 'Erzeugnis', |
3473 | 3481 |
'assembly_list' => 'erzeugnisliste', |
3474 | 3482 |
'averaged values, in invoice mode only useful when filtered by a part' => 'gemittelte Werte, im Rechnungsmodus nur sinnvoll wenn nach Artikel gefiltert wird', |
3483 |
'averconsumed_br' => 'Ø mtl.', |
|
3475 | 3484 |
'back' => 'zurück', |
3485 |
'back_br' => 'Zurk.', |
|
3476 | 3486 |
'balance' => 'Betriebsvermögensvergleich/Bilanzierung', |
3477 | 3487 |
'bank_collection_payment_list_#1' => 'bankeinzugszahlungsliste_#1', |
3478 | 3488 |
'bank_transfer_payment_list_#1' => 'ueberweisungszahlungsliste_#1', |
... | ... | |
3495 | 3505 |
'config/kivitendo.conf: Key "authentication/ldap" is missing.' => 'config/kivitendo.conf: Der Schlüssel "authentication/ldap" fehlt.', |
3496 | 3506 |
'config/kivitendo.conf: Missing parameters in "authentication/database". Required parameters are "host", "db" and "user".' => 'config/kivitendo.conf: Fehlende Parameter in "authentication/database". Benötigte Parameter sind "host", "db" und "user".', |
3497 | 3507 |
'config/kivitendo.conf: Missing parameters in "authentication/ldap". Required parameters are "host", "attribute" and "base_dn".' => 'config/kivitendo.conf: Fehlende Parameter in "authentication/ldap". Benötigt werden "host", "attribute" und "base_dn".', |
3508 |
'consumed' => 'Im Zeitraum', |
|
3498 | 3509 |
'contact_list' => 'ansprechperson_liste', |
3499 | 3510 |
'continue' => 'weiter', |
3500 | 3511 |
'correction' => 'Korrektur', |
3512 |
'correction_br' => 'Korr.', |
|
3501 | 3513 |
'cp_greeting to cp_gender migration' => 'Datenumwandlung von Titel nach Geschlecht (cp_greeting to cp_gender)', |
3502 | 3514 |
'customer' => 'Kunde', |
3503 | 3515 |
'customer_list' => 'kundenliste', |
... | ... | |
3511 | 3523 |
'difference_as_skonto' => 'Differenz als Skonto', |
3512 | 3524 |
'direct debit' => 'Lastschrifteinzug', |
3513 | 3525 |
'disposed' => 'Entsorgung', |
3526 |
'disposed_br' => 'Entsgt.', |
|
3514 | 3527 |
'do not include' => 'Nicht aufnehmen', |
3515 | 3528 |
'done' => 'erledigt', |
3516 | 3529 |
'dunning_list' => 'mahnungsliste', |
... | ... | |
3533 | 3546 |
'for all' => 'für alle', |
3534 | 3547 |
'for date' => 'zum Stichtag', |
3535 | 3548 |
'found' => 'Gefunden', |
3549 |
'found_br' => 'Gef.', |
|
3536 | 3550 |
'from (time)' => 'von', |
3537 | 3551 |
'general_ledger_list' => 'buchungsjournal', |
3538 | 3552 |
'generate cb/ob transactions for selected charts' => 'Buchungen erstellen', |
... | ... | |
3572 | 3586 |
'male' => 'männlich', |
3573 | 3587 |
'mark as paid' => 'als bezahlt markieren', |
3574 | 3588 |
'missing' => 'Fehlbestand', |
3589 |
'missing_br' => 'Fehl.', |
|
3575 | 3590 |
'month' => 'Monatliche Abgabe', |
3576 | 3591 |
'monthly' => 'monatlich', |
3577 | 3592 |
'never' => 'niemals', |
... | ... | |
3650 | 3665 |
'service' => 'Dienstleistung', |
3651 | 3666 |
'service_list' => 'dienstleistungsliste', |
3652 | 3667 |
'shipped' => 'verschickt', |
3668 |
'shipped_br' => 'Verschk.', |
|
3653 | 3669 |
'singular first char' => 'S', |
3654 | 3670 |
'sort items' => 'Positionen sortieren', |
3655 | 3671 |
'stock' => 'Einlagerung', |
3672 |
'stock_br' => 'Eingel.', |
|
3656 | 3673 |
'submit' => 'abschicken', |
3657 | 3674 |
'succeeded' => 'erfolgreich', |
3675 |
'sum' => 'Summe', |
|
3658 | 3676 |
'tax_chartaccno' => 'Automatikkonto', |
3659 | 3677 |
'tax_percent' => 'Prozentsatz', |
3660 | 3678 |
'tax_rate' => 'Prozent', |
... | ... | |
3682 | 3700 |
'use program settings' => 'benutze Programmeinstellungen', |
3683 | 3701 |
'use user config' => 'Verwende Benutzereinstellung', |
3684 | 3702 |
'used' => 'Verbraucht', |
3703 |
'used_br' => 'Verbr.', |
|
3685 | 3704 |
'valid from' => 'Gültig ab', |
3686 | 3705 |
'vendor' => 'Lieferant', |
3687 | 3706 |
'vendor_invoice_list' => 'kreditorenbuchungsliste', |
... | ... | |
3689 | 3708 |
'waiting for job to be started' => 'warte darauf, dass der Job gestartet wird', |
3690 | 3709 |
'warehouse_journal_list' => 'lagerbuchungsliste', |
3691 | 3710 |
'warehouse_report_list' => 'lagerbestandsliste', |
3711 |
'warehouse_usage_list' => 'Lagerentnahmeliste', |
|
3692 | 3712 |
'with amount' => 'mit Betrag', |
3693 | 3713 |
'with skonto acc. to pt' => 'mit Skonto nach ZB', |
3694 | 3714 |
'with_skonto_pt' => 'mit Skonto nach ZB', |
menus/user/12-warehouse-usage.yaml | ||
---|---|---|
1 |
# |
|
2 |
# opendynamic feature |
|
3 |
# |
|
4 |
--- |
|
5 |
# |
|
6 |
# Warenverbrauchsbericht |
|
7 |
# |
|
8 |
- parent: warehouse_reports |
|
9 |
id: warehouse_reports_whusage |
|
10 |
name: WHUsage |
|
11 |
icon: warehouse_usage |
|
12 |
order: 300 |
|
13 |
access: warehouse_contents | warehouse_management |
|
14 |
params: |
|
15 |
action: Inventory/stock_usage |
templates/webpages/inventory/report_bottom.html | ||
---|---|---|
1 |
[%- PROCESS 'common/paginate.html' pages=SELF.pages, base_url = SELF.base_url %] |
templates/webpages/inventory/warehouse_usage.html | ||
---|---|---|
1 |
[%- USE T8 %] |
|
2 |
[%- USE L %] |
|
3 |
[%- USE HTML %] |
|
4 |
[%- USE LxERP %] |
|
5 |
[%- WAREHOUSE_FILTER = 1 %] |
|
6 |
[%- PROCESS 'common/select_warehouse_bin.html' %] |
|
7 |
|
|
8 |
<h1>[% title | html %]</h1> |
|
9 |
|
|
10 |
[%- INCLUDE 'common/flash.html' %] |
|
11 |
|
|
12 |
<form name="Form" method="post" action="controller.pl"> |
|
13 |
|
|
14 |
<table border="0"> |
|
15 |
<tr> |
|
16 |
<th class="listheading" align="left" valign="top" colspan="5" nowrap>[% 'Period:' | $T8 %]</th> |
|
17 |
</tr> |
|
18 |
<tr> |
|
19 |
<th align=left><input name=reporttype class=radio type=radio value="custom" checked>[% 'Customized Report' | $T8 %]</th> |
|
20 |
</tr> |
|
21 |
<tr> |
|
22 |
<th colspan=1>[% 'Year' | $T8 %]</th> |
|
23 |
<td><input name=year size=11 title="[% 'YYYY' | $T8 %]" value="[% year %]" class="initial_focus"></td> |
|
24 |
</tr> |
|
25 |
<tr> |
|
26 |
<td align=right> <b>[% 'Yearly' | $T8 %]</b> </td> |
|
27 |
<th align=left>[% 'Quarterly' | $T8 %]</th> |
|
28 |
<th align=left colspan=3>[% 'Monthly' | $T8 %]</th> |
|
29 |
</tr> |
|
30 |
<tr> |
|
31 |
<td align=right> <input name=duetyp class=radio type=radio value="13" checked></td> |
|
32 |
<td><input name=duetyp class=radio type=radio value="A"> 1. [% 'Quarter' | $T8 %]</td> |
|
33 |
<td><input name=duetyp class=radio type=radio value="1"> [% 'January' | $T8 %]</td> |
|
34 |
<td><input name=duetyp class=radio type=radio value="5"> [% 'May' | $T8 %]</td> |
|
35 |
<td><input name=duetyp class=radio type=radio value="9"> [% 'September' | $T8 %]</td> |
|
36 |
</tr> |
|
37 |
<tr> |
|
38 |
<td align= right> </td> |
|
39 |
<td><input name=duetyp class=radio type=radio value="B"> 2. [% 'Quarter' | $T8 %]</td> |
|
40 |
<td><input name=duetyp class=radio type=radio value="2"> [% 'February' | $T8 %]</td> |
|
41 |
<td><input name=duetyp class=radio type=radio value="6"> [% 'June' | $T8 %]</td> |
|
42 |
<td><input name=duetyp class=radio type=radio value="10"> [% 'October' | $T8 %]</td> |
|
43 |
</tr> |
|
44 |
<tr> |
|
45 |
<td> </td> |
|
46 |
<td><input name=duetyp class=radio type=radio value="C"> 3. [% 'Quarter' | $T8 %]</td> |
|
47 |
<td><input name=duetyp class=radio type=radio value="3"> [% 'March' | $T8 %]</td> |
|
48 |
<td><input name=duetyp class=radio type=radio value="7"> [% 'July' | $T8 %]</td> |
|
49 |
<td><input name=duetyp class=radio type=radio value="11"> [% 'November' | $T8 %]</td> |
|
50 |
</tr> |
|
51 |
<tr> |
|
52 |
<td> </td> |
|
53 |
<td><input name=duetyp class=radio type=radio value="D"> 4. [% 'Quarter' | $T8 %]</td> |
|
54 |
<td><input name=duetyp class=radio type=radio value="4"> [% 'April' | $T8 %]</td> |
|
55 |
<td><input name=duetyp class=radio type=radio value="8"> [% 'August' | $T8 %]</td> |
|
56 |
<td><input name=duetyp class=radio type=radio value="12"> [% 'December' | $T8 %]</td> |
|
57 |
</tr> |
|
58 |
<tr> |
|
59 |
<td colspan="5"><hr size=3 noshade></td> |
|
60 |
</tr> |
|
61 |
<tr> |
|
62 |
<th align=left><input name=reporttype class=radio type=radio value="free">[% 'Free report period' | $T8 %]</th> |
|
63 |
<td align=left colspan=4> |
|
64 |
[% 'From' | $T8 %] [% L.date_tag('fromdate', fromdate) %] |
|
65 |
[% 'Bis' | $T8 %] [% L.date_tag('todate', todate) %] |
|
66 |
</td> |
|
67 |
</tr> |
|
68 |
<tr> |
|
69 |
<th class="listheading" align="left" valign="top" colspan="5" nowrap>[% 'Filter' | $T8 %]</th> |
|
70 |
</tr> |
|
71 |
<tr> |
|
72 |
<td colspan="5"> |
|
73 |
<table> |
|
74 |
<tr> |
|
75 |
<th align="right" nowrap>[% 'Warehouse' | $T8 %]:</th> |
|
76 |
<td> |
|
77 |
<select name="warehouse_id" id="warehouse_id" onchange="kivi.PartsWarehouse.warehouseChanged(this.value, 0)"> |
|
78 |
<option value="">---</option> |
|
79 |
[%- FOREACH warehouse = WAREHOUSES %] |
|
80 |
<option value="[% HTML.escape(warehouse.id) %]">[% warehouse.description %]</option> |
|
81 |
[%- END %] |
|
82 |
</select> |
|
83 |
</td> |
|
84 |
</tr> |
|
85 |
<tr> |
|
86 |
<th align="right" nowrap>[% 'Bin' | $T8 %]:</th> |
|
87 |
<td><select name="bin_id" id="bin_id"></select></td> |
|
88 |
</tr> |
|
89 |
<tr> |
|
90 |
<th align="right" nowrap>[% 'Part Number' | $T8 %]:</th> |
|
91 |
<td><input name="partnumber" size=20></td> |
|
92 |
</tr> |
|
93 |
<tr> |
|
94 |
<th align="right" nowrap>[% 'Part Description' | $T8 %]:</th> |
|
95 |
<td><input name="description" size=40></td> |
|
96 |
</tr> |
|
97 |
[% IF PARTSCLASSIFICATIONS %] |
|
98 |
<tr> |
|
99 |
<td> |
|
100 |
[% L.select_tag('partsclassification',PARTSCLASSIFICATION,title_key="partsclassification") %] |
|
101 |
</td> |
|
102 |
</tr> |
|
103 |
[% END %] |
|
104 |
<tr> |
|
105 |
<th align="right" nowrap>[% 'Charge Number' | $T8 %]:</th> |
|
106 |
<td><input name="chargenumber" size=40></td> |
|
107 |
</tr> |
|
108 |
[% IF INSTANCE_CONF.get_show_bestbefore %] |
|
109 |
<tr> |
|
110 |
<th align="right" nowrap>[% 'Best Before' | $T8 %]:</th> |
|
111 |
<td> |
|
112 |
[% L.date_tag('bestbefore') %] |
|
113 |
</td> |
|
114 |
</tr> |
|
115 |
[% END %] |
|
116 |
</table> |
|
117 |
</td> |
|
118 |
</tr> |
|
119 |
</table> |
|
120 |
</p> |
|
121 |
|
|
122 |
<p> |
|
123 |
<input type="hidden" name="action" value="Inventory/dispatch"> |
|
124 |
<input type="submit" id="action_usage" class="submit" name="action_usage" value="[% 'Continue' | $T8 %]"> |
|
125 |
</p> |
|
126 |
</form> |
templates/webpages/report_generator/pdf_export_options.html | ||
---|---|---|
1 | 1 |
[%- USE T8 %] |
2 | 2 |
[%- USE HTML %][%- USE LxERP %] |
3 | 3 |
|
4 |
[%- SET default_margin = LxERP.format_amount(1.5) %] |
|
4 |
[%- SET default_ymargin = LxERP.format_amount(1.5) %] |
|
5 |
[%- SET default_xmargin = LxERP.format_amount(0.8) %] |
|
5 | 6 |
|
6 | 7 |
<h1>[% HTML.escape(title) %]</h1> |
7 | 8 |
|
... | ... | |
73 | 74 |
|
74 | 75 |
<tr> |
75 | 76 |
<td align="right">[% 'Top' | $T8 %]</td> |
76 |
<td><input name="report_generator_pdf_options_margin_top" size="4" value="[% HTML.escape(default_margin) %]"> cm</td> |
|
77 |
<td><input name="report_generator_pdf_options_margin_top" size="4" value="[% HTML.escape(default_ymargin) %]"> cm</td>
|
|
77 | 78 |
</tr> |
78 | 79 |
|
79 | 80 |
<tr> |
80 | 81 |
<td align="right">[% 'Left' | $T8 %]</td> |
81 |
<td><input name="report_generator_pdf_options_margin_left" size="4" value="[% HTML.escape(default_margin) %]"> cm</td> |
|
82 |
<td><input name="report_generator_pdf_options_margin_left" size="4" value="[% HTML.escape(default_xmargin) %]"> cm</td>
|
|
82 | 83 |
</tr> |
83 | 84 |
|
84 | 85 |
<tr> |
85 | 86 |
<td align="right">[% 'Bottom' | $T8 %]</td> |
86 |
<td><input name="report_generator_pdf_options_margin_bottom" size="4" value="[% HTML.escape(default_margin) %]"> cm</td> |
|
87 |
<td><input name="report_generator_pdf_options_margin_bottom" size="4" value="[% HTML.escape(default_ymargin) %]"> cm</td>
|
|
87 | 88 |
</tr> |
88 | 89 |
|
89 | 90 |
<tr> |
90 | 91 |
<td align="right">[% 'Right' | $T8 %]</td> |
91 |
<td><input name="report_generator_pdf_options_margin_right" size="4" value="[% HTML.escape(default_margin) %]"> cm</td> |
|
92 |
<td><input name="report_generator_pdf_options_margin_right" size="4" value="[% HTML.escape(default_xmargin) %]"> cm</td>
|
|
92 | 93 |
</tr> |
93 | 94 |
|
94 | 95 |
<tr> |
Auch abrufbar als: Unified diff
Verbrauchsbericht: Lager->Berichte->Lagerentnahme
Ein Bericht über jährliche/quartalsweise/monatliche Lagerentnahme
Anforderungen waren:
1. Zahlen im Bericht einheitlich Formatieren (mit Tausender-Trennpunkt)
2. Spaltenüberschrift:
- "Lagerverbrauch" (Letzte zwei Spalten)
> "Entnommen (ohne Korrekturen)"
"Verbrauch monatlich" (vorletzte Spalte)> "Im Zeitraum"
"Ø Verbr." (letzte Spalte -> "Ø mtl."3. In der Suchmaske unter "Vorgewählte Zeiträume" sollte das aktuelle Jahr vorgegeben sein.
4. Filter "Freier Zeitraum" funktioniert nicht: "Es wurden keine Daten gefunden."
Bei der Berechnung des "Ø mtl." wird Folgendes beachtet:
Falls ein Zeitraum angegeben ist mit einem Enddatum in der Zukunft (z.B. auch bei "Jährlich" oder "Quartal")
muss der Bezugszeitraum mit dem aktuellen Datum (heute) begrenzt werden, ansonsten wird der Durchschnitt falsch berechnet!
Bei Zeitraum kleiner einem Monat, wird Durchschnitt des Entnommenen über einen Monat berechnet
Bei PDF/CSV Export müssen alle Werte berechnet werden
Wegen PDF-Erzeugung ausserhalb Papier X-Rand default reduziert auf 0,8 cm