Revision 2401956f
Von Tamino Steinert vor mehr als 1 Jahr hinzugefügt
SL/Controller/DispositionManager.pm | ||
---|---|---|
9 | 9 |
use SL::DB::Part; |
10 | 10 |
use SL::DB::PurchaseBasketItem; |
11 | 11 |
use SL::DB::Order; |
12 |
use SL::DB::OrderItem; |
|
12 | 13 |
use SL::DB::Vendor; |
13 | 14 |
use SL::PriceSource; |
14 | 15 |
use SL::Locale::String qw(t8); |
... | ... | |
140 | 141 |
my ($self) = @_; |
141 | 142 |
|
142 | 143 |
$::request->{layout}->add_javascripts( |
143 |
'kivi.DispositionManager.js', 'kivi.PartDetail.js'
|
|
144 |
'kivi.DispositionManager.js', 'kivi.Part.js' |
|
144 | 145 |
); |
145 | 146 |
my $basket_items = SL::DB::Manager::PurchaseBasketItem->get_all( |
146 | 147 |
query => [ cleared => 'F' ], |
... | ... | |
259 | 260 |
push @order_items, $order_item; |
260 | 261 |
} |
261 | 262 |
|
262 |
$order->add_items( @order_items );
|
|
263 |
$order->assign_attributes(orderitems => \@order_items);
|
|
263 | 264 |
|
264 | 265 |
$order->db->with_transaction( sub { |
265 | 266 |
$order->calculate_prices_and_taxes; |
SL/Controller/Part.pm | ||
---|---|---|
25 | 25 |
use SL::DB::PurchaseBasketItem; |
26 | 26 |
use SL::DB::Shop; |
27 | 27 |
use SL::Helper::Flash; |
28 |
use SL::Helper::PrintOptions; |
|
28 | 29 |
use SL::JSON; |
29 | 30 |
use SL::Locale::String qw(t8); |
30 | 31 |
use SL::MoreCommon qw(save_form); |
... | ... | |
758 | 759 |
} |
759 | 760 |
} |
760 | 761 |
|
762 |
sub action_showdetails { |
|
763 |
my ($self, %params) = @_; |
|
764 |
|
|
765 |
eval { |
|
766 |
my @bindata; |
|
767 |
my $bins = SL::DB::Manager::Bin->get_all(with_objects => ['warehouse' ]); |
|
768 |
my %bins_by_id = map { $_->id => $_ } @$bins; |
|
769 |
my $inventories = SL::DB::Manager::Inventory->get_all(where => [ parts_id => $self->part->id], |
|
770 |
with_objects => ['parts', 'trans_type' ], sort_by => 'bin_id ASC'); |
|
771 |
foreach my $bin (@{ $bins }) { |
|
772 |
$bin->{qty} = 0; |
|
773 |
} |
|
774 |
|
|
775 |
foreach my $inv (@{ $inventories }) { |
|
776 |
my $bin = $bins_by_id{ $inv->bin_id }; |
|
777 |
$bin->{qty} += $inv->qty; |
|
778 |
$bin->{unit} = $inv->parts->unit; |
|
779 |
$bin->{reserved} = defined $inv->reserve_for_id ? 1 : 0; |
|
780 |
} |
|
781 |
my $sum = 0; |
|
782 |
my $reserve_sum = 0; |
|
783 |
for my $bin (@{ $bins }) { |
|
784 |
push @bindata , { |
|
785 |
'warehouse' => $bin->warehouse->forreserve ? $bin->warehouse->description.' (R)' : $bin->warehouse->description, |
|
786 |
'description' => $bin->description, |
|
787 |
'qty' => $bin->{qty}, |
|
788 |
'unit' => $bin->{unit}, |
|
789 |
} if $bin->{qty} != 0; |
|
790 |
|
|
791 |
$sum += $bin->{qty}; |
|
792 |
if($bin->warehouse->forreserve || defined $bin->warehouse->{reserve_for_id}){ |
|
793 |
$reserve_sum += $bin->{qty}; |
|
794 |
} |
|
795 |
} |
|
796 |
# Einfacher ? $sum = $self->part->onhand |
|
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 |
my $print_form = Form->new(''); |
|
816 |
my $part = $self->part; |
|
817 |
|
|
818 |
my $stock_amounts = $self->part->get_simple_stock_sql; |
|
819 |
$print_form->{type} = 'part'; |
|
820 |
$print_form->{printers} = SL::DB::Manager::Printer->get_all_sorted; |
|
821 |
my $output = SL::Presenter->get->render('part/showdetails', |
|
822 |
part => $self->part, |
|
823 |
BINS => \@bindata, |
|
824 |
stock_amounts => $stock_amounts, |
|
825 |
average => $average/12, |
|
826 |
fromdate => $fromdate, |
|
827 |
todate => $todate, |
|
828 |
sum => $sum, |
|
829 |
reserve_sum => $reserve_sum, |
|
830 |
not_delivered => $not_delivered, |
|
831 |
ordered => $ordered, |
|
832 |
type_beleg => $::form->{type}, |
|
833 |
type_id => $::form->{type_id}, |
|
834 |
maker_id => $::form->{maker_id}, |
|
835 |
drawing => $::form->{drawing}, |
|
836 |
print_options => SL::Helper::PrintOptions->get_print_options( |
|
837 |
form => $print_form, |
|
838 |
options => {dialog_name_prefix => 'print_options.', |
|
839 |
show_headers => 1, |
|
840 |
no_queue => 1, |
|
841 |
no_postscript => 1, |
|
842 |
no_opendocument => 1, |
|
843 |
hide_language_id_print => 1, |
|
844 |
no_html => 1}, |
|
845 |
), |
|
846 |
); |
|
847 |
$self->render(\$output, { layout => 0, process => 0 }); |
|
848 |
1; |
|
849 |
} or do { |
|
850 |
}; |
|
851 |
} |
|
852 |
|
|
853 |
sub action_print_label { |
|
854 |
my ($self) = @_; |
|
855 |
# TODO: implement |
|
856 |
return $self->render('generic/error', { layout => 1 }, label_error => t8('Not implemented yet!')); |
|
857 |
} |
|
858 |
|
|
761 | 859 |
sub action_export_assembly_assortment_components { |
762 | 860 |
my ($self) = @_; |
763 | 861 |
|
SL/DB/Helper/ALL.pm | ||
---|---|---|
109 | 109 |
use SL::DB::ProjectStatus; |
110 | 110 |
use SL::DB::ProjectType; |
111 | 111 |
use SL::DB::PurchaseBasket; |
112 |
use SL::DB::PurchaseBasketItem; |
|
112 | 113 |
use SL::DB::PurchaseInvoice; |
113 | 114 |
use SL::DB::Reclamation; |
114 | 115 |
use SL::DB::ReclamationItem; |
SL/DB/Manager/Part.pm | ||
---|---|---|
154 | 154 |
my ($open_qty) = selectrow_query( |
155 | 155 |
$::form, $class->object_class->init_db->dbh, |
156 | 156 |
$query, $part_id, $part_id, $part_id |
157 |
); |
|
157 |
) || 0;
|
|
158 | 158 |
|
159 | 159 |
return $open_qty if $open_qty > 0; |
160 | 160 |
return 0; |
SL/DB/Part.pm | ||
---|---|---|
13 | 13 |
use SL::DB::MetaSetup::Part; |
14 | 14 |
use SL::DB::Manager::Part; |
15 | 15 |
use SL::DB::Chart; |
16 |
use SL::DB::Vendor; |
|
16 |
use SL::DB::Manager::Vendor;
|
|
17 | 17 |
use SL::DB::Helper::AttrHTML; |
18 | 18 |
use SL::DB::Helper::AttrSorted; |
19 | 19 |
use SL::DB::Helper::TransNumberGenerator; |
... | ... | |
104 | 104 |
__PACKAGE__->before_save('_before_save_set_partnumber'); |
105 | 105 |
__PACKAGE__->before_save('_before_save_set_assembly_weight'); |
106 | 106 |
|
107 |
sub init_onhandqty{ |
|
108 |
my ($self) = @_; |
|
109 |
my $qty = SL::Helper::Inventory::get_onhand(part => $self->id); |
|
110 |
return $qty; |
|
111 |
} |
|
112 |
|
|
113 |
sub init_stockqty{ |
|
114 |
my ($self) = @_; |
|
115 |
my $qty = SL::Helper::Inventory::get_stock(part => $self->id); |
|
116 |
return $qty; |
|
117 |
} |
|
118 |
|
|
119 |
sub init_get_open_ordered_qty { |
|
120 |
my $self = shift; |
|
121 |
my $result = SL::DB::Manager::Part->get_open_ordered_qty($self->id); |
|
122 |
|
|
123 |
return $result; |
|
124 |
} |
|
125 |
|
|
126 | 107 |
sub _before_save_set_partnumber { |
127 | 108 |
my ($self) = @_; |
128 | 109 |
|
... | ... | |
302 | 283 |
return $result{ $self->id }; |
303 | 284 |
} |
304 | 285 |
|
305 |
sub is_parts_first_order { |
|
306 |
|
|
307 |
my ($self, %params) = @_; |
|
308 |
|
|
309 |
#require SL::DB::OrderItem; |
|
310 |
my $orders_count = SL::DB::Manager::OrderItem->get_all_count( where => [ %params ], with_objects => 'order' ); |
|
311 |
|
|
312 |
return $orders_count == 1 ? 1 : 0; |
|
313 |
} |
|
314 |
|
|
315 | 286 |
sub available_units { |
316 | 287 |
shift->unit_obj->convertible_units; |
317 | 288 |
} |
... | ... | |
625 | 596 |
return \@vendor_dd; |
626 | 597 |
} |
627 | 598 |
|
599 |
sub init_onhandqty{ |
|
600 |
my ($self) = @_; |
|
601 |
my $qty = SL::Helper::Inventory::get_onhand(part => $self->id) || 0; |
|
602 |
return $qty; |
|
603 |
} |
|
604 |
|
|
605 |
sub init_stockqty{ |
|
606 |
my ($self) = @_; |
|
607 |
my $qty = SL::Helper::Inventory::get_stock(part => $self->id) || 0; |
|
608 |
return $qty; |
|
609 |
} |
|
610 |
|
|
611 |
sub init_get_open_ordered_qty { |
|
612 |
my ($self) = @_; |
|
613 |
my $result = SL::DB::Manager::Part->get_open_ordered_qty($self->id); |
|
614 |
|
|
615 |
return $result; |
|
616 |
} |
|
617 |
|
|
628 | 618 |
1; |
629 | 619 |
|
630 | 620 |
__END__ |
js/kivi.Part.js | ||
---|---|---|
22 | 22 |
$('#ic').submit(); |
23 | 23 |
}; |
24 | 24 |
|
25 |
ns.print_from_showdetail = function(part_id) { |
|
26 |
var data = $('#print_options_form').serializeArray(); |
|
27 |
data.push({ name: 'action', value: 'Part/print_label' }); |
|
28 |
data.push({ name: 'part.id', value: part_id }); |
|
29 |
$.download("controller.pl", data); |
|
30 |
}; |
|
31 |
|
|
25 | 32 |
ns.delete = function() { |
26 | 33 |
var data = $('#ic').serializeArray(); |
27 | 34 |
data.push({ name: 'action', value: 'Part/delete' }); |
locale/de/all | ||
---|---|---|
2506 | 2506 |
'Normalize part description and part notes' => 'Normalisierung Artikelbeschreibung und Artikellangtext (Bemerkung)', |
2507 | 2507 |
'Not Discountable' => 'Nicht rabattierfähig', |
2508 | 2508 |
'Not delivered' => 'Nicht geliefert', |
2509 |
'Not delivered amount' => 'nicht gelieferte Menge', |
|
2509 | 2510 |
'Not done yet' => 'Noch nicht fertig', |
2510 | 2511 |
'Not enough in stock for the serial number #1' => 'Nicht genug auf Lager von der Seriennummer #1', |
2511 | 2512 |
'Not obsolete' => 'Gültig', |
... | ... | |
2620 | 2621 |
'OrderItem' => 'Position', |
2621 | 2622 |
'Ordered' => 'Von Kunden bestellt', |
2622 | 2623 |
'Ordered purchase' => 'Bestellte Menge', |
2624 |
'Ordered, but not delivered (purchase)' => 'Bestellt, nicht geliefert(EK)', |
|
2623 | 2625 |
'Orderer' => 'BestellerIn', |
2624 | 2626 |
'Orders' => 'Aufträge', |
2625 | 2627 |
'Orders / Delivery Orders deleteable' => 'Aufträge / Lieferscheine löschbar', |
... | ... | |
3674 | 3676 |
'Subtotals per quarter' => 'Zwischensummen pro Quartal', |
3675 | 3677 |
'Such entries cannot be exported into the DATEV format and have to be fixed as well.' => 'Solche Einträge sind aber nicht DATEV-exportiertbar und müssen ebenfalls korrigiert werden.', |
3676 | 3678 |
'Suggested invoice' => 'Rechnungsvorschlag', |
3679 |
'Sum Amount' => 'Gesamtmenge', |
|
3677 | 3680 |
'Sum Credit' => 'Summe Haben', |
3678 | 3681 |
'Sum Debit' => 'Summe Soll', |
3679 | 3682 |
'Sum for' => 'Summe für', |
... | ... | |
4949 | 4952 |
'part \'#\'1 in bin \'#2\' only with qty #3 (need additional #4) and chargenumber \'#5\'.' => 'Artikel \'#1\' im \'#2\' nur mit der Menge #3 (noch #4 benötig) und Chargennummer \'#5\'.', |
4950 | 4953 |
'part_list' => 'Warenliste', |
4951 | 4954 |
'pdf_records.zip' => 'pdf_belege.zip', |
4955 |
'per month' => 'pro Monat', |
|
4952 | 4956 |
'percental' => 'prozentual', |
4953 | 4957 |
'periodic' => 'Aufwandsmethode', |
4954 | 4958 |
'perpetual' => 'Bestandsmethode', |
t/controllers/disposition_manager/disposition_manager.t | ||
---|---|---|
60 | 60 |
|
61 | 61 |
my $controller = SL::Controller::DispositionManager->new(); |
62 | 62 |
my $reorder_parts = $controller->_get_parts; |
63 |
is(scalar @{$reorder_parts}, 6, "found 6 parts where onhand <= rop");
|
|
63 |
is(scalar @{$reorder_parts}, 5, "found 5 parts where onhand < rop");
|
|
64 | 64 |
|
65 | 65 |
# die; # die here if you want to test making basket manually |
66 | 66 |
|
... | ... | |
76 | 76 |
select $oldFH; |
77 | 77 |
close $outputFH; |
78 | 78 |
|
79 |
is(SL::DB::Manager::PurchaseBasketItem->get_all_count(), 6, "6 items in purchase basket ok");
|
|
79 |
is(SL::DB::Manager::PurchaseBasketItem->get_all_count(), 5, "5 items in purchase basket ok");
|
|
80 | 80 |
|
81 | 81 |
# die; # die here if you want to test creating purchase orders manually |
82 | 82 |
|
... | ... | |
97 | 97 |
|
98 | 98 |
my $purchase_order = SL::DB::Manager::Order->get_first(); |
99 | 99 |
|
100 |
is( scalar @{$purchase_order->items}, 6, "Purchase order has 6 item ok");
|
|
101 |
print "PART\n"; |
|
102 |
print Dumper($part1); |
|
100 |
is( scalar @{$purchase_order->items}, 5, "Purchase order has 5 item ok");
|
|
101 |
# print "PART\n";
|
|
102 |
# print Dumper($part1);
|
|
103 | 103 |
my $first_item = $purchase_order->items_sorted->[0]; |
104 |
print "FIRST\n"; |
|
105 |
print Dumper($first_item); |
|
104 |
# print "FIRST\n";
|
|
105 |
# print Dumper($first_item);
|
|
106 | 106 |
is( $first_item->parts_id, $part1->id, "Purchase order: first item is part1"); |
107 |
is( $first_item->qty, '1.0000000', "Purchase order: first item has qty 1");
|
|
108 |
cmp_ok( $purchase_order->netamount, '==', 52, "Purchase order: netamount ok");
|
|
109 |
is( $first_item->active_price_source, 'makemodel/' . $part1->makemodels->[0]->id . "/" . $part1->makemodels->[0]->parts_id . "/" . $part1->makemodels->[0]->make, "Purchase order: first item has correct active_price_source" . $first_item->part->partnumber);
|
|
107 |
is( $first_item->qty, '20.00000', "Purchase order: first item has qty 20");
|
|
108 |
cmp_ok( $purchase_order->netamount, '==', 240, "Purchase order: netamount ok");
|
|
109 |
is( $first_item->active_price_source, 'makemodel/' . $part1->makemodels->[0]->id, "Purchase order: first item has correct active_price_source" . $first_item->part->partnumber); |
|
110 | 110 |
|
111 | 111 |
clear_up(); |
112 | 112 |
done_testing(); |
t/workflow/delivery_order_reclamation.t | ||
---|---|---|
281 | 281 |
"sales_delivery_order_items to sales_reclamation_items", |
282 | 282 |
qw( |
283 | 283 |
id delivery_order_id reclamation_id itime mtime |
284 |
cusordnumber marge_price_factor ordnumber transdate |
|
284 |
cusordnumber marge_price_factor ordnumber transdate orderer_id
|
|
285 | 285 |
description reason_description_ext reason_description_int reason_id |
286 | 286 |
)); |
287 | 287 |
} @sales_delivery_order_items, @converted_sales_reclamation_items; |
... | ... | |
301 | 301 |
"sales_reclamation_items to sales_delivery_order_items", |
302 | 302 |
qw( |
303 | 303 |
id delivery_order_id reclamation_id itime mtime |
304 |
cusordnumber marge_price_factor ordnumber transdate |
|
304 |
cusordnumber marge_price_factor ordnumber transdate orderer_id
|
|
305 | 305 |
description reason_description_ext reason_description_int reason_id |
306 | 306 |
)); |
307 | 307 |
} @sales_reclamation_items, @converted_sales_delivery_order_items; |
... | ... | |
323 | 323 |
"purchase_delivery_order_items to purchase_reclamation_items", |
324 | 324 |
qw( |
325 | 325 |
id delivery_order_id reclamation_id itime mtime |
326 |
cusordnumber marge_price_factor ordnumber transdate |
|
326 |
cusordnumber marge_price_factor ordnumber transdate orderer_id
|
|
327 | 327 |
description reason_description_ext reason_description_int reason_id |
328 | 328 |
)); |
329 | 329 |
} @purchase_delivery_order_items, @converted_purchase_reclamation_items; |
... | ... | |
343 | 343 |
"purchase_reclamation_items to purchase_delivery_order_items", |
344 | 344 |
qw( |
345 | 345 |
id delivery_order_id reclamation_id itime mtime |
346 |
cusordnumber marge_price_factor ordnumber transdate |
|
346 |
cusordnumber marge_price_factor ordnumber transdate orderer_id
|
|
347 | 347 |
description reason_description_ext reason_description_int reason_id |
348 | 348 |
)); |
349 | 349 |
} @purchase_reclamation_items, @converted_purchase_delivery_order_items; |
t/workflow/order_reclamation.t | ||
---|---|---|
282 | 282 |
"sales_order_items to sales_reclamation_items", |
283 | 283 |
qw( |
284 | 284 |
id trans_id reclamation_id itime mtime |
285 |
cusordnumber marge_percent marge_price_factor marge_total optional ordnumber ship subtotal transdate |
|
285 |
cusordnumber marge_percent marge_price_factor marge_total optional ordnumber ship subtotal transdate orderer_id
|
|
286 | 286 |
reason_description_ext reason_description_int reason_id |
287 | 287 |
recurring_billing_mode recurring_billing_invoice_id |
288 | 288 |
)); |
... | ... | |
302 | 302 |
"sales_reclamation_items to sales_order_items", |
303 | 303 |
qw( |
304 | 304 |
id trans_id reclamation_id itime mtime |
305 |
cusordnumber marge_percent marge_price_factor marge_total optional ordnumber ship subtotal transdate |
|
305 |
cusordnumber marge_percent marge_price_factor marge_total optional ordnumber ship subtotal transdate orderer_id
|
|
306 | 306 |
reason_description_ext reason_description_int reason_id |
307 | 307 |
recurring_billing_mode recurring_billing_invoice_id |
308 | 308 |
)); |
... | ... | |
323 | 323 |
"purchase_order_items to purchase_reclamation_items", |
324 | 324 |
qw( |
325 | 325 |
id trans_id reclamation_id itime mtime |
326 |
cusordnumber marge_percent marge_price_factor marge_total optional ordnumber ship subtotal transdate |
|
326 |
cusordnumber marge_percent marge_price_factor marge_total optional ordnumber ship subtotal transdate orderer_id
|
|
327 | 327 |
reason_description_ext reason_description_int reason_id |
328 | 328 |
recurring_billing_mode recurring_billing_invoice_id |
329 | 329 |
)); |
... | ... | |
343 | 343 |
"purchase_reclamation_items to purchase_order_items", |
344 | 344 |
qw( |
345 | 345 |
id trans_id reclamation_id itime mtime |
346 |
cusordnumber marge_percent marge_price_factor marge_total optional ordnumber ship subtotal transdate |
|
346 |
cusordnumber marge_percent marge_price_factor marge_total optional ordnumber ship subtotal transdate orderer_id
|
|
347 | 347 |
reason_description_ext reason_description_int reason_id |
348 | 348 |
recurring_billing_mode recurring_billing_invoice_id |
349 | 349 |
)); |
templates/webpages/part/showdetails.html | ||
---|---|---|
1 |
[%- USE LxERP -%][% USE L %][% USE HTML %][%- USE JavaScript -%][% USE T8 %][%- USE Dumper %] |
|
2 |
|
|
3 |
<div style="padding-bottom: 15px"> |
|
4 |
<table style="width: 100%" border="0px" ><tbody> |
|
5 |
<tr> |
|
6 |
<td><b>[% LxERP.t8('Description') %]</b></td><td colspan="3">[% part.description %]</td> |
|
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> |
|
12 |
<td><b>[% LxERP.t8('Default Warehouse') %]</b></td><td>[% part.warehouse.description %]</td> |
|
13 |
<td><b>[% LxERP.t8('Default Bin') %]</b></td><td>[% part.bin.description %]</td> |
|
14 |
</tr> |
|
15 |
<tr> |
|
16 |
<td><b>[% LxERP.t8('ROP') %]</b></td><td>[% part.rop_as_number %]</td> |
|
17 |
</tr> |
|
18 |
<tr> |
|
19 |
[%- IF stock_amounts.size %] |
|
20 |
<td colspan="4"><table style="width: 100%"> |
|
21 |
<tr class='listheading'> |
|
22 |
<th class="listheading">[% 'Warehouse' | $T8 %]</th> |
|
23 |
<th class="listheading">[% 'Bin' | $T8 %]</th> |
|
24 |
<th class="listheading">[% 'Chargenumber' | $T8 %]</th> |
|
25 |
<th class="listheading">[% 'Qty' | $T8 %]</th> |
|
26 |
<th class="listheading">[% 'Unit' | $T8 %]</th> |
|
27 |
</tr> |
|
28 |
[% FOREACH stock = stock_amounts %] |
|
29 |
<tr class='listrow'> |
|
30 |
<td >[% HTML.escape(stock.warehouse_description) %]</td> |
|
31 |
<td >[% IF stock.order_link %]<a target="_blank" href="[% stock.order_link %]">[% END %] |
|
32 |
[% HTML.escape(stock.bin_description) %] |
|
33 |
[% IF stock.order_link %]</a>[% END %] |
|
34 |
</td> |
|
35 |
<td >[% HTML.escape(stock.chargenumber) %]</td> |
|
36 |
<td class='numeric'>[% LxERP.format_amount(stock.qty, dec) %]</td> |
|
37 |
<td >[% HTML.escape(stock.unit) %]</td> |
|
38 |
</tr> |
|
39 |
[% IF stock.wh_lead != stock.warehouse_description %] |
|
40 |
<tr class='listheading'> |
|
41 |
<th class="listheading" >[% HTML.escape(stock.warehouse_description) %]</th> |
|
42 |
<td></td> |
|
43 |
<td></td> |
|
44 |
<td class='numeric bold'>[% LxERP.format_amount(stock.wh_run_qty, dec) %]</td> |
|
45 |
<td></td> |
|
46 |
</tr> |
|
47 |
[% END %] |
|
48 |
[% IF loop.last %] |
|
49 |
<tr class='listheading'> |
|
50 |
<th class="listheading">[% 'Total' | $T8 %]</th> |
|
51 |
<td></td> |
|
52 |
<td></td> |
|
53 |
<td class='numeric bold'>[% LxERP.format_amount(stock.run_qty, dec) %]</td> |
|
54 |
<td></td> |
|
55 |
</tr> |
|
56 |
[% END %] |
|
57 |
[% END %] |
|
58 |
[% ELSE %] |
|
59 |
<td> |
|
60 |
<p>[% 'No transactions yet.' | $T8 %]</p> |
|
61 |
[% END %] |
|
62 |
</td> |
|
63 |
</tr> |
|
64 |
<tr> |
|
65 |
<td><b>[% LxERP.t8('Sum Amount') %]</b></td><td>[% LxERP.format_amount(sum, 2) %] [% part.unit %]</td> |
|
66 |
<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 %]"> |
|
70 |
[% END %] |
|
71 |
</td> |
|
72 |
<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 |
</td> |
|
78 |
</tr> |
|
79 |
<tr> |
|
80 |
<td><b>[% LxERP.t8('Not delivered amount') %]</b></td><td colspan="3">[% LxERP.format_amount(not_delivered, 2) %] [% part.unit %]</td></tr> |
|
81 |
</tr> |
|
82 |
<tr> |
|
83 |
<td><b>[% LxERP.t8('Ordered, but not delivered (purchase)') %]</b></td><td colspan="3">[% LxERP.format_amount(ordered, 2) %] [% part.unit %]</td></tr> |
|
84 |
</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 |
<tr> |
|
89 |
<td><b>[% LxERP.t8('Available amount') %]</b></td><td colspan="3">[% LxERP.format_amount(part.onhandqty, 2) %] [% part.unit %]</td></tr> |
|
90 |
</tr> |
|
91 |
<tr> |
|
92 |
<td><b>[% LxERP.t8('Consume average') %]</b></td><td colspan="3">[% LxERP.format_amount(average, 2) %] [% part.unit %] [% LxERP.t8('per month') %]</td></tr> |
|
93 |
<tr><td colspan="4" nowrap>([% LxERP.t8('in the time between') %] [% fromdate.to_kivitendo %] - [% todate.to_kivitendo %])</td> |
|
94 |
</tr> |
|
95 |
<tr> |
|
96 |
<td>[%- L.button_tag("return \$('#detail_menu').dialog('close');", LxERP.t8('Close Details'), class => "submit") %]</td> |
|
97 |
</tr> |
|
98 |
</tbody></table> |
|
99 |
</div> |
|
100 |
<div id="print_options" > |
|
101 |
<form id="print_options_form"> |
|
102 |
[% print_options %] |
|
103 |
<br> |
|
104 |
[% L.button_tag('kivi.Part.print_from_showdetail(' _ part.id _ ')', LxERP.t8('Print')) %] |
|
105 |
</form> |
|
106 |
</div> |
|
107 |
|
Auch abrufbar als: Unified diff
WIP DispositionManager