Revision 2bef4707
Von Tamino Steinert vor etwa 1 Jahr hinzugefügt
SL/Controller/DispositionManager.pm | ||
---|---|---|
182 | 182 |
my ($self) = @_; |
183 | 183 |
my @error_report; |
184 | 184 |
|
185 |
my $basket_items_ids = $::form->{ids};
|
|
186 |
my $vendor_items_ids = $::form->{vendor_part_ids};
|
|
185 |
my $basket_item_ids = $::form->{ids}; |
|
186 |
my $vendor_item_ids = $::form->{vendor_part_ids}; |
|
187 | 187 |
|
188 |
unless (($basket_items_ids && scalar @{ $basket_items_ids})
|
|
189 |
|| ( $vendor_items_ids && scalar @{ $vendor_items_ids}))
|
|
188 |
unless (($basket_item_ids && scalar @{ $basket_item_ids})
|
|
189 |
|| ( $vendor_item_ids && scalar @{ $vendor_item_ids}))
|
|
190 | 190 |
{ |
191 | 191 |
$self->js->flash('error', t8('There are no items selected')); |
192 | 192 |
return $self->js->render(); |
193 | 193 |
} |
194 |
my $v_id = $::form->{vendor_ids}->[0] ; |
|
195 |
|
|
196 |
my ($vendor, $employee); |
|
197 |
$vendor = SL::DB::Manager::Vendor->find_by(id => $v_id); |
|
198 |
$employee = SL::DB::Manager::Employee->current; |
|
199 |
|
|
200 |
|
|
201 |
my @orderitem_maps = (); # part, qty, orderer_id |
|
202 |
if ($basket_items_ids && scalar @{ $basket_items_ids}) { |
|
203 |
my $basket_items = SL::DB::Manager::PurchaseBasketItem->get_all( |
|
204 |
query => [ id => $basket_items_ids ], |
|
205 |
with_objects => ['part'], |
|
206 |
); |
|
207 |
push @orderitem_maps, map {{ |
|
208 |
part => $_->part, |
|
209 |
qty => $_->qty, |
|
210 |
orderer_id => $_->orderer_id, |
|
211 |
}} @{$basket_items}; |
|
212 |
} |
|
213 |
if ($vendor_items_ids && scalar @{ $vendor_items_ids}) { |
|
214 |
my $vendor_items = SL::DB::Manager::Part->get_all( |
|
215 |
query => [ id => $vendor_items_ids ] ); |
|
216 |
push @orderitem_maps, map {{ |
|
217 |
part => $_, |
|
218 |
qty => $_->order_qty || 1, |
|
219 |
orderer_id => $employee->id, |
|
220 |
}} @{$vendor_items}; |
|
221 |
} |
|
222 | 194 |
|
223 |
my $order = SL::DB::Order->new( |
|
224 |
vendor_id => $vendor->id, |
|
225 |
employee_id => $employee->id, |
|
226 |
intnotes => $vendor->notes, |
|
227 |
salesman_id => $employee->id, |
|
228 |
payment_id => $vendor->payment_id, |
|
229 |
delivery_term_id => $vendor->delivery_term_id, |
|
230 |
taxzone_id => $vendor->taxzone_id, |
|
231 |
currency_id => $vendor->currency_id, |
|
232 |
transdate => DateTime->today_local |
|
233 |
); |
|
234 |
|
|
235 |
my @order_items; |
|
236 |
my $i = 0; |
|
237 |
foreach my $orderitem_map (@orderitem_maps) { |
|
238 |
$i++; |
|
239 |
my $part = $orderitem_map->{part}; |
|
240 |
my $qty = $orderitem_map->{qty}; |
|
241 |
my $orderer_id = $orderitem_map->{orderer_id}; |
|
242 |
|
|
243 |
my $order_item = SL::DB::OrderItem->new( |
|
244 |
part => $part, |
|
245 |
qty => $qty, |
|
246 |
unit => $part->unit, |
|
247 |
description => $part->description, |
|
248 |
price_factor_id => $part->price_factor_id, |
|
249 |
price_factor => |
|
250 |
$part->price_factor_id ? $part->price_factor->factor |
|
251 |
: '', |
|
252 |
orderer_id => $orderer_id, |
|
253 |
position => $i, |
|
254 |
); |
|
255 |
|
|
256 |
my $price_source = SL::PriceSource->new( |
|
257 |
record_item => $order_item, record => $order); |
|
258 |
$order_item->sellprice( |
|
259 |
$price_source->best_price ? $price_source->best_price->price |
|
260 |
: 0); |
|
261 |
$order_item->active_price_source( |
|
262 |
$price_source->best_price ? $price_source->best_price->source |
|
263 |
: ''); |
|
264 |
push @order_items, $order_item; |
|
195 |
my $vendor_id = $::form->{vendor_ids}->[0]; |
|
196 |
|
|
197 |
# check for same vendor |
|
198 |
my %basket_id_vendor_id_map = |
|
199 |
map {$::form->{basket_ids}->[$_] => $::form->{vendor_ids}->[$_]} |
|
200 |
(0..$#{$::form->{vendor_ids}}); |
|
201 |
my @different_vendor_ids = |
|
202 |
grep { $basket_id_vendor_id_map{$_} ne $vendor_id } |
|
203 |
@{$basket_item_ids}; |
|
204 |
if (scalar @different_vendor_ids) { |
|
205 |
$self->js->flash('error', t8('There are mulitple vendors selected')); |
|
206 |
return $self->js->render(); |
|
265 | 207 |
} |
266 | 208 |
|
267 |
$order->assign_attributes(orderitems => \@order_items); |
|
268 |
|
|
269 |
$order->db->with_transaction( sub { |
|
270 |
$order->calculate_prices_and_taxes; |
|
271 |
$order->save; |
|
272 |
|
|
273 |
my $snumbers = "ordernumber_" . $order->ordnumber; |
|
274 |
SL::DB::History->new( |
|
275 |
trans_id => $order->id, |
|
276 |
snumbers => $snumbers, |
|
277 |
employee_id => SL::DB::Manager::Employee->current->id, |
|
278 |
addition => 'SAVED', |
|
279 |
what_done => 'PurchaseBasket->Order', |
|
280 |
)->save(); |
|
281 |
foreach my $item(@{ $order->orderitems }){ |
|
282 |
$item->parse_custom_variable_values->save; |
|
283 |
$item->{custom_variables} = \@{ $item->cvars_by_config }; |
|
284 |
$item->save; |
|
285 |
} |
|
286 |
if ($basket_items_ids && scalar @{ $basket_items_ids}) { |
|
287 |
SL::DB::Manager::PurchaseBasketItem->delete_all( |
|
288 |
where => [ id => $basket_items_ids]); |
|
289 |
} |
|
290 |
return 1; |
|
291 |
}) || die "error: " . $order->db->error; |
|
292 |
|
|
293 | 209 |
$self->redirect_to( |
294 | 210 |
controller => 'Order', |
295 |
action => 'edit',
|
|
211 |
action => 'add_from_purchase_basket',
|
|
296 | 212 |
type => 'purchase_order', |
297 |
vc => 'vendor', |
|
298 |
id => $order->id, |
|
213 |
basket_item_ids => $basket_item_ids, |
|
214 |
vendor_item_ids => $vendor_item_ids, |
|
215 |
vendor_id => $vendor_id, |
|
299 | 216 |
); |
300 | 217 |
} |
301 | 218 |
|
... | ... | |
417 | 334 |
], |
418 | 335 |
action => [ |
419 | 336 |
t8('Action'), |
420 |
call => [ 'kivi.DispositionManager.create_order' ], |
|
337 |
call => [ 'kivi.DispositionManager.create_purchase_order' ],
|
|
421 | 338 |
tooltip => t8('Create purchase order'), |
422 | 339 |
], |
423 | 340 |
action => [ |
SL/Controller/Order.pm | ||
---|---|---|
74 | 74 |
|
75 | 75 |
__PACKAGE__->run_before('check_auth_for_edit', |
76 | 76 |
except => [ qw(edit show_customer_vendor_details_dialog price_popup load_second_rows close_quotations) ]); |
77 |
__PACKAGE__->run_before('get_basket_info_from_from'); |
|
77 | 78 |
|
78 | 79 |
# |
79 | 80 |
# actions |
... | ... | |
143 | 144 |
); |
144 | 145 |
} |
145 | 146 |
|
147 |
sub action_add_from_purchase_basket { |
|
148 |
my ($self) = @_; |
|
149 |
|
|
150 |
my $basket_item_ids = $::form->{basket_item_ids}; |
|
151 |
my $vendor_item_ids = $::form->{vendor_item_ids}; |
|
152 |
my $vendor_id = $::form->{vendor_id}; |
|
153 |
|
|
154 |
|
|
155 |
unless (scalar @{ $basket_item_ids} || scalar @{ $vendor_item_ids}) { |
|
156 |
$self->js->flash('error', t8('There are no items selected')); |
|
157 |
return $self->js->render(); |
|
158 |
} |
|
159 |
|
|
160 |
my $order = SL::DB::Order->create_from_purchase_basket( |
|
161 |
$basket_item_ids, $vendor_item_ids, $vendor_id |
|
162 |
); |
|
163 |
|
|
164 |
$self->order($order); |
|
165 |
|
|
166 |
$self->action_add(); |
|
167 |
} |
|
168 |
|
|
146 | 169 |
# edit an existing order |
147 | 170 |
sub action_edit { |
148 | 171 |
my ($self) = @_; |
... | ... | |
1620 | 1643 |
} |
1621 | 1644 |
$self->js->val('[name="converted_from_orderitems_ids[+]"]', ''); |
1622 | 1645 |
$self->js->val('[name="converted_from_reclamation_items_ids[+]"]', ''); |
1646 |
$self->js->val('[name="basket_item_ids[+]"]', ''); |
|
1623 | 1647 |
} |
1624 | 1648 |
|
1625 | 1649 |
# |
... | ... | |
1967 | 1991 |
return $item; |
1968 | 1992 |
} |
1969 | 1993 |
|
1994 |
sub get_basket_info_from_from { |
|
1995 |
my ($self) = @_; |
|
1996 |
|
|
1997 |
my $order = $self->order; |
|
1998 |
my $basket_item_ids = $::form->{basket_item_ids}; |
|
1999 |
if (scalar @{ $basket_item_ids || [] }) { |
|
2000 |
for my $idx (0 .. $#{ $order->items_sorted }) { |
|
2001 |
my $order_item = $order->items_sorted->[$idx]; |
|
2002 |
$order_item->{basket_item_id} = $basket_item_ids->[$idx]; |
|
2003 |
} |
|
2004 |
} |
|
2005 |
} |
|
2006 |
|
|
1970 | 2007 |
# setup custom shipto from form |
1971 | 2008 |
# |
1972 | 2009 |
# The dialog returns form variables starting with 'shipto' and cvars starting |
SL/DB/Order.pm | ||
---|---|---|
9 | 9 |
use List::MoreUtils qw(any); |
10 | 10 |
|
11 | 11 |
use SL::DBUtils (); |
12 |
use SL::DB::PurchaseBasketItem; |
|
12 | 13 |
use SL::DB::MetaSetup::Order; |
13 | 14 |
use SL::DB::Manager::Order; |
14 | 15 |
use SL::DB::Helper::Attr; |
... | ... | |
84 | 85 |
__PACKAGE__->before_save('_before_save_set_custom_shipto_module'); |
85 | 86 |
__PACKAGE__->after_save('_after_save_link_records'); |
86 | 87 |
__PACKAGE__->after_save('_after_save_close_reachable_intakes'); # uses linked records (order matters) |
88 |
__PACKAGE__->before_save('_before_save_delete_from_purchase_basket'); |
|
87 | 89 |
|
88 | 90 |
# hooks |
89 | 91 |
|
... | ... | |
171 | 173 |
return 1; |
172 | 174 |
} |
173 | 175 |
|
176 |
sub _before_save_delete_from_purchase_basket { |
|
177 |
my ($self) = @_; |
|
178 |
|
|
179 |
my @basket_item_ids = grep { $_ ne ''} map { $_->{basket_item_id} } $self->orderitems; |
|
180 |
|
|
181 |
if (scalar @basket_item_ids) { |
|
182 |
SL::DB::Manager::PurchaseBasketItem->delete_all( |
|
183 |
where => [ id => \@basket_item_ids] |
|
184 |
); |
|
185 |
} |
|
186 |
|
|
187 |
return 1; |
|
188 |
} |
|
189 |
|
|
174 | 190 |
# methods |
175 | 191 |
|
176 | 192 |
sub items { goto &orderitems; } |
... | ... | |
348 | 364 |
return $cloned; |
349 | 365 |
} |
350 | 366 |
|
367 |
sub create_from_purchase_basket { |
|
368 |
my ($class, $basket_item_ids, $vendor_item_ids, $vendor_id) = @_; |
|
369 |
|
|
370 |
my ($vendor, $employee); |
|
371 |
$vendor = SL::DB::Manager::Vendor->find_by(id => $vendor_id); |
|
372 |
$employee = SL::DB::Manager::Employee->current; |
|
373 |
|
|
374 |
my @orderitem_maps = (); # part, qty, orderer_id |
|
375 |
if ($basket_item_ids && scalar @{ $basket_item_ids}) { |
|
376 |
my $basket_items = SL::DB::Manager::PurchaseBasketItem->get_all( |
|
377 |
query => [ id => $basket_item_ids ], |
|
378 |
with_objects => ['part'], |
|
379 |
); |
|
380 |
push @orderitem_maps, map {{ |
|
381 |
basket_item_id => $_->id, |
|
382 |
part => $_->part, |
|
383 |
qty => $_->qty, |
|
384 |
orderer_id => $_->orderer_id, |
|
385 |
}} @{$basket_items}; |
|
386 |
} |
|
387 |
if ($vendor_item_ids && scalar @{ $vendor_item_ids}) { |
|
388 |
my $vendor_items = SL::DB::Manager::Part->get_all( |
|
389 |
query => [ id => $vendor_item_ids ] ); |
|
390 |
push @orderitem_maps, map {{ |
|
391 |
basket_item_id => undef, |
|
392 |
part => $_, |
|
393 |
qty => $_->order_qty || 1, |
|
394 |
orderer_id => $employee->id, |
|
395 |
}} @{$vendor_items}; |
|
396 |
} |
|
397 |
|
|
398 |
my $order = $class->new( |
|
399 |
vendor_id => $vendor->id, |
|
400 |
employee_id => $employee->id, |
|
401 |
intnotes => $vendor->notes, |
|
402 |
salesman_id => $employee->id, |
|
403 |
payment_id => $vendor->payment_id, |
|
404 |
delivery_term_id => $vendor->delivery_term_id, |
|
405 |
taxzone_id => $vendor->taxzone_id, |
|
406 |
currency_id => $vendor->currency_id, |
|
407 |
transdate => DateTime->today_local |
|
408 |
); |
|
409 |
|
|
410 |
my @order_items; |
|
411 |
my $i = 0; |
|
412 |
foreach my $orderitem_map (@orderitem_maps) { |
|
413 |
$i++; |
|
414 |
my $part = $orderitem_map->{part}; |
|
415 |
my $qty = $orderitem_map->{qty}; |
|
416 |
my $orderer_id = $orderitem_map->{orderer_id}; |
|
417 |
|
|
418 |
my $order_item = SL::DB::OrderItem->new( |
|
419 |
part => $part, |
|
420 |
qty => $qty, |
|
421 |
unit => $part->unit, |
|
422 |
description => $part->description, |
|
423 |
price_factor_id => $part->price_factor_id, |
|
424 |
price_factor => |
|
425 |
$part->price_factor_id ? $part->price_factor->factor |
|
426 |
: '', |
|
427 |
orderer_id => $orderer_id, |
|
428 |
position => $i, |
|
429 |
); |
|
430 |
$order_item->{basket_item_id} = $orderitem_map->{basket_item_id}; |
|
431 |
|
|
432 |
my $price_source = SL::PriceSource->new( |
|
433 |
record_item => $order_item, record => $order); |
|
434 |
$order_item->sellprice( |
|
435 |
$price_source->best_price ? $price_source->best_price->price |
|
436 |
: 0); |
|
437 |
$order_item->active_price_source( |
|
438 |
$price_source->best_price ? $price_source->best_price->source |
|
439 |
: ''); |
|
440 |
push @order_items, $order_item; |
|
441 |
} |
|
442 |
|
|
443 |
$order->assign_attributes(orderitems => \@order_items); |
|
444 |
|
|
445 |
$order->calculate_prices_and_taxes; |
|
446 |
|
|
447 |
foreach my $item(@{ $order->orderitems }){ |
|
448 |
$item->parse_custom_variable_values; |
|
449 |
$item->{custom_variables} = \@{ $item->cvars_by_config }; |
|
450 |
} |
|
451 |
|
|
452 |
return $order; |
|
453 |
} |
|
454 |
|
|
351 | 455 |
sub new_from { |
352 | 456 |
my ($class, $source, %params) = @_; |
353 | 457 |
|
js/kivi.DispositionManager.js | ||
---|---|---|
19 | 19 |
$('#vendor_parts').load(url); |
20 | 20 |
} |
21 | 21 |
|
22 |
ns.create_order = function() { |
|
22 |
ns.create_purchase_order = function() {
|
|
23 | 23 |
var data = $('#purchasebasket').serializeArray(); |
24 | 24 |
data.push({ name: 'action', value: 'DispositionManager/transfer_to_purchase_order' }); |
25 | 25 |
$.post("controller.pl", data, kivi.eval_json_result); |
templates/design40_webpages/disposition_manager/show_purchase_basket.html | ||
---|---|---|
45 | 45 |
[% FOREACH basket_item = BASKET_ITEMS %] |
46 | 46 |
|
47 | 47 |
<tr> |
48 |
<td>[% L.checkbox_tag('ids[+]', "data-checkall"=1, checked = '1', value=basket_item.id) %] [% HTML.escape(basket_item.part.partsgroup.partsgroup) %] |
|
48 |
<td> |
|
49 |
[% L.checkbox_tag('ids[+]', "data-checkall"=1, checked = '1', value=basket_item.id) %] |
|
50 |
[% L.hidden_tag('basket_ids[+]', basket_item.id) %] |
|
49 | 51 |
</td> |
50 | 52 |
<td> [% basket_item.part.presenter.part(target = '_blank') %] |
51 | 53 |
[% P.button_tag( |
templates/design40_webpages/order/tabs/_row.html | ||
---|---|---|
19 | 19 |
[% L.hidden_tag("converted_from_reclamation_items_ids[+]", ITEM.converted_from_reclamation_items_id) %] |
20 | 20 |
[% L.hidden_tag("order.orderitems[+].id", ITEM.id, id='item_' _ ID) %] |
21 | 21 |
[% L.hidden_tag("order.orderitems[].parts_id", ITEM.parts_id) %] |
22 |
[% L.hidden_tag("basket_item_ids[+]", ITEM.basket_item_id) %] |
|
22 | 23 |
</td> |
23 | 24 |
<td class="center"><div name="position">[% HTML.escape(ITEM.position) %]</div></td> |
24 | 25 |
<td><img src="image/updown.png" alt="[% LxERP.t8('reorder item') %]" class="dragdrop"></td> |
templates/webpages/disposition_manager/show_purchase_basket.html | ||
---|---|---|
33 | 33 |
[% FOREACH basket_item = BASKET_ITEMS %] |
34 | 34 |
|
35 | 35 |
<tr class="listrow"> |
36 |
<td>[% L.checkbox_tag('ids[+]', "data-checkall"=1, checked = '1', value=basket_item.id) %] [% HTML.escape(basket_item.part.partsgroup.partsgroup) %] |
|
36 |
<td> |
|
37 |
[% L.checkbox_tag('ids[+]', "data-checkall"=1, checked = '1', value=basket_item.id) %] |
|
38 |
[% L.hidden_tag('basket_ids[+]', basket_item.id) %] |
|
37 | 39 |
</td> |
38 | 40 |
<td> [% basket_item.part.presenter.part(target = '_blank') %] |
39 | 41 |
[% P.button_tag( |
templates/webpages/order/tabs/_row.html | ||
---|---|---|
19 | 19 |
[% L.hidden_tag("converted_from_reclamation_items_ids[+]", ITEM.converted_from_reclamation_items_id) %] |
20 | 20 |
[% L.hidden_tag("order.orderitems[+].id", ITEM.id, id='item_' _ ID) %] |
21 | 21 |
[% L.hidden_tag("order.orderitems[].parts_id", ITEM.parts_id) %] |
22 |
[% L.hidden_tag("purchase_basket_item_ids[+]", ITEM.purchase_basket_item_ids) %] |
|
22 | 23 |
</td> |
23 | 24 |
<td> |
24 | 25 |
<div name="position" class="numeric"> |
Auch abrufbar als: Unified diff
DispositionManager: Lieferschein beim Erstellen nicht automatisch speichern