Revision 20004cac
Von G. Richardson vor mehr als 5 Jahren hinzugefügt
SL/DB/Part.pm | ||
---|---|---|
3 | 3 |
use strict; |
4 | 4 |
|
5 | 5 |
use Carp; |
6 |
use List::MoreUtils qw(any); |
|
6 |
use List::MoreUtils qw(any uniq);
|
|
7 | 7 |
use Rose::DB::Object::Helpers qw(as_tree); |
8 | 8 |
|
9 | 9 |
use SL::Locale::String qw(t8); |
... | ... | |
363 | 363 |
SUM(i.qty) AS qty, |
364 | 364 |
SUM(i.qty * p.lastcost) AS stock_value, |
365 | 365 |
p.unit AS unit, |
366 |
LEAD(w.description) OVER pt AS wh_lead, -- to detect warehouse changes for subtotals |
|
366 |
LEAD(w.description) OVER pt AS wh_lead, -- to detect warehouse changes for subtotals in template
|
|
367 | 367 |
SUM( SUM(i.qty) ) OVER pt AS run_qty, -- running total of total qty |
368 | 368 |
SUM( SUM(i.qty) ) OVER wh AS wh_run_qty, -- running total of warehouse qty |
369 | 369 |
SUM( SUM(i.qty * p.lastcost)) OVER pt AS run_stock_value, -- running total of total stock_value |
370 | 370 |
SUM( SUM(i.qty * p.lastcost)) OVER wh AS wh_run_stock_value -- running total of warehouse stock_value |
371 | 371 |
FROM inventory i |
372 |
LEFT JOIN parts p ON (p.id = i.parts_id) |
|
373 |
LEFT JOIN warehouse w ON (i.warehouse_id = w.id) |
|
374 |
LEFT JOIN bin b ON (i.bin_id = b.id) |
|
372 |
LEFT JOIN parts p ON (p.id = i.parts_id)
|
|
373 |
LEFT JOIN warehouse w ON (i.warehouse_id = w.id)
|
|
374 |
LEFT JOIN bin b ON (i.bin_id = b.id)
|
|
375 | 375 |
WHERE parts_id = ? |
376 | 376 |
GROUP BY w.description, b.description, p.unit, i.parts_id |
377 | 377 |
HAVING SUM(qty) != 0 |
378 |
WINDOW pt AS (PARTITION BY i.parts_id ORDER BY w.description, b.description, p.unit),
|
|
379 |
wh AS (PARTITION by w.description ORDER BY w.description, b.description, p.unit)
|
|
380 |
ORDER BY w.description, b.description
|
|
378 |
WINDOW pt AS (PARTITION BY i.parts_id ORDER BY w.sortkey, b.description, p.unit),
|
|
379 |
wh AS (PARTITION by w.description ORDER BY w.sortkey, b.description, p.unit)
|
|
380 |
ORDER BY w.sortkey, b.description, p.unit
|
|
381 | 381 |
SQL |
382 | 382 |
|
383 | 383 |
my $stock_info = selectall_hashref_query($::form, $self->db->dbh, $query, $self->id); |
384 | 384 |
return $stock_info; |
385 | 385 |
} |
386 | 386 |
|
387 |
sub get_mini_journal { |
|
388 |
my ($self) = @_; |
|
389 |
|
|
390 |
# inventory ids of the most recent 10 inventory trans_ids |
|
391 |
|
|
392 |
# duplicate code copied from SL::Controller::Inventory mini_journal, except |
|
393 |
# for the added filter on parts_id |
|
394 |
|
|
395 |
my $parts_id = $self->id; |
|
396 |
my $query = <<"SQL"; |
|
397 |
with last_inventories as ( |
|
398 |
select id, |
|
399 |
trans_id, |
|
400 |
itime |
|
401 |
from inventory |
|
402 |
where parts_id = $parts_id |
|
403 |
order by itime desc |
|
404 |
limit 20 |
|
405 |
), |
|
406 |
grouped_ids as ( |
|
407 |
select trans_id, |
|
408 |
array_agg(id) as ids |
|
409 |
from last_inventories |
|
410 |
group by trans_id |
|
411 |
order by max(itime) |
|
412 |
desc limit 10 |
|
413 |
) |
|
414 |
select unnest(ids) |
|
415 |
from grouped_ids |
|
416 |
limit 20 -- so the planner knows how many ids to expect, the cte is an optimisation fence |
|
417 |
SQL |
|
418 |
|
|
419 |
my $objs = SL::DB::Manager::Inventory->get_all( |
|
420 |
query => [ id => [ \"$query" ] ], |
|
421 |
with_objects => [ 'parts', 'trans_type', 'bin', 'bin.warehouse' ], # prevent lazy loading in template |
|
422 |
sort_by => 'itime DESC', |
|
423 |
); |
|
424 |
# remember order of trans_ids from query, for ordering hash later |
|
425 |
my @sorted_trans_ids = uniq map { $_->trans_id } @$objs; |
|
426 |
|
|
427 |
# at most 2 of them belong to a transaction and the qty determines in or out. |
|
428 |
my %transactions; |
|
429 |
for (@$objs) { |
|
430 |
$transactions{ $_->trans_id }{ $_->qty > 0 ? 'in' : 'out' } = $_; |
|
431 |
$transactions{ $_->trans_id }{base} = $_; |
|
432 |
} |
|
433 |
|
|
434 |
# because the inventory transactions were built in a hash, we need to sort the |
|
435 |
# hash by using the original sort order of the trans_ids |
|
436 |
my @sorted = map { $transactions{$_} } @sorted_trans_ids; |
|
437 |
|
|
438 |
return \@sorted; |
|
439 |
} |
|
440 |
|
|
387 | 441 |
sub clone_and_reset_deep { |
388 | 442 |
my ($self) = @_; |
389 | 443 |
|
... | ... | |
612 | 666 |
description is about to change, i.e. the next line will contain numbers from a |
613 | 667 |
different warehouse, so that a subtotal line can be added. |
614 | 668 |
|
615 |
The last line will contain the qty total and the total stock value over all |
|
616 |
warehouses/bins and can be used to add a line for the grand totals. |
|
669 |
The last row will contain the running qty total (run_qty) and the running total |
|
670 |
stock value (run_stock_value) over all warehouses/bins and can be used to add a |
|
671 |
line for the grand totals. |
|
617 | 672 |
|
618 | 673 |
=item C<items_lastcost_sum> |
619 | 674 |
|
Auch abrufbar als: Unified diff
Part Controller - neuer Tab mit Lagerinformationen
(Derzeit gibt es im Template Variabeln um Zwischensummen und
Nachkommastellen zu kontrollieren)
Diese Daten werden nur bei Bedarf geladen, also wenn der Benutzer auf
den neuen Tab "Lagerbewegungen/-bestände" klickt.
Außerdem gibt es Links zu diversen Lageraktionen (Einlagern, Umlagern,
Entnahme), wo der Artikel dann schon vorausgewählt ist.