Revision 5c49b870
Von Bernd Bleßmann vor 9 Monaten hinzugefügt
bin/mozilla/wh.pl | ||
---|---|---|
33 | 33 |
####################################################################### |
34 | 34 |
|
35 | 35 |
use Carp; |
36 |
use List::Util qw(first);
|
|
36 |
use List::Util qw(any first none);
|
|
37 | 37 |
use POSIX qw(strftime); |
38 | 38 |
use Scalar::Util qw(blessed); |
39 | 39 |
|
... | ... | |
43 | 43 |
use SL::AM; |
44 | 44 |
use SL::CVar; |
45 | 45 |
use SL::CT; |
46 |
use SL::Helper::Flash qw(flash_later); |
|
46 |
use SL::Helper::Flash qw(flash flash_later);
|
|
47 | 47 |
use SL::IC; |
48 | 48 |
use SL::WH; |
49 | 49 |
use SL::OE; |
50 |
use SL::Helper::Inventory qw(produce_assembly); |
|
50 |
use SL::Helper::Inventory qw(get_stock produce_assembly allocate_for_assembly check_allocations_for_assembly); |
|
51 |
use SL::Helper::Inventory::Allocation; |
|
51 | 52 |
use SL::Locale::String qw(t8); |
52 | 53 |
use SL::ReportGenerator; |
53 | 54 |
use SL::Presenter::Tag qw(checkbox_tag); |
... | ... | |
398 | 399 |
$form->{bestbefore} = ''; |
399 | 400 |
} |
400 | 401 |
|
402 |
# Check if there are more than one chargenumber for one part of an assembly. |
|
403 |
# In this case let the user select the wanted chargenumbers. |
|
404 |
my $stocked_wh_id = $::instance_conf->get_produce_assembly_same_warehouse ? $form->{warehouse_id} : undef; |
|
405 |
my @stocked_by = qw(part warehouse bin chargenumber); # Or 'for_allocate'? That would include 'bestbefore'. |
|
406 |
my $stocked_parts = get_stock(part => [ map { $_->part } @{$assembly->assemblies} ], |
|
407 |
warehouse => $stocked_wh_id, |
|
408 |
by => \@stocked_by, |
|
409 |
with_objects => [qw(part warehouse bin)]); |
|
410 |
|
|
411 |
# Remove entries with no stock. |
|
412 |
$stocked_parts = [ grep { $_->{qty} != 0 } @$stocked_parts]; |
|
413 |
|
|
414 |
my %stocked_by_parts_id = map { my $p_id = $_->{parts_id }; $p_id => [grep { $_->{parts_id} == $p_id } @$stocked_parts] } @$stocked_parts; |
|
415 |
|
|
416 |
my $is_stock_ambiguous = any { scalar(@{$_ || []}) > 1 } values %stocked_by_parts_id; |
|
417 |
my $allocation_check_failed; |
|
418 |
my $stock_check_failed; |
|
419 |
|
|
420 |
my @allocations; |
|
421 |
if ($is_stock_ambiguous) { |
|
422 |
if (!scalar @{$form->{allocations} || []}) { |
|
423 |
# User has not selected something / first_time. |
|
424 |
# Pre-fill allocations for selection form. |
|
425 |
eval { |
|
426 |
@allocations = allocate_for_assembly(part => $assembly, |
|
427 |
qty => $form->{qty}, |
|
428 |
warehouse => ($form->{warehouse_id} ? SL::DB::Warehouse->new(id => $form->{warehouse_id})->load : undef), |
|
429 |
chargenumber => $form->{chargenumber},); |
|
430 |
1; |
|
431 |
} or do { |
|
432 |
my $ex = $@; |
|
433 |
die $ex unless blessed($ex) && $ex->isa('SL::X::Inventory::Allocation::Multi'); |
|
434 |
|
|
435 |
$form->{title} = $locale->text('Allocate for Assembly'); |
|
436 |
$form->header; |
|
437 |
print $form->parse_html_template( |
|
438 |
'wh/produce_assembly_error', |
|
439 |
{ |
|
440 |
missing_qty_exceptions => [ grep { $_->isa('SL::X::Inventory::Allocation::MissingQty') } @{ $ex->errors } ], |
|
441 |
other_exceptions => [ grep { !$_->isa('SL::X::Inventory::Allocation::MissingQty') } @{ $ex->errors } ], |
|
442 |
}); |
|
443 |
|
|
444 |
return $::lxdebug->leave_sub(); |
|
445 |
}; |
|
446 |
|
|
447 |
} else { |
|
448 |
# User has selected something / selection form was sent. |
|
449 |
# Check allocations. |
|
450 |
|
|
451 |
# Create allocation helper objects from form. |
|
452 |
@allocations = map { |
|
453 |
SL::Helper::Inventory::Allocation->new( |
|
454 |
parts_id => $_->{parts_id}, |
|
455 |
qty => $form->parse_amount(\%myconfig, $_->{qty}), |
|
456 |
bin_id => $_->{bin_id}, |
|
457 |
warehouse_id => $_->{warehouse_id}, |
|
458 |
chargenumber => $_->{chargenumber}, |
|
459 |
bestbefore => $_->{bestbefore}, |
|
460 |
comment => $_->{comment}, |
|
461 |
for_object_id => undef, |
|
462 |
) |
|
463 |
} grep { $form->parse_amount(\%myconfig, $_->{qty}) != 0 } @{$form->{allocations}}; |
|
464 |
|
|
465 |
$allocation_check_failed = !check_allocations_for_assembly(part => $assembly, |
|
466 |
qty => $form->{qty}, |
|
467 |
allocations => \@allocations, |
|
468 |
check_overfulfilment => 1); |
|
469 |
|
|
470 |
if (!$allocation_check_failed) { |
|
471 |
# Check, if all allocations are stocked. |
|
472 |
foreach my $allocation (@allocations) { |
|
473 |
$stock_check_failed = none { |
|
474 |
$_->{parts_id} == $allocation->parts_id && |
|
475 |
$_->{warehouse_id} == $allocation->warehouse_id && |
|
476 |
$_->{bin_id} == $allocation->bin_id && |
|
477 |
$_->{chargenumber} eq $allocation->chargenumber && |
|
478 |
$_->{qty} >= $allocation->qty |
|
479 |
} @$stocked_parts; |
|
480 |
|
|
481 |
last if $stock_check_failed; |
|
482 |
} |
|
483 |
} |
|
484 |
} |
|
485 |
|
|
486 |
# Show selection form if requested or check was not ok. Continue to production otherwise. |
|
487 |
if ($form->{show_allocations} || $allocation_check_failed || $stock_check_failed) { |
|
488 |
flash('warning', t8("Allocations are not sufficient or overfulfilled")) if ($allocation_check_failed); |
|
489 |
flash('warning', t8("Not enough on stock for one or more allocations")) if ($stock_check_failed); |
|
490 |
|
|
491 |
my %allocations_by_parts_id = map { my $p_id = $_->{parts_id}; $p_id => [grep { $_->{parts_id} == $p_id } @allocations] } @allocations; |
|
492 |
|
|
493 |
my %needed_by_parts_id = map { $_->{parts_id} => $_->qty * $form->{qty} } @{$assembly->assemblies}; |
|
494 |
return create_assembly_chargenumbers($form, \%stocked_by_parts_id, \%needed_by_parts_id, \%allocations_by_parts_id); |
|
495 |
} |
|
496 |
|
|
497 |
} |
|
498 |
|
|
401 | 499 |
eval { |
402 | 500 |
produce_assembly( |
403 | 501 |
part => $assembly, # target assembly |
404 | 502 |
qty => $form->{qty}, # qty |
405 |
auto_allocate => 1, |
|
503 |
allocations => ($is_stock_ambiguous ? \@allocations : undef), |
|
504 |
auto_allocate => !$is_stock_ambiguous, |
|
406 | 505 |
bin => $bin, # needed unless a global standard target is configured |
407 | 506 |
chargenumber => $form->{chargenumber}, # optional |
408 | 507 |
bestbefore => $form->{bestbefore}, |
... | ... | |
436 | 535 |
$main::lxdebug->leave_sub(); |
437 | 536 |
} |
438 | 537 |
|
538 |
sub create_assembly_chargenumbers { |
|
539 |
my ($form, $stocked_by_parts_id, $needed_by_parts_id, $allocated_by_parts_id) = @_; |
|
540 |
|
|
541 |
setup_wh_create_assembly_chargenumbers_action_bar(); |
|
542 |
|
|
543 |
my $hidden_vars = { map { $_ => $form->{$_} } qw(parts_id warehouse_id bin_id chargenumber qty unit comment) }; |
|
544 |
|
|
545 |
$form->{title} = $::locale->text('Select Chargenumbers'); |
|
546 |
$form->header; |
|
547 |
|
|
548 |
print $form->parse_html_template( |
|
549 |
'wh/create_assembly_chargenumbers', |
|
550 |
{ |
|
551 |
hidden_vars => $hidden_vars, |
|
552 |
stocked_by_parts_id => $stocked_by_parts_id, |
|
553 |
needed_by_parts_id => $needed_by_parts_id, |
|
554 |
allocated_by_parts_id => $allocated_by_parts_id, |
|
555 |
} |
|
556 |
); |
|
557 |
} |
|
558 |
|
|
439 | 559 |
# -------------------------------------------------------------------- |
440 | 560 |
# Transfer: removal |
441 | 561 |
# -------------------------------------------------------------------- |
... | ... | |
1200 | 1320 |
submit => [ '#form', { action => 'transfer_assembly_update_part' } ], |
1201 | 1321 |
accesskey => 'enter', |
1202 | 1322 |
], |
1323 |
action => [ |
|
1324 |
t8('Produce'), |
|
1325 |
submit => [ '#form', { action => 'create_assembly', show_allocations => 1 } ], |
|
1326 |
disabled => $::form->{parts_id} ? undef : $::locale->text('No assembly has been selected yet.'), |
|
1327 |
], |
|
1328 |
); |
|
1329 |
} |
|
1330 |
} |
|
1331 |
|
|
1332 |
sub setup_wh_create_assembly_chargenumbers_action_bar { |
|
1333 |
my ($action) = @_; |
|
1334 |
|
|
1335 |
for my $bar ($::request->layout->get('actionbar')) { |
|
1336 |
$bar->add( |
|
1337 |
action => [ |
|
1338 |
t8('Update'), |
|
1339 |
submit => [ '#form', { action => 'create_assembly', show_allocations => 1 } ], |
|
1340 |
accesskey => 'enter', |
|
1341 |
], |
|
1203 | 1342 |
action => [ |
1204 | 1343 |
t8('Produce'), |
1205 | 1344 |
submit => [ '#form', { action => 'create_assembly' } ], |
Auch abrufbar als: Unified diff
Erzeugnis fertigen: Chargenauswahl