Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision ad910e38

Von Kivitendo Admin vor mehr als 7 Jahren hinzugefügt

  • ID ad910e38c8be1b972756748493b99fa426e2e33e
  • Vorgänger d1f44c84
  • Nachfolger cafccbb1

SL::Dev::Inventory - neue Funktionen ...

... um Lagerbestand zu ändern und um Lieferscheine ein- oder auszulagern.

Unterschiede anzeigen:

SL/Dev/Inventory.pm
2 2

  
3 3
use strict;
4 4
use base qw(Exporter);
5
our @EXPORT = qw(create_warehouse_and_bins set_stock);
5
our @EXPORT = qw(create_warehouse_and_bins set_stock transfer_stock transfer_sales_delivery_order transfer_purchase_delivery_order transfer_delivery_order_item transfer_in transfer_out);
6 6

  
7 7
use SL::DB::Warehouse;
8 8
use SL::DB::Bin;
9 9
use SL::DB::Inventory;
10 10
use SL::DB::TransferType;
11 11
use SL::DB::Employee;
12
use SL::DB::DeliveryOrderItemsStock;
12 13
use SL::WH;
13 14
use DateTime;
14 15
use Data::Dumper;
16
use Carp;
15 17

  
16 18
sub create_warehouse_and_bins {
17 19
  my (%params) = @_;
......
184 186
  # return 1;
185 187
}
186 188

  
189
sub _transfer {
190
  my (%params) = @_;
191

  
192
  my $transfer_type = delete $params{transfer_type};
193

  
194
  die "param transfer_type is not a SL::DB::TransferType object: " . Dumper($transfer_type) unless ref($transfer_type) eq 'SL::DB::TransferType';
195

  
196
  my $shippingdate  = delete $params{shippingdate}  // DateTime->today;
197

  
198
  my $part = delete($params{part}) or croak 'part missing';
199
  my $qty  = delete($params{qty})  or croak 'qty missing';
200

  
201
  # distinguish absolute qty in inventory depending on transfer type direction
202
  $qty *= -1 if $transfer_type->direction eq 'out';
203

  
204
  # use defaults for unit/wh/bin is they exist and nothing else is specified
205
  my $unit = delete($params{unit}) // $part->unit      or croak 'unit missing';
206
  my $bin  = delete($params{bin})  // $part->bin       or croak 'bin missing';
207
  # if bin is given, we don't need a warehouse param
208
  my $wh   = $bin->warehouse or croak 'wh missing';
209

  
210
  WH->transfer({
211
    parts_id         => $part->id,
212
    dst_bin          => $bin,
213
    dst_wh           => $wh,
214
    qty              => $qty,
215
    transfer_type    => $transfer_type,
216
    unit             => $unit,
217
    comment          => delete $params{comment},
218
    shippingdate     => $shippingdate,
219
  });
220
}
221

  
222
sub transfer_in {
223
  my (%params) = @_;
224

  
225
  my $transfer_type = delete $params{transfer_type} // 'stock';
226

  
227
  my $transfer_type_obj = SL::DB::Manager::TransferType->find_by( direction => 'in', description => $transfer_type ) or die "Can't find transfer_type with direction in and descriptin " . $params{transfer_type};
228

  
229
  $params{transfer_type} = $transfer_type_obj;
230

  
231
  _transfer(%params);
232
}
233

  
234
sub transfer_out {
235
  my (%params) = @_;
236

  
237
  my $transfer_type = delete $params{transfer_type} // 'shipped';
238

  
239
  my $transfer_type_obj = SL::DB::Manager::TransferType->find_by( direction => 'out', description => $transfer_type ) or die "Can't find transfer_type with direction in and descriptin " . $params{transfer_type};
240

  
241
  $params{transfer_type} = $transfer_type_obj;
242

  
243
  _transfer(%params);
244
}
245

  
246
sub transfer_sales_delivery_order {
247
  my ($sales_delivery_order) = @_;
248
  die "first argument must be a sales delivery order Rose DB object" unless ref($sales_delivery_order) eq 'SL::DB::DeliveryOrder' and $sales_delivery_order->is_sales;
249

  
250
  die "the delivery order has already been delivered" if $sales_delivery_order->delivered;
251

  
252
  my ($wh, $bin, $trans_type);
253

  
254
  $sales_delivery_order->db->with_transaction(sub {
255

  
256
   foreach my $doi ( @{ $sales_delivery_order->items } ) {
257
     next if $doi->part->is_service or $doi->part->is_assortment;
258
     my $trans_type = SL::DB::Manager::TransferType->find_by(direction => 'out', description => 'shipped');
259
     transfer_delivery_order_item($doi, $wh, $bin, $trans_type);
260
   };
261
   $sales_delivery_order->delivered(1);
262
   $sales_delivery_order->save(changes_only=>1);
263
   1;
264
  }) or die "error while transferring sales_delivery_order: " . $sales_delivery_order->db->error;
265
};
266

  
267
sub transfer_purchase_delivery_order {
268
  my ($purchase_delivery_order) = @_;
269
  die "first argument must be a purchase delivery order Rose DB object" unless ref($purchase_delivery_order) eq 'SL::DB::DeliveryOrder' and not $purchase_delivery_order->is_sales;
270

  
271
  my ($wh, $bin, $trans_type);
272

  
273
  $purchase_delivery_order->db->with_transaction(sub {
274

  
275
   foreach my $doi ( @{ $purchase_delivery_order->items } ) {
276
     my $trans_type = SL::DB::Manager::TransferType->find_by(direction => 'in', description => 'stock');
277
     transfer_delivery_order_item($doi, $wh, $bin, $trans_type);
278
   };
279
   1;
280
  }) or die "error while transferring purchase_Delivery_order: " . $purchase_delivery_order->db->error;
281
};
282

  
283
sub transfer_delivery_order_item {
284
  my ($doi, $wh, $bin, $trans_type) = @_;
285

  
286
  unless ( defined $trans_type and ref($trans_type eq 'SL::DB::TransferType') ) {
287
    if ( $doi->record->is_sales ) {
288
      $trans_type //=  SL::DB::Manager::TransferType->find_by(direction => 'out', description => 'shipped');
289
    } else {
290
      $trans_type //= SL::DB::Manager::TransferType->find_by(direction => 'in', description => 'stock');
291
    }
292
  }
293

  
294
  $bin //= $doi->part->bin;
295
  $wh  //= $doi->part->warehouse;
296

  
297
  die "no bin and wh specified and part has no default bin or wh" unless $bin and $wh;
298

  
299
  my $employee = SL::DB::Manager::Employee->current || die "No employee";
300

  
301
  # dois are converted to base_qty, which is qty
302
  # AM->convert_unit( 'g' => 'kg') * 1000;   # 1
303
  #               $doi->unit   $doi->part->unit   $doi->qty
304
  my $dois = SL::DB::DeliveryOrderItemsStock->new(
305
    delivery_order_item => $doi,
306
    qty                 => AM->convert_unit($doi->unit => $doi->part->unit) * $doi->qty,
307
    unit                => $doi->part->unit,
308
    warehouse_id        => $wh->id,
309
    bin_id              => $bin->id,
310
  )->save;
311

  
312
  my $inventory = SL::DB::Inventory->new(
313
    parts                      => $dois->delivery_order_item->part,
314
    qty                        => $dois->delivery_order_item->record->is_sales ? $dois->qty * -1 : $dois->qty,
315
    oe                         => $doi->record,
316
    warehouse_id               => $dois->warehouse_id,
317
    bin_id                     => $dois->bin_id,
318
    trans_type_id              => $trans_type->id,
319
    delivery_order_items_stock => $dois,
320
    trans_id                   => $dois->id,
321
    employee_id                => $employee->id,
322
    shippingdate               => $doi->record->transdate,
323
  )->save;
324
};
325

  
187 326
1;
188 327

  
189 328
__END__
......
280 419
  $part->get_stock(bin_id => $wh->bins->[4]->id); # 3.00000
