Revision 6c7f739e
Von Martin Helmling martin.helmling@octosoft.eu vor etwa 4 Jahren hinzugefügt
SL/Helper/Inventory.pm | ||
---|---|---|
14 | 14 |
use SL::DB::TransferType; |
15 | 15 |
use SL::X; |
16 | 16 |
|
17 |
our @EXPORT_OK = qw(get_stock get_onhand allocate allocate_for_assembly produce_assembly); |
|
17 |
our @EXPORT_OK = qw(get_stock get_onhand allocate allocate_for_assembly produce_assembly check_constraints);
|
|
18 | 18 |
our %EXPORT_TAGS = (ALL => \@EXPORT_OK); |
19 | 19 |
|
20 | 20 |
sub _get_stock_onhand { |
... | ... | |
191 | 191 |
|| $bin_whitelist{$b->{bin_id}} <=> $bin_whitelist{$a->{bin_id}} # then prefer wanted bins |
192 | 192 |
|| $wh_whitelist{$b->{warehouse_id}} <=> $wh_whitelist{$a->{warehouse_id}} # then prefer wanted bins |
193 | 193 |
} @filtered_results; |
194 |
|
|
195 | 194 |
my @allocations; |
196 | 195 |
my $rest_qty = $qty; |
197 | 196 |
|
... | ... | |
220 | 219 |
msg => t8("can not allocate #1 units of #2, missing #3 units", $qty, $part->displayable_name, $rest_qty), |
221 | 220 |
); |
222 | 221 |
} else { |
222 |
if ($params{constraints}) { |
|
223 |
check_constraints($params{constraints},\@allocations); |
|
224 |
} |
|
223 | 225 |
return @allocations; |
224 | 226 |
} |
225 | 227 |
} |
... | ... | |
249 | 251 |
@allocations; |
250 | 252 |
} |
251 | 253 |
|
254 |
sub check_constraints { |
|
255 |
my ($constraints, $allocations) = @_; |
|
256 |
if ('CODE' eq ref $constraints) { |
|
257 |
if (!$constraints->(@$allocations)) { |
|
258 |
die SL::X::Inventory::Allocation->new( |
|
259 |
error => 'allocation constraints failure', |
|
260 |
msg => t8("Allocations didn't pass constraints"), |
|
261 |
); |
|
262 |
} |
|
263 |
} else { |
|
264 |
croak 'constraints needs to be a hashref' unless 'HASH' eq ref $constraints; |
|
265 |
|
|
266 |
my %supported_constraints = ( |
|
267 |
bin_id => 'bin_id', |
|
268 |
warehouse_id => 'warehouse_id', |
|
269 |
chargenumber => 'chargenumber', |
|
270 |
); |
|
271 |
|
|
272 |
for (keys %$constraints ) { |
|
273 |
croak "unsupported constraint '$_'" unless $supported_constraints{$_}; |
|
274 |
|
|
275 |
my %whitelist = map { (ref $_ ? $_->id : $_) => 1 } listify($constraints->{$_}); |
|
276 |
my $accessor = $supported_constraints{$_}; |
|
277 |
|
|
278 |
if (any { !$whitelist{$_->$accessor} } @$allocations) { |
|
279 |
my %error_constraints = ( |
|
280 |
bin_id => t8('Bins'), |
|
281 |
warehouse_id => t8('Warehouses'), |
|
282 |
chargenumber => t8('Chargenumbers'), |
|
283 |
); |
|
284 |
die SL::X::Inventory::Allocation->new( |
|
285 |
error => 'allocation constraints failure', |
|
286 |
msg => t8("Allocations didn't pass constraints for #1",$error_constraints{$_}), |
|
287 |
); |
|
288 |
} |
|
289 |
} |
|
290 |
} |
|
291 |
} |
|
292 |
|
|
252 | 293 |
sub produce_assembly { |
253 | 294 |
my (%params) = @_; |
254 | 295 |
|
... | ... | |
715 | 756 |
be C<undef> (but must still be present at creation time). Instances are |
716 | 757 |
considered immutable. |
717 | 758 |
|
759 |
=head1 CONSTRAINTS |
|
760 |
|
|
761 |
# whitelist constraints |
|
762 |
->allocate( |
|
763 |
... |
|
764 |
constraints => { |
|
765 |
bin_id => \@allowed_bins, |
|
766 |
chargenumber => \@allowed_chargenumbers, |
|
767 |
} |
|
768 |
); |
|
769 |
|
|
770 |
# custom constraints |
|
771 |
->allocate( |
|
772 |
constraints => sub { |
|
773 |
# only allow chargenumbers with specific format |
|
774 |
all { $_->chargenumber =~ /^ C \d{8} - \a{d2} $/x } @_ |
|
775 |
|
|
776 |
&& |
|
777 |
# and must be all reservations |
|
778 |
all { $_->reserve_for_id } @_; |
|
779 |
} |
|
780 |
) |
|
781 |
|
|
782 |
C<allocation> is "best effort" in nature. It will take the C<bin>, |
|
783 |
C<chargenumber> etc hints from the parameters, but will try it's bvest to |
|
784 |
fulfil the request anyway and only bail out if it is absolutely not possible. |
|
785 |
|
|
786 |
Sometimes you need to restrict allocations though. For this you can pass |
|
787 |
additional constraints to C<allocate>. A constraint serves as a whitelist. |
|
788 |
Every allocation must fulfil every constraint by having that attribute be one |
|
789 |
of the given values. |
|
790 |
|
|
791 |
In case even that is not enough, you may supply a custom check by passing a |
|
792 |
function that will be given the allocation objects. |
|
793 |
|
|
794 |
Note that both whitelists and constraints do not influence the order of |
|
795 |
allocations, which is done purely from the initial parameters. They only serve |
|
796 |
to reject allocations made in good faith which do fulfil required assertions. |
|
797 |
|
|
718 | 798 |
=head1 ERROR HANDLING |
719 | 799 |
|
720 | 800 |
C<allocate> and C<produce_assembly> will throw exceptions if the request can |
Auch abrufbar als: Unified diff
Inventory-Helper: neuer Parameter "constraints" um die Verfügbarkeit von Lagerbeständen einzuschränken
Eine extra Methode prüft gefundene Einträge auf bestimmte Einschränkungen
nachdem die Sortierung stattgefunden hat
zu #9457