Revision a33a6af3
Von Tamino Steinert vor mehr als 1 Jahr hinzugefügt
SL/Controller/Part.pm | ||
---|---|---|
768 | 768 |
sub action_showdetails { |
769 | 769 |
my ($self, %params) = @_; |
770 | 770 |
|
771 |
eval { |
|
772 |
my @bindata; |
|
773 |
my $bins = SL::DB::Manager::Bin->get_all(with_objects => ['warehouse' ]); |
|
774 |
my %bins_by_id = map { $_->id => $_ } @$bins; |
|
775 |
my $inventories = SL::DB::Manager::Inventory->get_all(where => [ parts_id => $self->part->id], |
|
776 |
with_objects => ['parts', 'trans_type' ], sort_by => 'bin_id ASC'); |
|
777 |
foreach my $bin (@{ $bins }) { |
|
778 |
$bin->{qty} = 0; |
|
779 |
} |
|
780 |
|
|
781 |
foreach my $inv (@{ $inventories }) { |
|
782 |
my $bin = $bins_by_id{ $inv->bin_id }; |
|
783 |
$bin->{qty} += $inv->qty; |
|
784 |
$bin->{unit} = $inv->parts->unit; |
|
785 |
$bin->{reserved} = defined $inv->reserve_for_id ? 1 : 0; |
|
786 |
} |
|
787 |
my $sum = 0; |
|
788 |
my $reserve_sum = 0; |
|
789 |
for my $bin (@{ $bins }) { |
|
790 |
push @bindata , { |
|
791 |
'warehouse' => $bin->warehouse->forreserve ? $bin->warehouse->description.' (R)' : $bin->warehouse->description, |
|
792 |
'description' => $bin->description, |
|
793 |
'qty' => $bin->{qty}, |
|
794 |
'unit' => $bin->{unit}, |
|
795 |
} if $bin->{qty} != 0; |
|
796 |
|
|
797 |
$sum += $bin->{qty}; |
|
798 |
if($bin->warehouse->forreserve || defined $bin->warehouse->{reserve_for_id}){ |
|
799 |
$reserve_sum += $bin->{qty}; |
|
800 |
} |
|
801 |
} |
|
802 |
# Einfacher ? $sum = $self->part->onhand |
|
803 |
my $todate = DateTime->now_local; |
|
804 |
my $fromdate = DateTime->now_local->add_duration(DateTime::Duration->new(years => -1)); |
|
805 |
my $average = 0; |
|
806 |
foreach my $inv (@{ $inventories }) { |
|
807 |
$average += abs($inv->qty) if $inv->shippingdate && $inv->trans_type->direction eq 'out' && |
|
808 |
DateTime->compare($inv->shippingdate,$fromdate) != -1 && |
|
809 |
DateTime->compare($inv->shippingdate,$todate) == -1; |
|
810 |
} |
|
811 |
my $openitems = SL::DB::Manager::OrderItem->get_all(where => [ parts_id => $self->part->id, 'order.closed' => 0 ], |
|
812 |
with_objects => ['order'],); |
|
813 |
my ($not_delivered, $ordered) = 0; |
|
814 |
for my $openitem (@{ $openitems }) { |
|
815 |
if($openitem -> order -> type eq 'sales_order') { |
|
816 |
$not_delivered += $openitem->qty - $openitem->shipped_qty; |
|
817 |
} elsif ( $openitem->order->type eq 'purchase_order' ) { |
|
818 |
$ordered += $openitem->qty - $openitem->delivered_qty; |
|
819 |
} |
|
820 |
} |
|
821 |
my $print_form = Form->new(''); |
|
822 |
my $part = $self->part; |
|
823 |
|
|
824 |
my $stock_amounts = $self->part->get_simple_stock_sql; |
|
825 |
$print_form->{type} = 'part'; |
|
826 |
$print_form->{printers} = SL::DB::Manager::Printer->get_all_sorted; |
|
827 |
my $output = SL::Presenter->get->render('part/showdetails', |
|
828 |
part => $self->part, |
|
829 |
BINS => \@bindata, |
|
830 |
stock_amounts => $stock_amounts, |
|
831 |
average => $average/12, |
|
832 |
fromdate => $fromdate, |
|
833 |
todate => $todate, |
|
834 |
sum => $sum, |
|
835 |
reserve_sum => $reserve_sum, |
|
836 |
not_delivered => $not_delivered, |
|
837 |
ordered => $ordered, |
|
838 |
type_beleg => $::form->{type}, |
|
839 |
type_id => $::form->{type_id}, |
|
840 |
maker_id => $::form->{maker_id}, |
|
841 |
drawing => $::form->{drawing}, |
|
771 |
my @bindata; |
|
772 |
my $bins = SL::DB::Manager::Bin->get_all(with_objects => ['warehouse' ]); |
|
773 |
my %bins_by_id = map { $_->id => $_ } @$bins; |
|
774 |
my $inventories = SL::DB::Manager::Inventory->get_all(where => [ parts_id => $self->part->id], |
|
775 |
with_objects => ['parts', 'trans_type' ], sort_by => 'bin_id ASC'); |
|
776 |
foreach my $bin (@{ $bins }) { |
|
777 |
$bin->{qty} = 0; |
|
778 |
} |
|
779 |
|
|
780 |
foreach my $inv (@{ $inventories }) { |
|
781 |
my $bin = $bins_by_id{ $inv->bin_id }; |
|
782 |
$bin->{qty} += $inv->qty; |
|
783 |
$bin->{unit} = $inv->parts->unit; |
|
784 |
} |
|
785 |
my $sum = 0; |
|
786 |
for my $bin (@{ $bins }) { |
|
787 |
push @bindata , { |
|
788 |
'warehouse' => $bin->warehouse->description, |
|
789 |
'description' => $bin->description, |
|
790 |
'qty' => $bin->{qty}, |
|
791 |
'unit' => $bin->{unit}, |
|
792 |
} if $bin->{qty} != 0; |
|
793 |
|
|
794 |
$sum += $bin->{qty}; |
|
795 |
} |
|
796 |
|
|
797 |
my $todate = DateTime->now_local; |
|
798 |
my $fromdate = DateTime->now_local->add_duration(DateTime::Duration->new(years => -1)); |
|
799 |
my $average = 0; |
|
800 |
foreach my $inv (@{ $inventories }) { |
|
801 |
$average += abs($inv->qty) if $inv->shippingdate && $inv->trans_type->direction eq 'out' && |
|
802 |
DateTime->compare($inv->shippingdate,$fromdate) != -1 && |
|
803 |
DateTime->compare($inv->shippingdate,$todate) == -1; |
|
804 |
} |
|
805 |
my $openitems = SL::DB::Manager::OrderItem->get_all(where => [ parts_id => $self->part->id, 'order.closed' => 0 ], |
|
806 |
with_objects => ['order'],); |
|
807 |
my ($not_delivered, $ordered) = 0; |
|
808 |
for my $openitem (@{ $openitems }) { |
|
809 |
if($openitem -> order -> type eq 'sales_order') { |
|
810 |
$not_delivered += $openitem->qty - $openitem->shipped_qty; |
|
811 |
} elsif ( $openitem->order->type eq 'purchase_order' ) { |
|
812 |
$ordered += $openitem->qty - $openitem->delivered_qty; |
|
813 |
} |
|
814 |
} |
|
815 |
|
|
816 |
my $stock_amounts = $self->part->get_simple_stock_sql; |
|
817 |
|
|
818 |
my $output = SL::Presenter->get->render('part/showdetails', |
|
819 |
part => $self->part, |
|
820 |
stock_amounts => $stock_amounts, |
|
821 |
average => $average/12, |
|
822 |
fromdate => $fromdate, |
|
823 |
todate => $todate, |
|
824 |
sum => $sum, |
|
825 |
not_delivered => $not_delivered, |
|
826 |
ordered => $ordered, |
|
842 | 827 |
print_options => SL::Helper::PrintOptions->get_print_options( |
843 |
form => $print_form, |
|
844 |
options => {dialog_name_prefix => 'print_options.', |
|
845 |
show_headers => 1, |
|
846 |
no_queue => 1, |
|
847 |
no_postscript => 1, |
|
848 |
no_opendocument => 1, |
|
849 |
hide_language_id_print => 1, |
|
850 |
no_html => 1}, |
|
828 |
form => Form->new( |
|
829 |
type => 'part', |
|
830 |
printers => SL::DB::Manager::Printer->get_all_sorted, |
|
831 |
), |
|
832 |
options => { |
|
833 |
dialog_name_prefix => 'print_options.', |
|
834 |
show_headers => 1, |
|
835 |
no_queue => 1, |
|
836 |
no_postscript => 1, |
|
837 |
no_opendocument => 1, |
|
838 |
hide_language_id_print => 1, |
|
839 |
no_html => 1, |
|
840 |
}, |
|
851 | 841 |
), |
852 |
); |
|
853 |
$self->render(\$output, { layout => 0, process => 0 }); |
|
854 |
1; |
|
855 |
} or do { |
|
856 |
}; |
|
842 |
); |
|
843 |
$self->render(\$output, { layout => 0, process => 0 }); |
|
857 | 844 |
} |
858 | 845 |
|
859 | 846 |
sub action_print_label { |
js/kivi.DispositionManager.js | ||
---|---|---|
35 | 35 |
|
36 | 36 |
ns.show_detail_dialog = function(part_id,partnumber) { |
37 | 37 |
if ( part_id && partnumber ) { |
38 |
var title = kivi.t8('Details of article number "#1"',[partnumber]); |
|
39 |
kivi.popup_dialog({ |
|
40 |
url: 'controller.pl', |
|
41 |
data: { |
|
42 |
action: 'Part/showdetails', |
|
43 |
id : part_id, |
|
44 |
}, |
|
45 |
id: 'detail_menu', |
|
46 |
dialog: { title: title |
|
47 |
, width: 1000 |
|
48 |
, height: 450 |
|
49 |
, modal: false } |
|
50 |
}); |
|
38 |
var title = kivi.t8('Details of article number "#1"',[partnumber]); |
|
39 |
kivi.popup_dialog({ |
|
40 |
url: 'controller.pl', |
|
41 |
data: { |
|
42 |
action: 'Part/showdetails', |
|
43 |
id : part_id, |
|
44 |
}, |
|
45 |
id: 'detail_menu', |
|
46 |
dialog: { |
|
47 |
title: title, |
|
48 |
width: 900, |
|
49 |
height: 600, |
|
50 |
modal: false |
|
51 |
} |
|
52 |
}); |
|
51 | 53 |
} |
52 | 54 |
return true; |
53 | 55 |
}; |
templates/design40_webpages/part/showdetails.html | ||
---|---|---|
1 |
[%- USE LxERP -%][% USE L %][% USE HTML %][%- USE JavaScript -%][% USE T8 %][%- USE Dumper %] |
|
2 |
|
|
3 |
<div class="wrapper"> |
|
4 |
<div class="col"> <!-- part info --> |
|
5 |
<div class="wrapper"> |
|
6 |
<table class="tbl-horizontal"> |
|
7 |
<tbody> |
|
8 |
<tr> |
|
9 |
<td><b>[% LxERP.t8('Description') %]</b></td> |
|
10 |
<td>[% part.description %]</td> |
|
11 |
</tr> |
|
12 |
<tr> |
|
13 |
<td><b>[% LxERP.t8('Default Warehouse') %]</b></td> |
|
14 |
<td>[% part.warehouse.description %]</td> |
|
15 |
</tr> |
|
16 |
<tr> |
|
17 |
<td><b>[% LxERP.t8('Default Bin') %]</b></td> |
|
18 |
<td>[% part.bin.description %]</td> |
|
19 |
</tr> |
|
20 |
<tr> |
|
21 |
<td><b>[% LxERP.t8('ROP') %]</b></td><td>[% part.rop_as_number %]</td> |
|
22 |
</tr> |
|
23 |
</tbody> |
|
24 |
</table> |
|
25 |
</div> |
|
26 |
|
|
27 |
<div class="wrapper"> |
|
28 |
<table class="tbl-list" style="margin-right: 1em;"> |
|
29 |
[%- IF stock_amounts.size %] |
|
30 |
<thead> |
|
31 |
<tr class='listheading'> |
|
32 |
<th>[% 'Warehouse' | $T8 %]</th> |
|
33 |
<th>[% 'Bin' | $T8 %]</th> |
|
34 |
<th>[% 'Chargenumber' | $T8 %]</th> |
|
35 |
<th>[% 'Qty' | $T8 %]</th> |
|
36 |
<th>[% 'Unit' | $T8 %]</th> |
|
37 |
</tr> |
|
38 |
</thead> |
|
39 |
<tbody> |
|
40 |
[% FOREACH stock = stock_amounts %] |
|
41 |
<tr> |
|
42 |
<td>[% HTML.escape(stock.warehouse_description) %]</td> |
|
43 |
<td>[% HTML.escape(stock.bin_description) %]</td> |
|
44 |
<td>[% HTML.escape(stock.chargenumber) %]</td> |
|
45 |
<td class='numeric'>[% LxERP.format_amount(stock.qty, dec) %]</td> |
|
46 |
<td>[% HTML.escape(stock.unit) %]</td> |
|
47 |
</tr> |
|
48 |
[% IF stock.wh_lead != stock.warehouse_description %] |
|
49 |
<tr> |
|
50 |
<th><b>[% HTML.escape(stock.warehouse_description) %]</b></th> |
|
51 |
<td></td> |
|
52 |
<td></td> |
|
53 |
<td class='numeric bold'>[% LxERP.format_amount(stock.wh_run_qty, dec) %]</td> |
|
54 |
<td></td> |
|
55 |
</tr> |
|
56 |
[% END %] |
|
57 |
[% IF loop.last %] |
|
58 |
<tr> |
|
59 |
<th><b>[% 'Total' | $T8 %]</b></th> |
|
60 |
<td></td> |
|
61 |
<td></td> |
|
62 |
<td class='numeric bold'>[% LxERP.format_amount(stock.run_qty, dec) %]</td> |
|
63 |
<td></td> |
|
64 |
</tr> |
|
65 |
[% END %] |
|
66 |
[% END %] |
|
67 |
</tbody> |
|
68 |
[% ELSE %] |
|
69 |
<thead> |
|
70 |
<th> |
|
71 |
<p>[% 'No transactions yet.' | $T8 %]</p> |
|
72 |
</th> |
|
73 |
</thead> |
|
74 |
[% END %] |
|
75 |
</table> |
|
76 |
</div> |
|
77 |
|
|
78 |
<div class="wrapper"> |
|
79 |
<table class="tbl-horizontal"> |
|
80 |
<tbody> |
|
81 |
<tr> |
|
82 |
<td><b>[% LxERP.t8('Sum Amount') %]</b></td> |
|
83 |
<td>[% LxERP.format_amount(sum, 2) %] [% part.unit %]</td> |
|
84 |
</tr> |
|
85 |
<tr> |
|
86 |
<td><b>[% LxERP.t8('Not delivered amount') %]</b></td> |
|
87 |
<td>[% LxERP.format_amount(not_delivered, 2) %] [% part.unit %] |
|
88 |
</td> |
|
89 |
</tr> |
|
90 |
<tr> |
|
91 |
<td><b>[% LxERP.t8('Ordered, but not delivered (purchase)') %]</b></td> |
|
92 |
<td>[% LxERP.format_amount(ordered, 2) %] [% part.unit %]</td> |
|
93 |
</tr> |
|
94 |
<tr> |
|
95 |
<td><b>[% LxERP.t8('Available amount') %]</b></td> |
|
96 |
<td>[% LxERP.format_amount(part.onhandqty, 2) %] [% part.unit %]</td> |
|
97 |
</tr> |
|
98 |
<tr> |
|
99 |
<td><b>[% LxERP.t8('Consume average') %]</b></td> |
|
100 |
<td>[% LxERP.format_amount(average, 2) %] [% part.unit %] [% LxERP.t8('per month') %]</td> |
|
101 |
</tr> |
|
102 |
<tr> |
|
103 |
<td colspan="2" nowrap>([% LxERP.t8('in the time between') %] [% fromdate.to_kivitendo %] - [% todate.to_kivitendo %])</td> |
|
104 |
</tr> |
|
105 |
</tbody></table> |
|
106 |
</div> |
|
107 |
|
|
108 |
<td>[%- L.button_tag("return \$('#detail_menu').dialog('close');", LxERP.t8('Close Details'), class => "submit") %]</td> |
|
109 |
</div> <!-- col 1 --> |
|
110 |
|
|
111 |
<div class="col"> <!-- col 2 --> |
|
112 |
<div id="print_options" class="wrapper"> |
|
113 |
<form id="print_options_form"> |
|
114 |
[% print_options %] |
|
115 |
<br> |
|
116 |
[% L.button_tag('kivi.Part.print_from_showdetail(' _ part.id _ ')', LxERP.t8('Print')) %] |
|
117 |
</form> |
|
118 |
</div> |
|
119 |
|
|
120 |
[% IF part.image && INSTANCE_CONF.get_parts_show_image %] |
|
121 |
<div class="wrapper"> |
|
122 |
<a href="[% part.image | html %]" target="_blank"><img style="[% INSTANCE_CONF.get_parts_image_css %]" src="[% part.image | html %]"/></a> |
|
123 |
</div> |
|
124 |
[% END %] |
|
125 |
</div> <!-- col 2 --> |
templates/webpages/part/showdetails.html | ||
---|---|---|
5 | 5 |
<tr> |
6 | 6 |
<td><b>[% LxERP.t8('Description') %]</b></td><td colspan="3">[% part.description %]</td> |
7 | 7 |
</tr> |
8 |
<tr> |
|
9 |
<td style="background:wheat;"><b>[% LxERP.t8('Internal Notes') %]</b></td><td colspan="3" style="background:wheat;">[% part.intnotes %]</td> |
|
10 |
</tr> |
|
11 |
<tr> |
|
8 |
<tr> |
|
12 | 9 |
<td><b>[% LxERP.t8('Default Warehouse') %]</b></td><td>[% part.warehouse.description %]</td> |
13 | 10 |
<td><b>[% LxERP.t8('Default Bin') %]</b></td><td>[% part.bin.description %]</td> |
14 | 11 |
</tr> |
... | ... | |
64 | 61 |
<tr> |
65 | 62 |
<td><b>[% LxERP.t8('Sum Amount') %]</b></td><td>[% LxERP.format_amount(sum, 2) %] [% part.unit %]</td> |
66 | 63 |
<td rowspan="5"> |
67 |
[% file = part.default_partimage %] |
|
68 |
[%- IF file && INSTANCE_CONF.get_parts_show_image %] |
|
69 |
<img src="controller.pl?action=File/download&id=[% file.id %][%- IF file.version %]&version=[%- file.version %][%- END %]" alt="[% file.title %]" style="[% INSTANCE_CONF.get_parts_image_css %]"> |
|
64 |
[%- IF part.image && INSTANCE_CONF.get_parts_show_image %] |
|
65 |
<a href="[% part.image | html %]" target="_blank"><img style="[% INSTANCE_CONF.get_parts_image_css %]" src="[% part.image | html %]"/></a> |
|
70 | 66 |
[% END %] |
71 | 67 |
</td> |
72 | 68 |
<td rowspan="5"> |
73 |
[%- FOREACH file = part.get_files %] |
|
74 |
<a href="controller.pl?action=File/download&id=[% file.id %][%- IF file.version %]&version=[%- file.version %][%- END %]"> |
|
75 |
<span id="[% "filename_" _ file.id %][%- IF file.version %]_[% file.version %][%- END %]">[% file.file_name %]</span></a><br><br> |
|
76 |
[%- END %] |
|
77 | 69 |
</td> |
78 | 70 |
</tr> |
79 | 71 |
<tr> |
... | ... | |
82 | 74 |
<tr> |
83 | 75 |
<td><b>[% LxERP.t8('Ordered, but not delivered (purchase)') %]</b></td><td colspan="3">[% LxERP.format_amount(ordered, 2) %] [% part.unit %]</td></tr> |
84 | 76 |
</tr> |
85 |
<tr> |
|
86 |
<td><b>[% LxERP.t8('Reserved amount') %]</b></td><td colspan="3">[% LxERP.format_amount(part.stockqty - part.onhandqty, 2) %] [% part.unit %]</td></tr> |
|
87 |
</tr> |
|
88 | 77 |
<tr> |
89 | 78 |
<td><b>[% LxERP.t8('Available amount') %]</b></td><td colspan="3">[% LxERP.format_amount(part.onhandqty, 2) %] [% part.unit %]</td></tr> |
90 | 79 |
</tr> |
Auch abrufbar als: Unified diff
DispositionManager: Popup Artikeldetails überarbeitet