281 420
  $part->get_stock(bin_id => $wh->bins->[2]->id); # 2.00000
282 421

  
422
=head2 C<transfer_sales_delivery_order %PARAMS>
423

  
424
Takes a SL::DB::DeliveryOrder object as its first argument and transfers out
425
all the items via their default bin, creating the delivery_order_stock and
426
inventory entries.
427

  
428
Assumes a fresh delivery order where nothing has been transferred out yet.
429

  
430
Should work like the functions in do.pl transfer_in/transfer_out and DO.pm
431
transfer_in_out, except that those work on the current form where as this just
432
works on database objects.
433

  
434
As this is just Dev it doesn't check for negative stocks etc.
435

  
436
Usage:
437
  my $sales_delivery_order = SL::DB::Manager::DeliveryOrder->find_by(donumber => 112);
438
  SL::Dev::Inventory::transfer_sales_delivery_order($sales_delivery_order1);
439

  
440
=head2 C<transfer_purchase_delivery_order %PARAMS>
441

  
442
Transfer in all the items in a purchase order.
443

  
444
Behaves like C<transfer_sales_delivery_order>.
445

  
446
=head2 C<transfer_delivery_order_item @PARAMS>
447

  
448
Transfers a delivery order item from a delivery order. The whole qty is transferred.
449
Doesn't check for available qty.
450

  
451
Usage:
452
  SL::Dev::Inventory::transfer_delivery_order_item($doi, $wh, $bin, $trans_type);
453

  
454
=head2 C<transfer_in %PARAMS>
455

  
456
Create stock in event for a part. Ideally the interface should mirror how data
457
is entered via the web interface.
458

  
459
Does some param checking, sets some defaults, but otherwise uses WH->transfer.
460

  
461
Mandatory params:
462
  part               - an SL::DB::Part object
463
  qty                - a number
464

  
465
Optional params: shippingdate
466
  bin           - an SL::DB::Bin object, defaults to $part->bin
467
  wh            - an SL::DB::Bin object, defaults to $part->warehouse
468
  unit          - a string such as 't', 'Stck', defaults to $part->unit->name
469
  shippingdate  - a DateTime object, defaults to today
470
  transfer_type - a string such as 'correction', defaults to 'stock'
471
  comment
472

  
473
Example minimal usage using part default warehouse and bin:
474
  my ($wh, $bin) = SL::Dev::Inventory::create_warehouse_and_bins();
475
  my $part       = SL::Dev::Part::create_part(unit => 'kg', warehouse => $wh, bin => $bin)->save;
476
  SL::Dev::Inventory::transfer_in(part => $part, qty => '0.9', unit => 't', comment => '900 kg in t');
477

  
478
Example with specific transfer_type and warehouse and bin and shipping_date:
479
  my $shipping_date = DateTime->today->subtract( days => 20 );
480
  SL::Dev::Inventory::transfer_in(part          => $part,
481
                                  qty           => 5,
482
                                  transfer_type => 'correction',
483
                                  bin           => $bin,
484
                                  shipping_date => $shipping_date,
485
                                 );
486

  
487
=head2 C<transfer_out %PARAMS>
488

  
489
Create stock out event for a part. See C<transfer_in>.
490

  
283 491
=head1 BUGS
284 492

  
285 493
Nothing here yet.

Auch abrufbar als: Unified diff