Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 6c7f739e

Von Martin Helmling martin.helmling@octosoft.eu vor etwa 4 Jahren hinzugefügt

  • ID 6c7f739ef61c9dabb597d3489fe635d35b74d45a
  • Vorgänger 922fd63a
  • Nachfolger 2af13d3a

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

Unterschiede anzeigen:

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
locale/de/all
270 270
  'All transactions'            => 'Alle Buchungen',
271 271
  'All units have either no or exactly one base unit of which they are multiples.' => 'Einheiten haben entweder keine oder genau eine Basiseinheit, von der sie ein Vielfaches sind.',
272 272
  'All users'                   => 'Alle BenutzerInnen',
273
  'Allocations didn\'t pass constraints' => 'Keine Verfügbarkeit wegen Lagereinschränkung',
274
  'Allocations didn\'t pass constraints for #1' => 'Keine Verfügbarkeit wegen Lagereinschränkung auf \'#1\'',
273 275
  'Allow access'                => 'Zugriff erlauben',
274 276
  'Allow conversion from sales orders to sales invoices' => 'Umwandlung von Verkaufsaufträgen in Verkaufsrechnungen zulassen',
275 277
  'Allow conversion from sales quotations to sales invoices' => 'Umwandlung von Verkaufsangeboten in Verkaufsrechnungen zulassen',
......
597 599
  'Charge'                      => 'Berechnen',
598 600
  'Charge Number'               => 'Chargennummer',
599 601
  'Charge number'               => 'Chargennummer',
602
  'Chargenumbers'               => '',
600 603
  'Charset'                     => 'Zeichensatz',
601 604
  'Chart'                       => 'Buchungskonto',
602 605
  'Chart Type'                  => 'Kontentyp',

Auch abrufbar als: Unified diff