}
if ($rest_qty > 0) {
die SL::X::Inventory::Allocation->new(
- error => 'not enough to allocate',
- msg => t8("can not allocate #1 units of #2, missing #3 units", _format_number($qty), $part->displayable_name, _format_number($rest_qty)),
+ code => 'not enough to allocate',
+ message => t8("can not allocate #1 units of #2, missing #3 units", _format_number($qty), $part->displayable_name, _format_number($rest_qty)),
);
} else {
if ($params{constraints}) {
my $part = $params{part} or Carp::croak('allocate needs a part');
my $qty = $params{qty} or Carp::croak('allocate needs a qty');
+ my $wh = $params{warehouse};
+ my $wh_strict = $::instance_conf->get_produce_assembly_same_warehouse;
+ my $consume_service = $::instance_conf->get_produce_assembly_transfer_service;
- Carp::croak('not an assembly') unless $part->is_assembly;
+ Carp::croak('not an assembly') unless $part->is_assembly;
+ Carp::croak('No warehouse selected') if $wh_strict && !$wh;
my %parts_to_allocate;
for my $assembly ($part->assemblies) {
+ next if $assembly->part->type eq 'service' && !$consume_service;
$parts_to_allocate{ $assembly->part->id } //= 0;
$parts_to_allocate{ $assembly->part->id } += $assembly->qty * $qty;
}
for my $part_id (keys %parts_to_allocate) {
my $part = SL::DB::Part->load_cached($part_id);
push @allocations, allocate(%params, part => $part, qty => $parts_to_allocate{$part_id});
+ if ($wh_strict) {
+ die SL::X::Inventory::Allocation->new(
+ code => "wrong warehouse for part",
+ message => t8('Part #1 exists in warehouse #2, but not in warehouse #3 ',
+ $part->partnumber . ' ' . $part->description,
+ SL::DB::Manager::Warehouse->find_by(id => $allocations[-1]->{warehouse_id})->description,
+ $wh->description),
+ ) unless $allocations[-1]->{warehouse_id} == $wh->id;
+ }
}
@allocations;
if ('CODE' eq ref $constraints) {
if (!$constraints->(@$allocations)) {
die SL::X::Inventory::Allocation->new(
- error => 'allocation constraints failure',
- msg => t8("Allocations didn't pass constraints"),
+ code => 'allocation constraints failure',
+ message => t8("Allocations didn't pass constraints"),
);
}
} else {
SL::DB::Bin->load_cached($_->bin_id)->full_description,
_format_number($_->qty), _format_number($needed), $_->chargenumber ? $_->chargenumber : '--') for @allocs;
die SL::X::Inventory::Allocation->new(
- error => 'allocation constraints failure',
- msg => $err,
+ code => 'allocation constraints failure',
+ message => $err,
);
}
}
my $part = $params{part} or Carp::croak('produce_assembly needs a part');
my $qty = $params{qty} or Carp::croak('produce_assembly needs a qty');
+ my $bin = $params{bin} or Carp::croak("need target bin");
my $allocations = $params{allocations};
+ my $strict_wh = $::instance_conf->get_produce_assembly_same_warehouse ? $bin->warehouse : undef;
if ($params{auto_allocate}) {
Carp::croak("produce_assembly: can't have both allocations and auto_allocate") if $params{allocations};
- $allocations = [ allocate_for_assembly(part => $part, qty => $qty) ];
+ $allocations = [ allocate_for_assembly(part => $part, qty => $qty, warehouse => $strict_wh, chargenumber => $params{chargenumber}) ];
} else {
Carp::croak("produce_assembly: need allocations or auto_allocate to produce something") if !$params{allocations};
$allocations = $params{allocations};
}
- my $bin = $params{bin} or Carp::croak("need target bin");
- my $chargenumber = $params{chargenumber};
- my $bestbefore = $params{bestbefore};
+ my $chargenumber = $params{chargenumber};
+ my $bestbefore = $params{bestbefore};
my $for_object_id = $params{for_object_id};
- my $comment = $params{comment} // '';
-
- my $invoice = $params{invoice};
- my $project = $params{project};
+ my $comment = $params{comment} // '';
+ my $invoice = $params{invoice};
+ my $project = $params{project};
+ my $shippingdate = $params{shippingsdate} // DateTime->now_local;
+ my $trans_id = $params{trans_id};
- my $shippingdate = $params{shippingsdate} // DateTime->now_local;
-
- my $trans_id = $params{trans_id};
($trans_id) = selectrow_query($::form, SL::DB->client->dbh, qq|SELECT nextval('id')| ) unless $trans_id;
my $trans_type_out = SL::DB::Manager::TransferType->find_by(direction => 'out', description => 'used');
- my $trans_type_in = SL::DB::Manager::TransferType->find_by(direction => 'in', description => 'assembled');
+ my $trans_type_in = SL::DB::Manager::TransferType->find_by(direction => 'in', description => 'assembled');
# check whether allocations are sane
if (!$params{no_check_allocations} && !$params{auto_allocate}) {
$allocations_by_part{ $assembly->parts_id } -= $assembly->qty * $qty;
}
- die "allocations are insufficient for production" if any { $_ < 0 } values %allocations_by_part;
+ die SL::X::Inventory::Allocation->new(
+ code => "allocations are insufficient for production",
+ message => t8('can not allocate enough resources for production'),
+ ) if any { $_ < 0 } values %allocations_by_part;
}
my @transfers;
trans_type => $trans_type_out,
shippingdate => $shippingdate,
employee => SL::DB::Manager::Employee->current,
+ comment => t8('Used for assembly #1 #2', $part->partnumber, $part->description),
);
}