Revision 8fa9177a
Von Tamino Steinert vor mehr als 1 Jahr hinzugefügt
SL/Controller/DispositionManager.pm | ||
---|---|---|
8 | 8 |
use SL::Controller::Helper::ReportGenerator; |
9 | 9 |
use SL::DB::Part; |
10 | 10 |
use SL::DB::PurchaseBasketItem; |
11 |
use SL::DB::Order; |
|
12 |
use SL::DB::Vendor; |
|
11 | 13 |
use SL::PriceSource; |
12 | 14 |
use SL::Locale::String qw(t8); |
13 | 15 |
use SL::Helper::Flash qw(flash); |
... | ... | |
15 | 17 |
|
16 | 18 |
use Data::Dumper; |
17 | 19 |
|
18 |
use Rose::Object::MakeMethods::Generic |
|
19 |
( |
|
20 |
use Rose::Object::MakeMethods::Generic ( |
|
20 | 21 |
'scalar --get_set_init' => [ qw(models) ], |
21 | 22 |
); |
22 | 23 |
|
23 | 24 |
sub action_list_parts { |
24 |
my ( $self ) = @_;
|
|
25 |
my ($self) = @_;
|
|
25 | 26 |
$self->{action} = 'list_parts'; |
26 |
$self->prepare_report('Reorder Level List', $::form->{noshow} ? 1 : 0 );
|
|
27 |
$self->prepare_report(t8('Reorder Level List'), $::form->{noshow} ? 1 : 0 );
|
|
27 | 28 |
|
28 | 29 |
my $objects = $::form->{noshow} ? [] : $self->models->get; |
29 | 30 |
|
30 | 31 |
$self->_setup_list_action_bar; |
31 |
$self->report_generator_list_objects(report => $self->{report}, objects => $objects); |
|
32 |
$self->report_generator_list_objects( |
|
33 |
report => $self->{report}, objects => $objects); |
|
32 | 34 |
} |
33 | 35 |
|
34 | 36 |
sub prepare_report { |
35 | 37 |
my ($self, $title, $noshow ) = @_; |
36 |
$main::lxdebug->enter_sub(); |
|
37 | 38 |
|
38 |
my $locale = $main::locale; |
|
39 | 39 |
my $report = SL::ReportGenerator->new(\%::myconfig, $::form); |
40 | 40 |
$self->{report} = $report; |
41 | 41 |
|
42 |
my @columns = qw(partnumber description drawing available onhand rop ordered); # consume); |
|
43 |
my @visible = qw(partnumber description drawing available onhand rop ordered); # consume); |
|
44 |
my @sortable = qw(partnumber description); # consume); |
|
42 |
my @columns = qw( |
|
43 |
partnumber description available onhand rop ordered |
|
44 |
); |
|
45 |
my @visible = qw( |
|
46 |
partnumber description available onhand rop ordered |
|
47 |
); |
|
48 |
my @sortable = qw(partnumber description); |
|
45 | 49 |
|
46 | 50 |
my %column_defs = ( |
47 |
'partnumber' => { sub => sub { $_[0]->partnumber }, text => t8('Part Number'), |
|
48 |
obj_link => sub { $_[0]->presenter->link_to }, }, |
|
49 |
'description' => { sub => sub { $_[0]->description }, text => t8('Part Description'), |
|
50 |
obj_link => sub { $_[0]->presenter->link_to }, }, |
|
51 |
'drawing' => { sub => sub { $_[0]->drawing }, text => t8('Drawing'), }, |
|
52 |
'available' => { sub => sub { $::form->format_amount(\%::myconfig,$_[0]->onhandqty,2); }, text => t8('Available Stock'), }, |
|
53 |
'onhand' => { sub => sub { $::form->format_amount(\%::myconfig,$_[0]->stockqty,2); }, text => t8('All On Hand'), }, |
|
54 |
'rop' => { sub => sub { $::form->format_amount(\%::myconfig,$_[0]->rop,2); }, text => t8('Rop'), }, |
|
55 |
'ordered' => { sub => sub { $::form->format_amount(\%::myconfig,$_[0]->get_open_ordered_qty,2); }, text => t8('Ordered purchase'), }, |
|
56 |
# 'consume' => { sub => sub { $::form->format_amount(\%::myconfig,$_[0]->consume,2); }, text => t8('Consume'), }, |
|
57 |
); |
|
58 |
|
|
59 |
# for my $col (@sortable) { |
|
60 |
# $column_defs{$col}{link} = $self->self_url( |
|
61 |
# sort_by => $col, |
|
62 |
# sort_dir => ($self->{sort_by} eq $col ? 1 - $self->{sort_dir} : $self->{sort_dir}), |
|
63 |
# page => $self->{pages}{cur}, |
|
64 |
# retype => $::form->{retype}, |
|
65 |
# stock => $::form->{stock}, |
|
66 |
# ); |
|
67 |
# } |
|
51 |
partnumber => { |
|
52 |
sub => sub { $_[0]->partnumber }, |
|
53 |
text => t8('Part Number'), |
|
54 |
obj_link => sub { $_[0]->presenter->link_to }, |
|
55 |
}, |
|
56 |
description => { |
|
57 |
sub => sub { $_[0]->description }, |
|
58 |
text => t8('Part Description'), |
|
59 |
obj_link => sub { $_[0]->presenter->link_to }, |
|
60 |
}, |
|
61 |
available => { |
|
62 |
sub => sub { $::form->format_amount(\%::myconfig,$_[0]->onhandqty,2); }, |
|
63 |
text => t8('Available Stock'), |
|
64 |
}, |
|
65 |
onhand => { |
|
66 |
sub => sub { $::form->format_amount(\%::myconfig,$_[0]->stockqty,2); }, |
|
67 |
text => t8('Total Stock'), |
|
68 |
}, |
|
69 |
rop => { |
|
70 |
sub => sub { $::form->format_amount(\%::myconfig,$_[0]->rop,2); }, |
|
71 |
text => t8('Rop'), |
|
72 |
}, |
|
73 |
ordered => { |
|
74 |
sub => sub { $::form->format_amount( |
|
75 |
\%::myconfig,$_[0]->get_open_ordered_qty,2); }, |
|
76 |
text => t8('Ordered purchase'), |
|
77 |
}, |
|
78 |
); |
|
68 | 79 |
|
69 | 80 |
map { $column_defs{$_}->{visible} = 1 } @visible; |
70 | 81 |
|
... | ... | |
82 | 93 |
$report->set_options_from_form; |
83 | 94 |
|
84 | 95 |
unless ( $noshow ) { |
85 |
$self->models->disable_plugin('paginated') if $report->{options}{output_format} =~ /^(pdf|csv)$/i; |
|
96 |
if ($report->{options}{output_format} =~ /^(pdf|csv)$/i) { |
|
97 |
$self->models->disable_plugin('paginated'); |
|
98 |
} |
|
86 | 99 |
$self->models->finalize; # for filter laundering |
87 |
$self->models->set_report_generator_sort_options(report => $report, sortable_columns => \@sortable); |
|
88 |
#$report->set_sort_indicator($self->{sort_by}, $self->{sort_dir}); |
|
100 |
$self->models->set_report_generator_sort_options( |
|
101 |
report => $report, sortable_columns => \@sortable |
|
102 |
); |
|
89 | 103 |
} |
90 |
#$::request->layout->add_javascripts('kivi.PartsWarehouse.js'); |
|
91 |
#$::form->get_lists('warehouses' => { 'key' => 'WAREHOUSES', |
|
92 |
# 'bins' => 'BINS', }); |
|
93 | 104 |
my $parts = $self->_get_parts(0); |
94 | 105 |
my $top = $self->render('disposition_manager/list_parts', { output => 0 }, |
95 | 106 |
noshow => $noshow, |
96 | 107 |
PARTS => $parts, |
97 | 108 |
); |
98 |
my $bottom = $noshow ? undef : $self->render('reorder_level_list/report_bottom', { output => 0}, models => $self->models ); |
|
109 |
my $bottom = $noshow ? undef : $self->render( |
|
110 |
'disposition_manager/reorder_level_list/report_bottom', |
|
111 |
{ output => 0}, models => $self->models ); |
|
99 | 112 |
$report->set_options( |
100 | 113 |
raw_top_info_text => $top, |
101 | 114 |
raw_bottom_info_text => $bottom, |
102 | 115 |
); |
103 |
$main::lxdebug->leave_sub(); |
|
104 | 116 |
} |
117 |
|
|
105 | 118 |
sub action_add_to_purchase_basket{ |
106 |
my ( $self ) = @_; |
|
119 |
my ($self) = @_; |
|
120 |
|
|
121 |
my $employee = SL::DB::Manager::Employee->current; |
|
107 | 122 |
|
108 | 123 |
my $parts_to_add = delete($::form->{ids}) || []; |
109 | 124 |
foreach my $id (@{ $parts_to_add }) { |
110 |
my $part = SL::DB::Manager::Part->find_by(id => $id) or die "Can't find part with id: $id\n"; |
|
125 |
my $part = SL::DB::Manager::Part->find_by(id => $id) |
|
126 |
or die "Can't find part with id: $id\n"; |
|
127 |
my $needed_qty = $part->order_qty < ($part->rop - $part->onhandqty) ? |
|
128 |
$part->rop - $part->onhandqty |
|
129 |
: $part->order_qty; |
|
111 | 130 |
my $basket_part = SL::DB::PurchaseBasketItem->new( |
112 |
parts_id => $part->id, |
|
113 |
qty => $part->ordersize, # was ist wenn order_size < (rop-onhand) ist? sollte dann nicht (rop-onhand) genommen werden? |
|
131 |
part_id => $part->id, |
|
132 |
qty => $needed_qty, |
|
133 |
orderer_id => $employee->id, |
|
114 | 134 |
)->save; |
115 | 135 |
} |
116 | 136 |
$self->action_show_basket; |
117 |
|
|
118 | 137 |
} |
119 | 138 |
|
120 | 139 |
sub action_show_basket { |
121 |
my ( $self ) = @_;
|
|
140 |
my ($self) = @_;
|
|
122 | 141 |
|
123 |
$::request->{layout}->add_javascripts('kivi.DispositionManager.js', 'kivi.PartDetail.js'); |
|
124 |
my $basket_items = SL::DB::Manager::PurchaseBasketItem->get_all( query => [ cleared => 'F' ], with_objects => [ 'part', 'part.makemodels' ]); |
|
142 |
$::request->{layout}->add_javascripts( |
|
143 |
'kivi.DispositionManager.js', 'kivi.PartDetail.js' |
|
144 |
); |
|
145 |
my $basket_items = SL::DB::Manager::PurchaseBasketItem->get_all( |
|
146 |
query => [ cleared => 'F' ], |
|
147 |
with_objects => [ 'part', 'part.makemodels' ] |
|
148 |
); |
|
125 | 149 |
$self->_setup_show_basket_action_bar; |
126 |
$self->render('disposition_manager/show_purchase_basket', BASKET_ITEMS => $basket_items, title => "Purchase basket" ); |
|
150 |
$self->render( |
|
151 |
'disposition_manager/show_purchase_basket', |
|
152 |
BASKET_ITEMS => $basket_items, |
|
153 |
title => t8('Purchase basket'), |
|
154 |
); |
|
127 | 155 |
} |
128 | 156 |
|
129 | 157 |
sub action_show_vendor_items { |
130 |
my ( $self ) = @_;
|
|
158 |
my ($self) = @_;
|
|
131 | 159 |
|
132 |
my $makemodels_parts = SL::DB::Manager::Part->get_all( query => [ 'makemodels.make' => $::form->{v_id}, 'makemodels.sortorder' => 1, '!id' => ['5599'], ], sort_by => 'onhand', with_objects => [ 'makemodels' ]); |
|
133 |
$self->render('disposition_manager/_show_vendor_parts', { layout => 0 }, MAKEMODEL_ITEMS => $makemodels_parts); |
|
160 |
my $makemodels_parts = SL::DB::Manager::Part->get_all( |
|
161 |
query => [ |
|
162 |
'makemodels.make' => $::form->{v_id}, |
|
163 |
'makemodels.sortorder' => 1, |
|
164 |
], |
|
165 |
sort_by => 'onhand', |
|
166 |
with_objects => [ 'makemodels' ] |
|
167 |
); |
|
168 |
$self->render( |
|
169 |
'disposition_manager/_show_vendor_parts', |
|
170 |
{ layout => 0 }, |
|
171 |
MAKEMODEL_ITEMS => $makemodels_parts |
|
172 |
); |
|
134 | 173 |
} |
135 | 174 |
|
136 | 175 |
sub action_transfer_to_purchase_order { |
137 | 176 |
|
138 |
my ( $self ) = @_; |
|
139 |
require SL::DB::Order; |
|
140 |
# require SL::DB::OrderItem; |
|
141 |
require SL::DB::Vendor; |
|
177 |
my ($self) = @_; |
|
142 | 178 |
my @error_report; |
143 | 179 |
|
144 |
unless (($::form->{ids} && scalar @{ $::form->{ids}}) || ( $::form->{vendor_part_ids} && scalar @{ $::form->{vendor_part_ids}})) { |
|
145 |
die 'There are no items selected'; |
|
180 |
my $basket_items_ids = $::form->{ids}; |
|
181 |
my $vendor_items_ids = $::form->{vendor_part_ids}; |
|
182 |
|
|
183 |
unless (($basket_items_ids && scalar @{ $basket_items_ids}) |
|
184 |
|| ( $vendor_items_ids && scalar @{ $vendor_items_ids})) |
|
185 |
{ |
|
186 |
$self->js->flash('error', t8('There are no items selected')); |
|
187 |
return $self->js->render(); |
|
146 | 188 |
} |
147 | 189 |
my $v_id = $::form->{vendor_ids}->[0] ; |
148 | 190 |
|
149 | 191 |
my ($vendor, $employee); |
150 |
$vendor = SL::DB::Manager::Vendor->find_by(id => $v_id) or die "Can't find vendor"; |
|
151 |
$employee = SL::DB::Manager::Employee->current or die "Can't find employee"; |
|
152 |
|
|
192 |
$vendor = SL::DB::Manager::Vendor->find_by(id => $v_id); |
|
193 |
$employee = SL::DB::Manager::Employee->current; |
|
153 | 194 |
|
154 |
my $basket_items; |
|
155 |
$basket_items = SL::DB::Manager::PurchaseBasketItem->get_all( query => [ id => \@{ $::form->{ids} } ] ) if ($::form->{ids} && scalar @{ $::form->{ids}}); |
|
156 | 195 |
|
157 |
my $vendor_items; |
|
158 |
$vendor_items = SL::DB::Manager::Part->get_all( query => [ id => \@{ $::form->{vendor_part_ids} } ] ) if ($::form->{vendor_part_ids} && scalar @{ $::form->{vendor_part_ids}}); |
|
196 |
my @orderitem_maps = (); # part, qty, orderer_id |
|
197 |
if ($basket_items_ids && scalar @{ $basket_items_ids}) { |
|
198 |
my $basket_items = SL::DB::Manager::PurchaseBasketItem->get_all( |
|
199 |
query => [ id => $basket_items_ids ], |
|
200 |
with_objects => ['part'], |
|
201 |
); |
|
202 |
push @orderitem_maps, map {{ |
|
203 |
part => $_->part, |
|
204 |
qty => $_->qty, |
|
205 |
orderer_id => $_->orderer_id, |
|
206 |
}} @{$basket_items}; |
|
207 |
} |
|
208 |
if ($vendor_items_ids && scalar @{ $vendor_items_ids}) { |
|
209 |
my $vendor_items = SL::DB::Manager::Part->get_all( |
|
210 |
query => [ id => $vendor_items_ids ] ); |
|
211 |
push @orderitem_maps, map {{ |
|
212 |
part => $_, |
|
213 |
qty => $_->order_qty || 1, |
|
214 |
orderer_id => $employee->id, |
|
215 |
}} @{$vendor_items}; |
|
216 |
} |
|
159 | 217 |
|
160 |
# create order first so we have a record for PriceSource |
|
161 | 218 |
my $order = SL::DB::Order->new( |
162 | 219 |
vendor_id => $vendor->id, |
163 | 220 |
employee_id => $employee->id, |
... | ... | |
170 | 227 |
transdate => DateTime->today_local |
171 | 228 |
); |
172 | 229 |
|
230 |
my @order_items; |
|
173 | 231 |
my $i = 0; |
174 |
my @items; |
|
175 |
|
|
176 |
if ($::form->{ids} && scalar @{ $::form->{ids}}) { |
|
177 |
foreach my $basket_item ( @{ $basket_items } ) { |
|
178 |
$i++; |
|
179 |
|
|
180 |
my $current_order_item = SL::DB::OrderItem->new( |
|
181 |
part => $basket_item->part, |
|
182 |
qty => $basket_item->part->min_order_qty || 1, |
|
183 |
unit => $basket_item->part->unit, |
|
184 |
description => $basket_item->part->description, |
|
185 |
longdescription => $basket_item->part->notes, |
|
186 |
position => $i, |
|
187 |
orderer_id => $basket_item->orderer->id, |
|
188 |
price_factor_id => $basket_item->part->price_factor_id, |
|
189 |
price_factor => $basket_item->part->price_factor_id ? $basket_item->part->price_factor->factor : '', |
|
190 |
position => $i, |
|
191 |
); |
|
192 |
|
|
193 |
my $price_source = SL::PriceSource->new(record_item => $current_order_item, record => $order); |
|
194 |
|
|
195 |
$current_order_item->sellprice($price_source->best_price ? $price_source->best_price->price : 0); |
|
196 |
$current_order_item->active_price_source($price_source->best_price ? $price_source->best_price->source : ''); |
|
197 |
push(@items, $current_order_item); |
|
198 |
} |
|
199 |
} |
|
232 |
foreach my $orderitem_map (@orderitem_maps) { |
|
233 |
$i++; |
|
234 |
my $part = $orderitem_map->{part}; |
|
235 |
my $qty = $orderitem_map->{qty}; |
|
236 |
my $orderer_id = $orderitem_map->{orderer_id}; |
|
237 |
|
|
238 |
my $order_item = SL::DB::OrderItem->new( |
|
239 |
part => $part, |
|
240 |
qty => $qty, |
|
241 |
unit => $part->unit, |
|
242 |
description => $part->description, |
|
243 |
price_factor_id => $part->price_factor_id, |
|
244 |
price_factor => |
|
245 |
$part->price_factor_id ? $part->price_factor->factor |
|
246 |
: '', |
|
247 |
orderer_id => $orderer_id, |
|
248 |
position => $i, |
|
249 |
); |
|
200 | 250 |
|
201 |
if ($::form->{vendor_part_ids} && scalar @{ $::form->{vendor_part_ids}}) { |
|
202 |
foreach my $vendor_item ( @{ $vendor_items } ) { |
|
203 |
$i++; |
|
204 |
|
|
205 |
my $current_order_item = SL::DB::OrderItem->new( |
|
206 |
part => $vendor_item, |
|
207 |
qty => $vendor_item->ordersize || 1, |
|
208 |
unit => $vendor_item->unit, |
|
209 |
description => $vendor_item->description, |
|
210 |
price_factor_id => $vendor_item->price_factor_id, |
|
211 |
price_factor => $vendor_item->price_factor_id ? $vendor_item->price_factor->factor : '', |
|
212 |
position => $i, |
|
213 |
orderer_id => $employee->id, |
|
214 |
); |
|
215 |
|
|
216 |
my $price_source = SL::PriceSource->new(record_item => $current_order_item, record => $order); |
|
217 |
$current_order_item->sellprice($price_source->best_price->price); |
|
218 |
$current_order_item->active_price_source($price_source->best_price->source); |
|
219 |
push(@items, $current_order_item); |
|
220 |
} |
|
251 |
my $price_source = SL::PriceSource->new( |
|
252 |
record_item => $order_item, record => $order); |
|
253 |
$order_item->sellprice( |
|
254 |
$price_source->best_price ? $price_source->best_price->price |
|
255 |
: 0); |
|
256 |
$order_item->active_price_source( |
|
257 |
$price_source->best_price ? $price_source->best_price->source |
|
258 |
: ''); |
|
259 |
push @order_items, $order_item; |
|
221 | 260 |
} |
222 | 261 |
|
223 |
$order->orderitems( [ @items ] );
|
|
262 |
$order->add_items( @order_items );
|
|
224 | 263 |
|
225 | 264 |
$order->db->with_transaction( sub { |
226 | 265 |
$order->calculate_prices_and_taxes; |
... | ... | |
239 | 278 |
$item->{custom_variables} = \@{ $item->cvars_by_config }; |
240 | 279 |
$item->save; |
241 | 280 |
} |
242 |
SL::DB::Manager::PurchaseBasketItem->delete_all( where => [ id => \@{ $::form->{ids} }]) if ($::form->{ids} && scalar @{ $::form->{ids}}); |
|
281 |
if ($basket_items_ids && scalar @{ $basket_items_ids}) { |
|
282 |
SL::DB::Manager::PurchaseBasketItem->delete_all( |
|
283 |
where => [ id => $basket_items_ids]); |
|
284 |
} |
|
243 | 285 |
return 1; |
244 | 286 |
}) || die "error: " . $order->db->error; |
245 | 287 |
|
246 |
my $user_prefs_doc = SL::Helper::UserPreferences->new( |
|
247 |
namespace => 'DefaultOrderController', |
|
288 |
$self->redirect_to( |
|
289 |
controller => 'Order', |
|
290 |
action => 'edit', |
|
291 |
type => 'purchase_order', |
|
292 |
vc => 'vendor', |
|
293 |
id => $order->id, |
|
248 | 294 |
); |
249 |
my $doc_val = $::instance_conf->get_feature_experimental_order ? 'new' : 'old'; |
|
250 |
$doc_val = $user_prefs_doc->get('default_order_controller') if ($user_prefs_doc); |
|
251 |
if ( $doc_val eq 'old') { |
|
252 |
$self->redirect_to( |
|
253 |
controller => 'oe.pl', |
|
254 |
action => 'edit', |
|
255 |
type => 'purchase_order', |
|
256 |
vc => 'vendor', |
|
257 |
id => $order->id, |
|
258 |
); |
|
259 |
} else { |
|
260 |
$self->redirect_to( |
|
261 |
controller => 'Order', |
|
262 |
action => 'edit', |
|
263 |
type => 'purchase_order', |
|
264 |
vc => 'vendor', |
|
265 |
id => $order->id, |
|
266 |
); |
|
267 |
} |
|
268 | 295 |
} |
269 | 296 |
|
270 | 297 |
sub _get_parts { |
271 | 298 |
my ($self, $ordered) = @_; |
272 | 299 |
|
273 | 300 |
my $query = <<SQL; |
274 |
SELECT * |
|
275 |
FROM parts |
|
276 |
WHERE onhand < rop |
|
277 |
AND rop != 0 |
|
278 |
AND id NOT IN( SELECT parts_id FROM purchase_basket_items ) |
|
279 |
AND NOT obsolete |
|
280 |
ORDER BY partnumber |
|
301 |
WITH available AS ( |
|
302 |
SELECT inv.parts_id, sum(qty) as sum |
|
303 |
FROM inventory inv |
|
304 |
LEFT JOIN warehouse w ON inv.warehouse_id = w.id |
|
305 |
WHERE NOT w.invalid |
|
306 |
GROUP BY inv.parts_id |
|
307 |
|
|
308 |
UNION ALL |
|
309 |
|
|
310 |
SELECT p.id, 0 as sum |
|
311 |
FROM parts p |
|
312 |
WHERE p.id NOT IN ( SELECT distinct parts_id from inventory) |
|
313 |
AND NOT p.obsolete |
|
314 |
AND p.rop != 0 |
|
315 |
) |
|
316 |
|
|
317 |
SELECT p.id |
|
318 |
FROM parts p |
|
319 |
LEFT JOIN available ava ON ava.parts_id = p.id |
|
320 |
WHERE ( ava.sum < p.rop ) |
|
321 |
AND p.id NOT IN ( SELECT part_id FROM purchase_basket_items ) |
|
322 |
AND NOT p.obsolete |
|
323 |
ORDER BY p.partnumber |
|
281 | 324 |
SQL |
282 |
|
|
283 |
my $parts = SL::DB::Manager::Part->get_objects_from_sql( sql => $query ); |
|
325 |
my @ids = selectall_array_query($::form, $::form->get_standard_dbh, $query); |
|
326 |
return unless scalar @ids; |
|
327 |
my $parts = SL::DB::Manager::Part->get_all( query => [ id => \@ids ] ); |
|
284 | 328 |
my $parts_to_order = [ grep { !$_->get_open_ordered_qty } @{$parts} ]; |
285 |
my $parts_ordered = [ map { $_->id } grep { $_->get_open_ordered_qty } @{$parts} ]; |
|
286 | 329 |
return $parts_to_order if !$ordered; |
330 |
my $parts_ordered = [ |
|
331 |
map { $_->id } grep { $_->get_open_ordered_qty } @{$parts} |
|
332 |
]; |
|
287 | 333 |
return $parts_ordered if $ordered; |
288 | 334 |
}; |
289 | 335 |
|
... | ... | |
296 | 342 |
model => 'Part', |
297 | 343 |
sorted => { |
298 | 344 |
_default => { |
299 |
by => 'partnumber',
|
|
300 |
dir => 1,
|
|
345 |
by => 'partnumber', |
|
346 |
dir => 1, |
|
301 | 347 |
}, |
302 |
partnumber => $::locale->text('Part Number'),
|
|
303 |
description => $::locale->text('Description'),
|
|
348 |
partnumber => $::locale->text('Part Number'), |
|
349 |
description => $::locale->text('Description'), |
|
304 | 350 |
}, |
305 |
query => [
|
|
306 |
(id => \@parts) x !!@parts,
|
|
351 |
query => [ |
|
352 |
(id => \@parts) x !!@parts, |
|
307 | 353 |
], |
308 | 354 |
paginated => { |
309 | 355 |
form_params => [ qw(page per_page) ], |
... | ... | |
321 | 367 |
$bar->add( |
322 | 368 |
action => [ |
323 | 369 |
t8('Action'), |
324 |
submit => [ '#form', { action => "DispositionManager/add_to_purchase_basket" } ], |
|
325 |
tooltip => t8('Add to purchase basket'), |
|
370 |
submit => [ |
|
371 |
'#form', { action => "DispositionManager/add_to_purchase_basket" } ], |
|
372 |
tooltip => t8('Add to purchase basket'), |
|
326 | 373 |
], |
327 | 374 |
); |
328 | 375 |
} |
... | ... | |
334 | 381 |
$bar->add( |
335 | 382 |
action => [ |
336 | 383 |
t8('Reload'), |
337 |
link => $self->url_for(controller => 'DispositionManager', action => 'show_basket'), |
|
384 |
link => $self->url_for( |
|
385 |
controller => 'DispositionManager', |
|
386 |
action => 'show_basket', |
|
387 |
), |
|
338 | 388 |
], |
339 | 389 |
action => [ |
340 | 390 |
t8('Action'), |
341 |
call => [ 'kivi.DispositionManager.create_order' ], |
|
342 |
tooltip => t8('Create purchase order'),
|
|
391 |
call => [ 'kivi.DispositionManager.create_order' ],
|
|
392 |
tooltip => t8('Create purchase order'), |
|
343 | 393 |
], |
344 | 394 |
); |
345 | 395 |
} |
SL/Controller/Part.pm | ||
---|---|---|
266 | 266 |
|
267 | 267 |
if ( !$self->_is_in_purchase_basket && scalar @{$self->part->makemodels}) { |
268 | 268 |
my $basket_part = SL::DB::PurchaseBasketItem->new( |
269 |
parts_id => $self->part->id,
|
|
270 |
qty => $self->part->ordersize || 1, # was ist wenn order_size < (rop-onhand) ist? sollte dann nicht (rop-onhand) genommen werden?
|
|
269 |
part_id => $self->part->id,
|
|
270 |
qty => $self->part->order_qty || 1, # was ist wenn order_qty < (rop-onhand) ist? sollte dann nicht (rop-onhand) genommen werden?
|
|
271 | 271 |
orderer => SL::DB::Manager::Employee->current, |
272 | 272 |
)->save; |
273 | 273 |
|
... | ... | |
1588 | 1588 |
sub _is_in_purchase_basket { |
1589 | 1589 |
my ( $self ) = @_; |
1590 | 1590 |
|
1591 |
return SL::DB::Manager::PurchaseBasketItem->get_all_count( query => [ parts_id => $self->part->id ] );
|
|
1591 |
return SL::DB::Manager::PurchaseBasketItem->get_all_count( query => [ part_id => $self->part->id ] ); |
|
1592 | 1592 |
} |
1593 | 1593 |
sub _is_ordered { |
1594 | 1594 |
my ( $self ) = @_; |
SL/DB/Manager/Part.pm | ||
---|---|---|
98 | 98 |
|
99 | 99 |
my $query = <<SQL; |
100 | 100 |
WITH |
101 |
open_qty AS ( SELECT parts_id, sum(oi.qty) as sum |
|
102 |
FROM orderitems oi |
|
103 |
LEFT OUTER JOIN oe o ON (oi.trans_id = o.id) |
|
104 |
WHERE |
|
105 |
oi.parts_id = ? |
|
106 |
AND (NOT COALESCE(o.quotation, FALSE)) |
|
107 |
AND (NOT COALESCE(o.closed, FALSE)) |
|
108 |
AND (NOT COALESCE(o.delivered, FALSE)) |
|
109 |
AND (COALESCE(o.vendor_id, 0) <> 0) |
|
110 |
GROUP BY oi.parts_id), |
|
111 |
|
|
112 |
open_orderitems_ids AS ( SELECT oi.id, parts_id |
|
113 |
FROM orderitems oi |
|
114 |
LEFT OUTER JOIN oe o ON (oi.trans_id = o.id) |
|
115 |
WHERE |
|
116 |
oi.parts_id = ? |
|
117 |
AND (NOT COALESCE(o.quotation, FALSE)) |
|
118 |
AND (NOT COALESCE(o.closed, FALSE)) |
|
119 |
AND (NOT COALESCE(o.delivered, FALSE)) |
|
120 |
AND (COALESCE(o.vendor_id, 0) <> 0) |
|
101 |
open_qty AS ( |
|
102 |
SELECT parts_id, sum(oi.qty) as sum |
|
103 |
FROM orderitems oi |
|
104 |
LEFT OUTER JOIN oe o ON (oi.trans_id = o.id) |
|
105 |
WHERE |
|
106 |
oi.parts_id = ? |
|
107 |
AND (NOT COALESCE(o.quotation, FALSE)) |
|
108 |
AND (NOT COALESCE(o.closed, FALSE)) |
|
109 |
AND (NOT COALESCE(o.delivered, FALSE)) |
|
110 |
AND (COALESCE(o.vendor_id, 0) <> 0) |
|
111 |
GROUP BY oi.parts_id |
|
121 | 112 |
), |
122 | 113 |
|
123 |
delivered_qty AS ( select parts_id, sum(qty) AS sum FROM delivery_order_items |
|
124 |
WHERE id IN (select to_id from record_links WHERE from_id IN (SELECT id FROM open_orderitems_ids) AND from_table = 'orderitems' AND to_table = 'delivery_order_items') AND parts_id = ? GROUP BY parts_id), |
|
114 |
open_orderitems_ids AS ( |
|
115 |
SELECT oi.id, parts_id |
|
116 |
FROM orderitems oi |
|
117 |
LEFT OUTER JOIN oe o ON (oi.trans_id = o.id) |
|
118 |
WHERE |
|
119 |
oi.parts_id = ? |
|
120 |
AND (NOT COALESCE(o.quotation, FALSE)) |
|
121 |
AND (NOT COALESCE(o.closed, FALSE)) |
|
122 |
AND (NOT COALESCE(o.delivered, FALSE)) |
|
123 |
AND (o.vendor_id is not null) |
|
124 |
), |
|
125 |
|
|
126 |
delivered_qty AS ( |
|
127 |
SELECT parts_id, sum(qty) AS sum |
|
128 |
FROM delivery_order_items |
|
129 |
WHERE id IN ( |
|
130 |
SELECT to_id from record_links |
|
131 |
WHERE |
|
132 |
from_id IN ( SELECT id FROM open_orderitems_ids) |
|
133 |
AND from_table = 'orderitems' |
|
134 |
AND to_table = 'delivery_order_items' |
|
135 |
) AND parts_id = ? |
|
136 |
GROUP BY parts_id |
|
137 |
), |
|
125 | 138 |
|
126 |
open_ordered_qty AS ( select oq.parts_id, oq.sum AS ordered_sum, iif(dq.sum is null,0.00,dq.sum) AS sum, sum(iif(oq.sum is null,0.00,oq.sum) - iif(dq.sum is null,0.00,dq.sum)) AS open_qty |
|
127 |
FROM open_qty oq |
|
128 |
LEFT JOIN delivered_qty dq ON dq.parts_id = oq.parts_id |
|
129 |
GROUP BY oq.parts_id, oq.sum, dq.sum) |
|
139 |
open_ordered_qty AS ( |
|
140 |
SELECT |
|
141 |
oq.parts_id, |
|
142 |
oq.sum AS ordered_sum, |
|
143 |
COALESCE(dq.sum,0.00) AS sum, |
|
144 |
sum(COALESCE(oq.sum,0.00) - COALESCE(dq.sum,0.00)) AS open_qty |
|
145 |
FROM open_qty oq |
|
146 |
LEFT JOIN delivered_qty dq ON dq.parts_id = oq.parts_id |
|
147 |
GROUP BY oq.parts_id, oq.sum, dq.sum |
|
148 |
) |
|
130 | 149 |
|
131 | 150 |
SELECT open_qty FROM open_ordered_qty |
132 | 151 |
|
133 | 152 |
SQL |
134 | 153 |
|
135 |
my ($open_qty) = selectrow_query($::form, $class->object_class->init_db->dbh, $query, $part_id, $part_id, $part_id); |
|
136 |
### Über Rose dauert das ganze 3 minuten |
|
137 |
# my $openitems = SL::DB::Manager::OrderItem->get_all(where => [ |
|
138 |
# parts_id => $part_id, |
|
139 |
# 'order.closed' => 0, |
|
140 |
# 'order.quotation' => 0, |
|
141 |
# 'order.delivered' => 0, |
|
142 |
# # 'order.type' => { ilike => 'purchase_order' }, |
|
143 |
# 'order.vendor_id' => { ne => 0 } |
|
144 |
# ], |
|
145 |
# with_objects => ['order'], |
|
146 |
# ); |
|
147 |
# $main::lxdebug->dump(0, 'WH:OPEN ', $openitems); |
|
148 |
|
|
149 |
# return 0 unless $openitems; |
|
150 |
# my $open_qty = 0; |
|
151 |
# my $ordered_qty = 0; |
|
152 |
# my $delivered_qty = 0; |
|
153 |
# for my $openitem (@{ $openitems }) { |
|
154 |
## if($openitem->order->type eq 'purchase_order') { |
|
155 |
# $ordered_qty += $openitem->qty; |
|
156 |
# $delivered_qty += $openitem->delivered_qty; |
|
157 |
## } |
|
158 |
# } |
|
159 |
## $open_qty = map{ $_->qty - $_->delivered_qty } @{$openitems}; |
|
160 |
# $open_qty = $ordered_qty - $delivered_qty; |
|
161 |
|
|
162 |
# return $open_qty; |
|
154 |
my ($open_qty) = selectrow_query( |
|
155 |
$::form, $class->object_class->init_db->dbh, |
|
156 |
$query, $part_id, $part_id, $part_id |
|
157 |
); |
|
163 | 158 |
|
164 | 159 |
return $open_qty if $open_qty > 0; |
165 | 160 |
return 0; |
SL/DB/MetaSetup/MakeModel.pm | ||
---|---|---|
14 | 14 |
lastcost => { type => 'numeric', precision => 15, scale => 5 }, |
15 | 15 |
lastupdate => { type => 'date' }, |
16 | 16 |
make => { type => 'integer' }, |
17 |
min_order_qty => { type => 'numeric', precision => 15, scale => 5 }, |
|
18 | 17 |
model => { type => 'text' }, |
19 | 18 |
mtime => { type => 'timestamp' }, |
20 | 19 |
part_description => { type => 'text' }, |
SL/DB/MetaSetup/Part.pm | ||
---|---|---|
31 | 31 |
notes => { type => 'text' }, |
32 | 32 |
obsolete => { type => 'boolean', default => 'false', not_null => 1 }, |
33 | 33 |
onhand => { type => 'numeric', default => '0', precision => 25, scale => 5 }, |
34 |
order_qty => { type => 'numeric', default => '0', not_null => 1, precision => 15, scale => 5 }, |
|
34 | 35 |
part_type => { type => 'enum', check_in => [ 'part', 'service', 'assembly', 'assortment' ], db_type => 'part_type_enum', not_null => 1 }, |
35 | 36 |
partnumber => { type => 'text', not_null => 1 }, |
36 | 37 |
partsgroup_id => { type => 'integer' }, |
SL/DB/MetaSetup/PurchaseBasketItem.pm | ||
---|---|---|
11 | 11 |
__PACKAGE__->meta->columns( |
12 | 12 |
cleared => { type => 'boolean', default => 'false', not_null => 1 }, |
13 | 13 |
id => { type => 'serial', not_null => 1 }, |
14 |
itime => { type => 'timestamp', default => 'now()' }, |
|
15 |
mtime => { type => 'timestamp' }, |
|
14 | 16 |
orderer_id => { type => 'integer' }, |
15 |
parts_id => { type => 'integer' },
|
|
16 |
qty => { type => 'numeric', precision => 15, scale => 5 }, |
|
17 |
part_id => { type => 'integer' },
|
|
18 |
qty => { type => 'numeric', not_null => 1, precision => 15, scale => 5 },
|
|
17 | 19 |
); |
18 | 20 |
|
19 | 21 |
__PACKAGE__->meta->primary_key_columns([ 'id' ]); |
20 | 22 |
|
23 |
__PACKAGE__->meta->allow_inline_column_values(1); |
|
24 |
|
|
21 | 25 |
__PACKAGE__->meta->foreign_keys( |
22 | 26 |
orderer => { |
23 | 27 |
class => 'SL::DB::Employee', |
... | ... | |
26 | 30 |
|
27 | 31 |
part => { |
28 | 32 |
class => 'SL::DB::Part', |
29 |
key_columns => { parts_id => 'id' },
|
|
33 |
key_columns => { part_id => 'id' }, |
|
30 | 34 |
}, |
31 | 35 |
); |
32 | 36 |
|
SL/DB/Part.pm | ||
---|---|---|
8 | 8 |
use Rose::DB::Object::Helpers qw(as_tree); |
9 | 9 |
|
10 | 10 |
use SL::Locale::String qw(t8); |
11 |
use SL::Helper::Inventory; |
|
11 | 12 |
use SL::DBUtils; |
12 | 13 |
use SL::DB::MetaSetup::Part; |
13 | 14 |
use SL::DB::Manager::Part; |
... | ... | |
103 | 104 |
__PACKAGE__->before_save('_before_save_set_partnumber'); |
104 | 105 |
__PACKAGE__->before_save('_before_save_set_assembly_weight'); |
105 | 106 |
|
106 |
sub onhandqty_as_number { |
|
107 |
my ($self, $string) = @_; |
|
108 |
$self->onhandqty($::form->parse_amount(\%::myconfig, $string)) if @_ > 1; |
|
109 |
return $::form->format_amount(\%::myconfig, $self->onhandqty, 2); |
|
110 |
} |
|
111 |
|
|
112 | 107 |
sub init_onhandqty{ |
113 | 108 |
my ($self) = @_; |
114 | 109 |
my $qty = SL::Helper::Inventory::get_onhand(part => $self->id); |
115 | 110 |
return $qty; |
116 | 111 |
} |
117 | 112 |
|
118 |
sub stockqty_as_number { |
|
119 |
my ($self, $string) = @_; |
|
120 |
$self->stockqty($::form->parse_amount(\%::myconfig, $string)) if @_ > 1; |
|
121 |
return $::form->format_amount(\%::myconfig, $self->stockqty, 2); |
|
122 |
} |
|
123 |
|
|
124 | 113 |
sub init_stockqty{ |
125 | 114 |
my ($self) = @_; |
126 | 115 |
my $qty = SL::Helper::Inventory::get_stock(part => $self->id); |
127 | 116 |
return $qty; |
128 | 117 |
} |
129 | 118 |
|
130 |
sub get_open_ordered_qty_as_number { |
|
131 |
my ($self, $string) = @_; |
|
132 |
$self->get_open_ordered_qty($::form->parse_amount(\%::myconfig, $string)) if @_ > 1; |
|
133 |
return $::form->format_amount(\%::myconfig, $self->get_open_ordered_qty, 2); |
|
134 |
} |
|
135 |
|
|
136 | 119 |
sub init_get_open_ordered_qty { |
137 | 120 |
my $self = shift; |
138 | 121 |
my $result = SL::DB::Manager::Part->get_open_ordered_qty($self->id); |
139 | 122 |
|
140 | 123 |
return $result; |
141 | 124 |
} |
142 |
#sub reservedqty_as_number { |
|
143 |
# my ($self, $string) = @_; |
|
144 |
# $self->reservedqty($::form->parse_amount(\%::myconfig, $string)) if @_ > 1; |
|
145 |
# return $::form->format_amount(\%::myconfig, $self->reservedqty, $self->places); |
|
146 |
#} |
|
147 |
|
|
148 |
#sub init_onhandqty{ |
|
149 |
# my ($self) = @_; |
|
150 |
# my $qty = get_onhand(part => $self->id); |
|
151 |
# return $qty; |
|
152 |
#} |
|
153 |
>>>>>>> cf3ff322d1 (Einkaufshelfer/Dispositionsmanager bescheleunigt) |
|
154 | 125 |
|
155 | 126 |
sub _before_save_set_partnumber { |
156 | 127 |
my ($self) = @_; |
... | ... | |
642 | 613 |
} |
643 | 614 |
|
644 | 615 |
sub vendor_dropdown { |
645 |
my ( $self ) = @_;
|
|
616 |
my ($self) = @_;
|
|
646 | 617 |
|
647 | 618 |
my @vendor_dd; |
648 |
# $main::lxdebug->dump(0, 'WH:MakeModels ', $_[0]->makemodels); |
|
649 | 619 |
|
650 |
foreach my $mm ( @{$_[0]->makemodels} ){
|
|
620 |
foreach my $mm ( @{$self->makemodels} ){
|
|
651 | 621 |
my $vendor = SL::DB::Manager::Vendor->get_first( where => [ id => $mm->make ] ); |
652 | 622 |
my @tmp = ({ title => $vendor->vendornumber . "--" .$vendor->name . " (" . $::form->format_amount(\%::myconfig, $mm->lastcost, 2) . ")", value => $vendor->{id} }); |
653 | 623 |
push @vendor_dd, @tmp; |
js/locale/de.js | ||
---|---|---|
47 | 47 |
"Delete requirement spec":"Pflichtenheft löschen", |
48 | 48 |
"Delete template":"Vorlage löschen", |
49 | 49 |
"Delete text block":"Textblock löschen", |
50 |
"Details of article number \"#1\"":"Details von Artikel \"#1\"", |
|
50 | 51 |
"Do you really want to cancel?":"Möchten Sie wirklich abbrechen?", |
51 | 52 |
"Do you really want to continue?":"Möchten Sie wirklich fortfahren?", |
52 | 53 |
"Do you really want to delete the selected documents?":"Möchten Sie wirklich diese Dateien löschen?", |
js/locale/en.js | ||
---|---|---|
47 | 47 |
"Delete requirement spec":"", |
48 | 48 |
"Delete template":"", |
49 | 49 |
"Delete text block":"", |
50 |
"Details of article number \"#1\"":"", |
|
50 | 51 |
"Do you really want to cancel?":"", |
51 | 52 |
"Do you really want to continue?":"", |
52 | 53 |
"Do you really want to delete the selected documents?":"", |
locale/de/all | ||
---|---|---|
308 | 308 |
'All general ledger entries' => 'Alle Hauptbucheinträge', |
309 | 309 |
'All groups' => 'Alle Gruppen', |
310 | 310 |
'All modules' => 'Alle Module', |
311 |
'All parts of vendor odered by onhand' => 'Alle Artikel des Lieferanten sortiert nach Lagerbestand', |
|
311 | 312 |
'All partsgroups' => 'Alle Warengruppen', |
312 | 313 |
'All pay postings successfully imported.' => 'Alle Lohnbuchungen erfolgreich importiert.', |
313 | 314 |
'All payments have already been posted.' => 'Es wurden bereits alle Zahlungen verbucht.', |
... | ... | |
331 | 332 |
'Already counted' => 'Bereits erfasst', |
332 | 333 |
'Already imported entries (duplicates)' => 'Bereits importierte Einträge (Duplikate)', |
333 | 334 |
'Already imported: ' => 'Bereits importiert:', |
334 |
'Also with reserved Qty' => 'inklusive Reservierungen', |
|
335 | 335 |
'Always edit assembly items (user can change/delete items even if assemblies are already produced)' => 'Erzeugnisbestandteile verändern (Löschen/Umsortieren) auch nachdem dieses Erzeugnis schon produziert wurde.', |
336 | 336 |
'Always edit assortment items (user can change/delete items even if assortments are already used)' => 'Sortimentsbestandteile verändern (Löschen/Umsortieren), auch nachdem dieses Sortiment schon verwendet wurde.', |
337 | 337 |
'Always save orders with a projectnumber (create new projects)' => 'Aufträge immer mit Projektnummer speichern (neue Projekte erstellen)', |
... | ... | |
386 | 386 |
'Article Code' => 'Artikelkürzel', |
387 | 387 |
'Article classification' => 'Artikel-Klassifizierung', |
388 | 388 |
'Article data' => 'Artikeldaten', |
389 |
'Article details' => 'Artikeldetails', |
|
389 | 390 |
'Article type' => 'Artikeltyp', |
390 | 391 |
'Articles' => 'Artikel', |
391 | 392 |
'As a result, the saved onhand values of the present goods can be stored into a warehouse designated by you, or will be reset for a proper warehouse tracking' => 'Als Konsequenz können die gespeicherten Mengen entweder in ein Lager überführt werden, oder für eine frische Lagerverwaltung resettet werden.', |
... | ... | |
446 | 447 |
'Automatically created invoice for fee and interest for dunning %s' => 'Automatisch erzeugte Rechnung für Gebühren und Zinsen zu Mahnung %s', |
447 | 448 |
'Available' => 'Verfügbar', |
448 | 449 |
'Available Prices' => 'Mögliche Preise', |
450 |
'Available Stock' => 'verfügbarer Bestand', |
|
449 | 451 |
'Available qty' => 'Lagerbestand', |
450 | 452 |
'Available to all users' => 'Für alle BenutzerInnen verfügbar', |
451 | 453 |
'BALANCE SHEET' => 'BILANZ', |
... | ... | |
1200 | 1202 |
'Detailed information about this customer' => 'Detaillierte Informationen über diesen Kunden', |
1201 | 1203 |
'Details' => 'Details', |
1202 | 1204 |
'Details (one letter abbreviation)' => 'D', |
1205 |
'Details of article number "#1"' => 'Details von Artikel "#1"', |
|
1203 | 1206 |
'Details: #1' => 'Details: #1', |
1204 | 1207 |
'Developer Tools' => 'Developer Tools', |
1205 | 1208 |
'Dial command missing in kivitendo configuration\'s [cti] section' => 'Wählbefehl fehlt im Abschnitt [cti] der kivitendo-Konfiguration', |
... | ... | |
1220 | 1223 |
'Display in basic data tab' => 'Im Reiter Basisdaten anzeigen', |
1221 | 1224 |
'Display options' => 'Anzeigeoptionen', |
1222 | 1225 |
'Displayable Name Preferences' => 'Einstellungen für Anzeigenamen', |
1223 |
'Disposition manager' => 'Dispositionsmanager', |
|
1224 | 1226 |
'Do not change the tax rate of taxkey 0.' => 'Ändern Sie nicht den Steuersatz vom Steuerschlüssel 0.', |
1225 | 1227 |
'Do not check for duplicates' => 'Nicht nach Dubletten suchen', |
1226 | 1228 |
'Do not create Factur-X/ZUGFeRD invoices' => 'Keine Factur-X-/ZUGFeRD-Rechnungen erzeugen', |
... | ... | |
2603 | 2605 |
'Order Date missing!' => 'Auftragsdatum fehlt!', |
2604 | 2606 |
'Order Number' => 'Auftragsnummer', |
2605 | 2607 |
'Order Number missing!' => 'Auftragsnummer fehlt!', |
2608 |
'Order Size' => 'Bestellmenge', |
|
2606 | 2609 |
'Order amount' => 'Auftragswert', |
2607 | 2610 |
'Order data' => 'Auftragsinformationen', |
2608 | 2611 |
'Order deleted!' => 'Auftrag gelöscht!', |
... | ... | |
2614 | 2617 |
'Order/Item row name' => 'Name der Auftrag-/Positions-Zeilen', |
2615 | 2618 |
'Order/Item/Stock row name' => 'Name der Auftrag-/Positions-/Lager-Zeilen', |
2616 | 2619 |
'Order/RFQ Number' => 'Belegnummer', |
2617 |
'Order:' => 'Auftrag:', |
|
2618 | 2620 |
'OrderItem' => 'Position', |
2619 | 2621 |
'Ordered' => 'Von Kunden bestellt', |
2620 |
'Ordered qty' => 'bestellt', |
|
2621 | 2622 |
'Ordered purchase' => 'Bestellte Menge', |
2622 | 2623 |
'Orderer' => 'BestellerIn', |
2623 | 2624 |
'Orders' => 'Aufträge', |
... | ... | |
2690 | 2691 |
'Part Type' => 'Artikel-Typ', |
2691 | 2692 |
'Part Unit' => 'Einheit', |
2692 | 2693 |
'Part added to purchasebasket' => 'Zu Einkaufkorb hinzugefügt', |
2693 |
'Part already in purchasebasket or has no vendor' => 'Artikel ist schon im Bestellwarenkorb oder hat keinen Lieferanten', |
|
2694 | 2694 |
'Part already in purchasebasket' => 'Schon im Einkaufskorb', |
2695 |
'Part already in purchasebasket or has no vendor' => 'Artikel ist schon im Bestellwarenkorb oder hat keinen Lieferanten', |
|
2695 | 2696 |
'Part already ordered' => 'Artikel ist bestellt', |
2696 | 2697 |
'Part classifications' => 'Artikel-Klassifizierungen', |
2697 | 2698 |
'Part marked as "Shop part"' => 'Markiert als Shopartikel', |
... | ... | |
2707 | 2708 |
'Parts Classification' => 'Artikel-Klassifizierung', |
2708 | 2709 |
'Parts Inventory' => 'Warenliste', |
2709 | 2710 |
'Parts Master Data' => 'Artikelstammdaten', |
2710 |
'Parts short onhand' => 'Artikel mit geringer Lagermenge', |
|
2711 | 2711 |
'Parts with existing part numbers' => 'Artikel mit existierender Artikelnummer', |
2712 | 2712 |
'Parts, services and assemblies' => 'Waren, Dienstleistungen und Erzeugnisse', |
2713 | 2713 |
'Partsgroup' => 'Warengruppe', |
... | ... | |
3139 | 3139 |
'Rename Images' => 'Bilder umbenennen', |
3140 | 3140 |
'Rename attachment' => 'Dateianhang umbenennen', |
3141 | 3141 |
'Renumber sections and function blocks' => 'Abschnitte/Funktionsblöcke neu nummerieren', |
3142 |
'Reorder Level List' => 'Meldebestandsliste', |
|
3142 | 3143 |
'Replace legacy order controller with new one' => 'Neuen Auftrags-Controller verwenden', |
3143 | 3144 |
'Replace the orphaned currencies by other not orphaned currencies. To do so, please delete the currency in the textfields above and replace it by another currency. You could loose or change unintentionally exchangerates. Go on very carefully since you could destroy transactions.' => 'Ersetze die Währungen durch andere gültige Währungen. Wenn Sie sich hierfür entscheiden, ersetzen Sie bitte alle Währungen, die oben angegeben sind, durch Währungen, die in Ihrem System ordnungsgemäß eingetragen sind. Alle eingetragenen Wechselkurse für die verwaiste Währung werden dabei gelöscht. Bitte gehen Sie sehr vorsichtig vor, denn die betroffenen Buchungen können unter Umständen kaputt gehen.', |
3144 | 3145 |
'Report Positions' => 'Berichte', |
... | ... | |
3484 | 3485 |
'Shoporders' => 'Shopbest.', |
3485 | 3486 |
'Shops' => 'Webshops', |
3486 | 3487 |
'Short' => 'Knapp', |
3487 |
'Short onhand Ordered' => 'Geringe Lagermenge, aber bestellt', |
|
3488 | 3488 |
'Short onhand' => 'Geringe Lagermenge', |
3489 | 3489 |
'Should VAT ID or taxnumber be unique for all vendors? This is checked when saving a vendor\'s master data. One of the fields is sufficient and required.' => 'Soll die UStID oder Steuernummer eindeutig über alle Lieferanten sein? Dies wird beim Speichern von Lieferantenstammdaten geprüft. Eines dieser Felder reicht aus und muss angegeben sein.', |
3490 | 3490 |
'Should VAT ID or taxnumber be unique for customers? This is checked when saving a customer\'s master data. One of the fields is sufficient and required.' => 'Soll die UStID oder Steuernummer eindeutig über alle Kunden sein? Dies wird beim Speichern von Kundenstammdaten geprüft. Eines dieser Felder reicht aus und muss angegeben sein.', |
... | ... | |
4161 | 4161 |
'There are no entries that match the filter.' => 'Es gibt keine Einträge, auf die der Filter zutrifft.', |
4162 | 4162 |
'There are no items in stock.' => 'Dieser Artikel ist nicht eingelagert.', |
4163 | 4163 |
'There are no items on your TODO list at the moment.' => 'Ihre Aufgabenliste enthält momentan keine Einträge.', |
4164 |
'There are no items selected' => 'Es wurden keine Positionen ausgewählt', |
|
4164 | 4165 |
'There are no orders for the selected time period.' => 'Es gibt für den ausgewählten Zeitraum keine Aufträge.', |
4165 | 4166 |
'There are no record templates yet.' => 'Es gibt noch keine Belegvorlagen.', |
4166 | 4167 |
'There are parts with no reclamation reason at position:' => 'Es git Artikel mit keinem Reklamationsgrund an Position:', |
... | ... | |
4322 | 4323 |
'Total' => 'Summe', |
4323 | 4324 |
'Total Fees' => 'Kumulierte Gebühren', |
4324 | 4325 |
'Total Sales Orders Value' => 'Auftragseingang', |
4326 |
'Total Stock' => 'Gesamtbestand', |
|
4325 | 4327 |
'Total number of entries' => 'Gesamtzahl Einträge', |
4326 | 4328 |
'Total stock value' => 'Gesamter Bestandswert', |
4327 | 4329 |
'Total sum' => 'Gesamtsumme', |
... | ... | |
4536 | 4538 |
'VAT ID' => 'USt-IdNr.', |
4537 | 4539 |
'VAT ID and/or taxnumber must be given.' => 'UStId und/oder Steuernummer muss angegeben werden.', |
4538 | 4540 |
'VN' => 'Kred.-Nr.', |
4539 |
'VPE' => '', |
|
4540 | 4541 |
'Valid' => 'Gültig', |
4541 | 4542 |
'Valid are integer values and floating point numbers, e.g. 4.75h = 4 hours and 45 minutes.' => 'Erlaubt sind ganzzahlige Werte und Kommawerte: Beispiel: 4,75h = 4 Stunden und 45 Minuten.', |
4542 | 4543 |
'Valid for Purchase' => 'Gültig für Einkauf', |
... | ... | |
4939 | 4940 |
'once' => 'einmalig', |
4940 | 4941 |
'one time' => 'einmalig', |
4941 | 4942 |
'one-time execution' => 'einmalige Ausführung', |
4942 |
'onhand' => 'Auf Lager', |
|
4943 | 4943 |
'only OB Transactions' => 'nur EB-Buchungen', |
4944 | 4944 |
'open' => 'Offen', |
4945 | 4945 |
'order' => 'Reihenfolge', |
... | ... | |
4983 | 4983 |
'revert deleted' => 'löschen rückgängig', |
4984 | 4984 |
'rfq_list' => 'anfragenliste', |
4985 | 4985 |
'rma_delivery_order_list' => 'lieferscheinliste_rma', |
4986 |
'rop' => 'Mindestlagerbestand', |
|
4987 | 4986 |
'running' => 'läuft', |
4988 | 4987 |
'sales tax identification number' => 'USt-IdNr.', |
4989 | 4988 |
'sales_delivery_order_list' => 'lieferscheinliste_verkauf', |
locale/en/all | ||
---|---|---|
274 | 274 |
'Add text block' => '', |
275 | 275 |
'Add time recording article' => '', |
276 | 276 |
'Add title' => '', |
277 |
'Add to basket' => '', |
|
278 |
'Add to purchase basket' => '', |
|
277 | 279 |
'Add unit' => '', |
278 | 280 |
'Added sections and function blocks: #1' => '', |
279 | 281 |
'Added text blocks: #1' => '', |
... | ... | |
306 | 308 |
'All general ledger entries' => '', |
307 | 309 |
'All groups' => '', |
308 | 310 |
'All modules' => '', |
311 |
'All parts of vendor odered by onhand' => '', |
|
309 | 312 |
'All partsgroups' => '', |
310 | 313 |
'All pay postings successfully imported.' => '', |
311 | 314 |
'All payments have already been posted.' => '', |
... | ... | |
383 | 386 |
'Article Code' => '', |
384 | 387 |
'Article classification' => '', |
385 | 388 |
'Article data' => '', |
389 |
'Article details' => '', |
|
386 | 390 |
'Article type' => '', |
387 | 391 |
'Articles' => '', |
388 | 392 |
'As a result, the saved onhand values of the present goods can be stored into a warehouse designated by you, or will be reset for a proper warehouse tracking' => '', |
... | ... | |
443 | 447 |
'Automatically created invoice for fee and interest for dunning %s' => '', |
444 | 448 |
'Available' => '', |
445 | 449 |
'Available Prices' => '', |
450 |
'Available Stock' => '', |
|
446 | 451 |
'Available qty' => '', |
447 | 452 |
'Available to all users' => '', |
448 | 453 |
'BALANCE SHEET' => '', |
... | ... | |
894 | 899 |
'Create new version' => '', |
895 | 900 |
'Create one from the context menu by right-clicking on this text.' => '', |
896 | 901 |
'Create order' => '', |
902 |
'Create purchase order' => '', |
|
897 | 903 |
'Create sales invoices with Factur-X/ZUGFeRD data' => '', |
898 | 904 |
'Create sales invoices with Swiss QR-bill' => '', |
899 | 905 |
'Create tables' => '', |
... | ... | |
1195 | 1201 |
'Detailed information about this contact' => '', |
1196 | 1202 |
'Detailed information about this customer' => '', |
1197 | 1203 |
'Details' => '', |
1198 |
'Details (one letter abbreviation)' => '', |
|
1204 |
'Details (one letter abbreviation)' => 'D', |
|
1205 |
'Details of article number "#1"' => '', |
|
1199 | 1206 |
'Details: #1' => '', |
1200 | 1207 |
'Developer Tools' => '', |
1201 | 1208 |
'Dial command missing in kivitendo configuration\'s [cti] section' => '', |
... | ... | |
2189 | 2196 |
'List of jobs' => '', |
2190 | 2197 |
'List of tax zones' => '', |
2191 | 2198 |
'List open SEPA exports' => '', |
2199 |
'List short onhand' => '', |
|
2192 | 2200 |
'List time recordings of all staff members' => '', |
2193 | 2201 |
'Listprice' => '', |
2194 | 2202 |
'Load' => '', |
... | ... | |
2290 | 2298 |
'Microfiche' => '', |
2291 | 2299 |
'Minimize Panel' => '', |
2292 | 2300 |
'Minimum Amount' => '', |
2301 |
'Minimum order quantity' => '', |
|
2293 | 2302 |
'Miscellaneous' => '', |
2294 | 2303 |
'Missing \'description\' field.' => '', |
2295 | 2304 |
'Missing \'tag\' field.' => '', |
... | ... | |
2390 | 2399 |
'No Shopdescription' => '', |
2391 | 2400 |
'No Shopimages' => '', |
2392 | 2401 |
'No VAT Info for this Factur-X/ZUGFeRD invoice, please ask your vendor to add this for his Factur-X/ZUGFeRD data.' => '', |
2402 |
'No Vendor' => '', |
|
2393 | 2403 |
'No Vendor was found matching the search parameters.' => '', |
2394 | 2404 |
'No account selected. Please select an account.' => '', |
2395 | 2405 |
'No action defined.' => '', |
... | ... | |
2479 | 2489 |
'No valid number entered for pricegroup "#1".' => '', |
2480 | 2490 |
'No vendor has been selected yet.' => '', |
2481 | 2491 |
'No vendor selected or found!' => '', |
2492 |
'No vendors to add to purchasebasket' => '', |
|
2482 | 2493 |
'No warehouse has been created yet or the quantity of the bins is not configured yet.' => '', |
2483 | 2494 |
'No webdav backend enabled.' => '', |
2484 | 2495 |
'No year given for method year' => '', |
... | ... | |
2593 | 2604 |
'Order Date missing!' => '', |
2594 | 2605 |
'Order Number' => '', |
2595 | 2606 |
'Order Number missing!' => '', |
2607 |
'Order Size' => '', |
|
2596 | 2608 |
'Order amount' => '', |
2597 | 2609 |
'Order data' => '', |
2598 | 2610 |
'Order deleted!' => '', |
2599 | 2611 |
'Order item search' => '', |
2600 | 2612 |
'Order probability' => '', |
2601 | 2613 |
'Order probability & expected billing date' => '', |
2614 |
'Order quantity' => '', |
|
2602 | 2615 |
'Order value periodicity' => '', |
2603 | 2616 |
'Order/Item row name' => '', |
2604 | 2617 |
'Order/Item/Stock row name' => '', |
2605 | 2618 |
'Order/RFQ Number' => '', |
2606 | 2619 |
'OrderItem' => '', |
2607 | 2620 |
'Ordered' => '', |
2621 |
'Ordered purchase' => '', |
|
2622 |
'Orderer' => '', |
|
2608 | 2623 |
'Orders' => '', |
2609 | 2624 |
'Orders / Delivery Orders deleteable' => '', |
2610 | 2625 |
'Orders in Webshop' => '', |
... | ... | |
2674 | 2689 |
'Part Test' => '', |
2675 | 2690 |
'Part Type' => '', |
2676 | 2691 |
'Part Unit' => '', |
2692 |
'Part added to purchasebasket' => '', |
|
2693 |
'Part already in purchasebasket' => '', |
|
2694 |
'Part already in purchasebasket or has no vendor' => '', |
|
2695 |
'Part already ordered' => '', |
|
2677 | 2696 |
'Part classifications' => '', |
2678 | 2697 |
'Part marked as "Shop part"' => '', |
2679 | 2698 |
'Part picker' => '', |
... | ... | |
2973 | 2992 |
'Purchase Reclamation' => '', |
2974 | 2993 |
'Purchase Reclamations' => '', |
2975 | 2994 |
'Purchase Reclamations deleteable' => '', |
2995 |
'Purchase basket' => '', |
|
2976 | 2996 |
'Purchase delivery order' => '', |
2977 | 2997 |
'Purchase invoices' => '', |
2978 | 2998 |
'Purchase invoices changeable' => '', |
... | ... | |
3089 | 3109 |
'Registration' => '', |
3090 | 3110 |
'Relaxed (UTF-8)' => '', |
3091 | 3111 |
'Release From Stock' => '', |
3112 |
'Reload' => '', |
|
3092 | 3113 |
'Remaining' => '', |
3093 | 3114 |
'Remaining Amount' => '', |
3094 | 3115 |
'Remaining Net Amount' => '', |
... | ... | |
3117 | 3138 |
'Rename Images' => '', |
3118 | 3139 |
'Rename attachment' => '', |
3119 | 3140 |
'Renumber sections and function blocks' => '', |
3141 |
'Reorder Level List' => '', |
|
3120 | 3142 |
'Replace legacy order controller with new one' => '', |
3121 | 3143 |
'Replace the orphaned currencies by other not orphaned currencies. To do so, please delete the currency in the textfields above and replace it by another currency. You could loose or change unintentionally exchangerates. Go on very carefully since you could destroy transactions.' => '', |
3122 | 3144 |
'Report Positions' => '', |
... | ... | |
3182 | 3204 |
'Risk' => '', |
3183 | 3205 |
'Risk levels' => '', |
3184 | 3206 |
'Risks' => '', |
3207 |
'Rop' => '', |
|
3185 | 3208 |
'Rounding' => '', |
3186 | 3209 |
'Rounding Gain' => '', |
3187 | 3210 |
'Rounding Loss' => '', |
... | ... | |
3461 | 3484 |
'Shoporders' => '', |
3462 | 3485 |
'Shops' => '', |
3463 | 3486 |
'Short' => '', |
3487 |
'Short onhand' => '', |
|
3464 | 3488 |
'Should VAT ID or taxnumber be unique for all vendors? This is checked when saving a vendor\'s master data. One of the fields is sufficient and required.' => '', |
3465 | 3489 |
'Should VAT ID or taxnumber be unique for customers? This is checked when saving a customer\'s master data. One of the fields is sufficient and required.' => '', |
3466 | 3490 |
'Should ap transactions be and when should they be changeable or deleteable after posting?' => '', |
... | ... | |
3522 | 3546 |
'Show overdue sales quotations and requests for quotations...' => '', |
3523 | 3547 |
'Show parts' => '', |
3524 | 3548 |
'Show parts longdescription (notes) in select list' => '', |
3549 |
'Show purchase basket' => '', |
|
3525 | 3550 |
'Show purchase letters report' => '', |
3526 | 3551 |
'Show record tab in customer' => '', |
3527 | 3552 |
'Show record tab in vendor' => '', |
... | ... | |
4134 | 4159 |
'There are no entries that match the filter.' => '', |
4135 | 4160 |
'There are no items in stock.' => '', |
4136 | 4161 |
'There are no items on your TODO list at the moment.' => '', |
4162 |
'There are no items selected' => '', |
|
4137 | 4163 |
'There are no orders for the selected time period.' => '', |
4138 | 4164 |
'There are no record templates yet.' => '', |
4139 | 4165 |
'There are parts with no reclamation reason at position:' => '', |
... | ... | |
4295 | 4321 |
'Total' => '', |
4296 | 4322 |
'Total Fees' => '', |
4297 | 4323 |
'Total Sales Orders Value' => '', |
4324 |
'Total Stock' => '', |
|
4298 | 4325 |
'Total number of entries' => '', |
4299 | 4326 |
'Total stock value' => '', |
4300 | 4327 |
'Total sum' => '', |
scripts/rose_auto_create_model.pl | ||
---|---|---|
83 | 83 |
|
84 | 84 |
assembly => { parts_id => 'part', id => 'assembly_part' }, |
85 | 85 |
assortment_items => { parts_id => 'part' }, |
86 |
purchase_basket_items => { parts_id => 'part' }, |
|
87 | 86 |
|
88 | 87 |
dunning => { trans_id => 'invoice', fee_interest_ar_id => 'fee_interest_invoice' }, |
89 | 88 |
}, |
sql/Pg-upgrade2/add_orderer.sql | ||
---|---|---|
1 |
-- @tag: add_orderer |
|
2 |
-- @description: Neue Spalte Besteller in purchase_basket_items, orderitems und delivery_order_items |
|
3 |
-- @depends: purchase_basket_items |
|
4 |
-- @ignore: 0 |
|
5 |
|
|
6 |
ALTER TABLE purchase_basket_items ADD COLUMN orderer_id INTEGER REFERENCES employee(id); |
|
7 |
ALTER TABLE orderitems ADD COLUMN orderer_id INTEGER REFERENCES employee(id); |
|
8 |
ALTER TABLE delivery_order_items ADD COLUMN orderer_id INTEGER REFERENCES employee(id); |
sql/Pg-upgrade2/add_parts_order_qty.sql | ||
---|---|---|
1 |
-- @tag: add_parts_order_qty |
|
2 |
-- @description: Bestellmenge für Artikel |
|
3 |
-- @depends: purchase_basket_items |
|
4 |
-- @ignore: 0 |
|
5 |
|
|
6 |
ALTER TABLE parts ADD COLUMN |
|
7 |
order_qty numeric(15, 5) NOT NULL DEFAULT 0; |
sql/Pg-upgrade2/hmo_purchase_basket.sql | ||
---|---|---|
1 |
-- @tag: hmo_purchase_basket |
|
2 |
-- @description: Änderungen HMO für Dispositionsmanager. Neue Spalte Besteller in orderitems und delivery_order_items |
|
3 |
-- @depends: purchase_basket |
|
4 |
-- @ignore: 0 |
|
5 |
|
|
6 |
ALTER TABLE purchase_basket_items DROP COLUMN description; |
|
7 |
ALTER TABLE purchase_basket_items ADD COLUMN orderer_id INTEGER REFERENCES employee(id); |
|
8 |
ALTER TABLE orderitems ADD COLUMN orderer_id INTEGER REFERENCES employee(id); |
|
9 |
ALTER TABLE delivery_order_items ADD COLUMN orderer_id INTEGER REFERENCES employee(id); |
sql/Pg-upgrade2/purchase_basket.sql | ||
---|---|---|
1 |
-- @tag: purchase_basket |
|
2 |
-- @description: Tabelle für den Dispositionsmanager |
|
3 |
-- @depends: release_3_5_1 |
|
4 |
-- @ignore: 0 |
|
5 |
|
|
6 |
CREATE TABLE purchase_basket_items ( |
|
7 |
id SERIAL PRIMARY KEY, |
|
8 |
parts_id INTEGER REFERENCES parts(id), |
|
9 |
qty NUMERIC(15,5), |
|
10 |
description text, |
|
11 |
cleared BOOLEAN NOT NULL DEFAULT FALSE |
|
12 |
); |
sql/Pg-upgrade2/purchase_basket_2.sql | ||
---|---|---|
1 |
-- @tag: purchase_basket_2 |
|
2 |
-- @description: min_order_qty zu Tbl parts hinzufügen |
|
3 |
-- @depends: purchase_basket |
|
4 |
-- @ignore: 0 |
|
5 |
|
|
6 |
ALTER TABLE parts ADD COLUMN min_order_qty numeric(15, 5); |
sql/Pg-upgrade2/purchase_basket_items.sql | ||
---|---|---|
1 |
-- @tag: purchase_basket_items |
|
2 |
-- @description: Tabelle für den Dispositionsmanager |
|
3 |
-- @depends: release_3_8_0 |
|
4 |
-- @ignore: 0 |
|
5 |
|
|
6 |
CREATE TABLE purchase_basket_items ( |
|
7 |
id SERIAL PRIMARY KEY, |
|
8 |
part_id INTEGER REFERENCES parts(id), |
|
9 |
qty NUMERIC(15,5) NOT NULL, |
|
10 |
cleared BOOLEAN NOT NULL DEFAULT FALSE, |
|
11 |
itime TIMESTAMP without time zone DEFAULT now(), |
|
12 |
mtime TIMESTAMP without time zone |
|
13 |
); |
|
14 |
CREATE TRIGGER mtime_purchase_basket_items |
|
15 |
BEFORE UPDATE ON purchase_basket_items |
|
16 |
FOR EACH ROW EXECUTE PROCEDURE set_mtime(); |
t/controllers/disposition_manager/disposition_manager.t | ||
---|---|---|
29 | 29 |
sellprice => 5, |
30 | 30 |
lastcost => 3, |
31 | 31 |
rop => 20, |
32 |
ordersize => 1,
|
|
32 |
order_qty => 1,
|
|
33 | 33 |
warehouse_id => $wh->id, |
34 | 34 |
bin_id => $bin->id, |
35 | 35 |
makemodels => [ _create_makemodel_for_vendor(vendor => $vendor) ], |
... | ... | |
39 | 39 |
partnumber => 'TP 2', |
40 | 40 |
description => 'Testpart 2 norop', |
41 | 41 |
rop => 60, |
42 |
ordersize => 2,
|
|
42 |
order_qty => 2,
|
|
43 | 43 |
)->save; |
44 | 44 |
set_stock(part => $part2, bin_id => $bin->id, qty => 80); |
45 | 45 |
|
... | ... | |
48 | 48 |
partnumber => "TPO $i", |
49 | 49 |
description => "Testpart onhand $i", |
50 | 50 |
rop => 50, |
51 |
ordersize => $i+2,
|
|
51 |
order_qty => $i+2,
|
|
52 | 52 |
sellprice => 5, |
53 | 53 |
lastcost => 3, |
54 | 54 |
warehouse_id => $wh->id, |
templates/webpages/disposition_manager/_show_vendor_parts.html | ||
---|---|---|
1 |
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%][% USE P %] |
|
2 |
[% USE Dumper %] |
|
1 |
[%- USE HTML -%] |
|
2 |
[%- USE LxERP -%] |
|
3 |
[%- USE L -%] |
|
4 |
[%- USE T8 -%] |
|
5 |
[%- USE P -%] |
|
6 |
|
|
3 | 7 |
<h2>[% 'All parts of vendor odered by onhand' | $T8 %]</h2> |
4 | 8 |
<table width="100%"> |
5 | 9 |
<thead> |
6 | 10 |
<tr class="listheading"> |
7 |
<th>[% 'Purchase basket' | $T8 %] </th> |
|
8 |
<th>[% 'Partnumber' | $T8 %] </th> |
|
9 |
<th>[% 'Description' | $T8 %] </th> |
|
10 |
<th>[% 'Onhand / Ordered' | $T8 %] </th> |
|
11 |
<th>[% 'Rop' | $T8 %] </th> |
|
12 |
<th>[% 'Order quantity' | $T8 %] </th> |
|
13 |
<th>[% 'Vendor' | $T8 %] </th> |
|
11 |
<th>[% 'Purchase basket' | $T8 %] </th> |
|
12 |
<th>[% 'Partnumber' | $T8 %] </th> |
|
13 |
<th>[% 'Description' | $T8 %] </th> |
|
14 |
<th>[% 'Onhand' | $T8 %] </th> |
|
15 |
<th>[% 'Ordered' | $T8 %] </th> |
|
16 |
<th>[% 'Rop' | $T8 %] </th> |
|
17 |
<th>[% 'Order quantity' | $T8 %] </th> |
|
18 |
<th>[% 'Vendor' | $T8 %] </th> |
|
14 | 19 |
</tr> |
15 | 20 |
</thead> |
16 | 21 |
<tbody> |
17 | 22 |
[% FOREACH makemodel_item = MAKEMODEL_ITEMS %] |
18 | 23 |
|
19 |
[% # Dumper.dump_html('TEST') %] |
|
20 |
[% # Dumper.dump_html(basket_item) %] |
|
21 | 24 |
[% SET select_size = basket_item.part.vendor_dropdown.size %] |
22 | 25 |
<tr class="listrow"> |
23 |
<td>[% L.checkbox_tag('vendor_part_ids[+]', checked = '0', value=makemodel_item.id) %]</td> |
|
24 |
<td>[% HTML.escape(makemodel_item.partnumber) %] |
|
25 |
[% IF makemodel_item.id %] |
|
26 |
<img class="odbuttons" onclick="kivi.DispositionManager.show_detail_dialog('[% makemodel_item.id %]','[% makemodel_item.partnumber %]')" src="image/icons/svg/information.svg" |
|
27 |
title="[% 'Article details' | $T8 %]"> |
|
28 |
[% END %] |
|
26 |
<td>[% L.checkbox_tag('vendor_part_ids[+]', |
|
27 |
checked='0', value=makemodel_item.id) %]</td> |
|
28 |
<td>[% makemodel_item.presenter.part(target = '_blank') %] |
|
29 |
[% P.button_tag( |
|
30 |
"kivi.DispositionManager.show_detail_dialog(" |
|
31 |
_ makemodel_item.id _ "," _ makemodel_item.partnumber _ |
|
32 |
")", |
|
33 |
LxERP.t8('Details (one letter abbreviation)'), |
|
34 |
title=LxERP.t8('Article details'), class="button") %] |
|
29 | 35 |
</td> |
30 | 36 |
<td>[% HTML.escape(makemodel_item.description) %]</td> |
31 |
<td class="numeric">[% makemodel_item.onhand_as_number %] / [% makemodel_item.get_ordered_qty %]</td> |
|
32 |
<td class="numeric">[% makemodel_item.rop_as_number %] </td> |
|
33 |
<td class="numeric">[% makemodel_item.qty_as_number %] </td> |
|
34 |
<td>[% L.select_tag('vendor_ids[]', makemodel_item.vendor_dropdown, value_key = 'value', title_key = 'title', default = makemodel_item.makemodels.item(0).make, size = select_size, style='width: 350px;' ) %]</td> |
|
37 |
<td class="numeric">[% makemodel_item.onhand_as_number %]</td> |
|
38 |
<td class="numeric">[% makemodel_item.get_ordered_qty %]</td> |
|
39 |
<td class="numeric">[% makemodel_item.rop_as_number %]</td> |
|
40 |
<td class="numeric">[% makemodel_item.qty_as_number %]</td> |
|
41 |
<td>[% L.select_tag('vendor_ids[]', makemodel_item.vendor_dropdown, |
|
42 |
value_key='value', title_key='title', |
|
43 |
default=makemodel_item.makemodels.item(0).make, |
|
44 |
size=select_size, style='width:350px;' ) %] |
|
45 |
</td> |
|
35 | 46 |
</tr> |
36 | 47 |
[% END %] |
37 | 48 |
</tbody> |
templates/webpages/disposition_manager/list_parts.html | ||
---|---|---|
1 |
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%] |
|
2 |
[% USE Dumper %] |
|
1 |
[%- USE HTML -%] |
|
2 |
[%- USE LxERP -%] |
|
3 |
[%- USE L -%] |
|
4 |
[%- USE T8 -%] |
|
5 |
|
|
3 | 6 |
[%- INCLUDE 'common/flash.html' %] |
4 | 7 |
<hr> |
5 | 8 |
<h2>[% 'Short onhand' | $T8 %]</h2> |
... | ... | |
8 | 11 |
<table width="100%"> |
9 | 12 |
<thead> |
10 | 13 |
<tr class="listheading"> |
11 |
<th>[% L.checkbox_tag('check_all', checkall="[data-checkall=1]") %][% 'Purchase basket' | $T8 %] </th> |
|
14 |
<th> |
|
15 |
[% L.checkbox_tag('check_all', checkall='[data-checkall=1]') %] |
|
16 |
[% 'Purchase basket' | $T8 %] |
|
17 |
</th> |
|
12 | 18 |
<th>[% 'Partnumber' | $T8 %] </th> |
13 | 19 |
<th>[% 'Description' | $T8 %] </th> |
14 | 20 |
<th>[% 'Vendor' | $T8 %] </th> |
... | ... | |
20 | 26 |
[% FOREACH part = PARTS %] |
21 | 27 |
[% IF !part.get_open_ordered_qty %] |
22 | 28 |
<tr class="listrow"> |
23 |
<td>[% IF part.makemodels.size %][% L.checkbox_tag('ids[+]', "data-checkall"=1, checked = '1', value=part.id) %][% ELSE %][% 'No Vendor' | $T8 %][% END %]</td> |
|
29 |
<td> |
|
30 |
[% IF part.makemodels.size %] |
|
31 |
[% L.checkbox_tag('ids[+]', 'data-checkall'=1, |
|
32 |
checked = '1', value=part.id) %] |
|
33 |
[% ELSE %] |
|
34 |
[% 'No Vendor' | $T8 %] |
|
35 |
[% END %] |
|
36 |
</td> |
|
24 | 37 |
<td>[% HTML.escape(part.partnumber) %]</td> |
25 | 38 |
<td>[% HTML.escape(part.description) %]</td> |
26 |
<td>[% L.select_tag('vendor_ids[]', part.vendor_dropdown, value_key = 'value', title_key = 'title', default = basket_item.part.makemodels.item(0).make, size = select_size, style='width: 250px;' ) %]</td> |
|
27 |
<td class="numeric">[% part.onhandqty_as_number %]</td> |
|
28 |
<td class="numeric">[% part.rop_as_number %] </td> |
|
29 |
<td class="numeric">[% part.ordersize_as_number %] </td> |
|
39 |
<td> |
|
40 |
[% L.select_tag( |
|
41 |
'vendor_ids[]', part.vendor_dropdown, |
|
42 |
value_key = 'value', title_key = 'title', |
|
43 |
default = basket_item.part.makemodels.item(0).make, |
|
44 |
size = select_size, style='width: 250px;' ) %] |
|
45 |
</td> |
|
46 |
<td class="numeric">[% LxERP.format_amount(part.onhandqty, 2) %]</td> |
|
47 |
<td class="numeric">[% part.rop_as_number %]</td> |
|
48 |
<td class="numeric">[% part.order_qty_as_number %]</td> |
|
30 | 49 |
</tr> |
31 | 50 |
[% END %] |
32 | 51 |
[% END %] |
33 | 52 |
</table> |
34 | 53 |
</form> |
35 | 54 |
<hr> |
36 |
<h2>[% 'Short onhand Ordered' | $T8 %]</h2> |
|
37 |
<<<<<<< HEAD |
|
38 |
<div style="margin:1em;"> |
|
39 |
<table width="100%"> |
|
40 |
<thead> |
|
41 |
<tr class="listheading"> |
|
42 |
<th>[% 'Partnumber' | $T8 %] </th> |
|
43 |
<th>[% 'Description' | $T8 %] </th> |
|
44 |
<th>[% 'onhand' | $T8 %] </th> |
|
45 |
<th>[% 'rop' | $T8 %] </th> |
|
46 |
<th>[% 'Ordered purchase' | $T8 %] </th> |
|
47 |
</tr> |
|
48 |
</thead> |
|
49 |
[% FOREACH part = PARTS %] |
|
50 |
[% IF part.get_open_ordered_qty %] |
|
51 |
<tr class="listrow"> |
|
52 |
<td>[% HTML.escape(part.partnumber) %]</td> |
|
53 |
<td>[% HTML.escape(part.description) %] </td> |
|
54 |
<td class="numeric">[% part.onhand_as_number %] </td> |
|
55 |
<td class="numeric">[% part.rop_as_number %] </td> |
|
56 |
<td class="numeric">[% part.get_open_ordered_qty_as_number %] </td> |
|
57 |
</tr> |
|
58 |
[% END %] |
|
59 |
[% END %] |
|
60 |
</table> |
|
61 |
======= |
|
62 |
>>>>>>> a1d2278510 (Dispomanager Meldebestand Bestellte Artikel als Report) |
|
63 | 55 |
</div> |
templates/webpages/disposition_manager/reorder_level_list/report_bottom.html | ||
---|---|---|
1 |
[% USE L %] |
|
2 |
[%- L.paginate_controls(models=SELF.models) %] |
templates/webpages/disposition_manager/show_purchase_basket.html | ||
---|---|---|
1 |
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%][% USE P %] |
|
2 |
[% USE Dumper %] |
|
1 |
[%- USE HTML -%] |
|
2 |
[%- USE LxERP -%] |
|
3 |
[%- USE L -%] |
|
4 |
[%- USE T8 -%] |
|
5 |
[%- USE P -%] |
|
6 |
|
|
3 | 7 |
[%- INCLUDE 'common/flash.html' %] |
4 | 8 |
<h1>[% title %]</h1> |
5 | 9 |
[% # Dumper.dump_html(BASKET_ITEMS) %] |
6 | 10 |
<form id="purchasebasket" style="margin:1em;"> |
7 | 11 |
<div> |
8 |
<p>[% 'Vendor' | $T8 %]: [% P.customer_vendor.picker('vendor_id2', FORM.vendor_id2, type='vendor') %]</p> |
|
9 |
<p>[% 'Partsgroup' | $T8 %]: [% P.partsgroup.picker('partsgroup_id', FORM.partsgroup_id, with_empty=1, onchange=> "kivi.DispositionManager.filter_partsgroup();") %]</p> |
|
12 |
<p> |
|
13 |
[% 'Vendor' | $T8 %]: |
|
14 |
[% P.customer_vendor.picker('vendor_id2', FORM.vendor_id2, type='vendor') %] |
|
15 |
</p> |
|
10 | 16 |
</div> |
11 | 17 |
<div> |
12 | 18 |
<table id="baskettable" width="100%"> |
13 | 19 |
<thead> |
14 | 20 |
<tr class="listheading"> |
15 |
<th>[% L.checkbox_tag("", id="check_all", checkall="[data-checkall=1]") %][% 'Purchase basket' | $T8 %] </th> |
|
21 |
<th> |
|
22 |
[% L.checkbox_tag("", id="check_all", checkall="[data-checkall=1]") %] |
|
23 |
[% 'Purchase basket' | $T8 %] |
|
24 |
</th> |
|
16 | 25 |
<th>[% 'Partnumber' | $T8 %] </th> |
17 | 26 |
<th>[% 'Description' | $T8 %] </th> |
18 | 27 |
<th>[% 'Onhand' | $T8 %] </th> |
... | ... | |
24 | 33 |
<tbody> |
25 | 34 |
[% FOREACH basket_item = BASKET_ITEMS %] |
26 | 35 |
|
27 |
[% # Dumper.dump_html('TEST') %] |
|
28 |
[% # Dumper.dump_html(basket_item) %] |
|
29 | 36 |
[% SET select_size = basket_item.part.vendor_dropdown.size %] |
Auch abrufbar als: Unified diff
TMP DispositionManager aktueller stand