X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FHelper%2FShippedQty.pm;h=2ac4e3974a32bdb54b5875d373771ffe80d9867b;hb=0f521b3d8ea765b3e39f2f817e5f4f97a23d562c;hp=af2a4f47cbad5115418e3caa16a51233e329c869;hpb=c4104eb32fe068961c83d5905816686637d4abc6;p=kivitendo-erp.git diff --git a/SL/Helper/ShippedQty.pm b/SL/Helper/ShippedQty.pm index af2a4f47c..2ac4e3974 100644 --- a/SL/Helper/ShippedQty.pm +++ b/SL/Helper/ShippedQty.pm @@ -3,17 +3,19 @@ package SL::Helper::ShippedQty; use strict; use parent qw(Rose::Object); -use SL::AM; +use Carp; use Scalar::Util qw(blessed); -use SL::DBUtils qw(selectall_hashref_query selectall_as_map); use List::Util qw(min); use List::MoreUtils qw(any all uniq); use List::UtilsBy qw(partition_by); +use SL::AM; +use SL::DBUtils qw(selectall_hashref_query selectall_as_map); use SL::Locale::String qw(t8); use Rose::Object::MakeMethods::Generic ( 'scalar' => [ qw(objects objects_or_ids shipped_qty keep_matches) ], - 'scalar --get_set_init' => [ qw(oe_ids dbh require_stock_out fill_up item_identity_fields oi2oe oi_qty delivered matches) ], + 'scalar --get_set_init' => [ qw(oe_ids dbh require_stock_out fill_up item_identity_fields oi2oe oi_qty delivered matches + services_deliverable) ], ); my $no_stock_item_links_query = <<''; @@ -25,6 +27,7 @@ my $no_stock_item_links_query = <<''; ORDER BY oi.trans_id, oi.position # oi not item linked. takes about 250ms for 100k hits +# obsolete since 3.5.6 my $fill_up_oi_query = <<''; SELECT oi.id, oi.trans_id, oi.position, oi.parts_id, oi.description, oi.reqdate, oi.serialnumber, oi.qty, oi.unit FROM orderitems oi @@ -32,6 +35,7 @@ my $fill_up_oi_query = <<''; ORDER BY oi.trans_id, oi.position # doi linked by record, but not by items; 250ms for 100k hits +# obsolete since 3.5.6 my $no_stock_fill_up_doi_query = <<''; SELECT doi.id, doi.delivery_order_id, doi.position, doi.parts_id, doi.description, doi.reqdate, doi.serialnumber, doi.qty, doi.unit FROM delivery_order_items doi @@ -102,7 +106,7 @@ my %item_identity_fields = ( sub calculate { my ($self, $data) = @_; - die 'Need exactly one argument, either id, object or arrayref of ids or objects.' unless 2 == @_; + croak 'Need exactly one argument, either id, object or arrayref of ids or objects.' unless 2 == @_; $self->normalize_input($data); @@ -207,7 +211,7 @@ sub calculate_fill_up { sub write_to { my ($self, $objects) = @_; - die 'expecting array of objects' unless 'ARRAY' eq ref $objects; + croak 'expecting array of objects' unless 'ARRAY' eq ref $objects; my $shipped_qty = $self->shipped_qty; @@ -216,12 +220,13 @@ sub write_to { $obj->{shipped_qty} = $shipped_qty->{$obj->id} //= 0; $obj->{delivered} = $shipped_qty->{$obj->id} == $obj->qty; } elsif ('SL::DB::Order' eq ref $obj) { - if (defined $obj->{orderitems}) { - $self->write_to($obj->{orderitems}); - $obj->{delivered} = all { $_->{delivered} } @{ $obj->{orderitems} }; + # load all orderitems unless not already loaded + $obj->orderitems unless (defined $obj->{orderitems}); + $self->write_to($obj->{orderitems}); + if ($self->services_deliverable) { + $obj->{delivered} = all { $_->{delivered} } grep { !$_->{optional} } @{ $obj->{orderitems} }; } else { - # don't force a load on items. just compute by oe_id directly - $obj->{delivered} = $self->delivered->{$obj->id}; + $obj->{delivered} = all { $_->{delivered} } grep { !$_->{optional} && !$_->part->is_service } @{ $obj->{orderitems} }; } } else { die "unknown reference '@{[ ref $obj ]}' for @{[ __PACKAGE__ ]}::write_to"; @@ -235,7 +240,7 @@ sub write_to_objects { return unless @{ $self->oe_ids }; - die 'Can only use write_to_objects, when calculate was called with objects. Use write_to instead.' unless $self->objects_or_ids; + croak 'Can only use write_to_objects, when calculate was called with objects. Use write_to instead.' unless $self->objects_or_ids; $self->write_to($self->objects); } @@ -254,17 +259,33 @@ sub normalize_input { $self->objects_or_ids(!!blessed($data->[0])); if ($self->objects_or_ids) { - die 'unblessed object in data while expecting object' if any { !blessed($_) } @$data; + croak 'unblessed object in data while expecting object' if any { !blessed($_) } @$data; $self->objects($data); } else { - die 'object or reference in data while expecting ids' if any { ref($_) } @$data; - die 'ids need to be numbers' if any { ! ($_ * 1) } @$data; + croak 'object or reference in data while expecting ids' if any { ref($_) } @$data; + croak 'ids need to be numbers' if any { ! ($_ * 1) } @$data; $self->oe_ids($data); } $self->shipped_qty({}); } +# some of the invocations never need to load all orderitems to copute their answers +# delivered however needs oi_qty to be set for each orderitem to decide whether +# delivered should be set or not. +sub ensure_all_orderitems_for_orders { + my ($self) = @_; + + return if $self->fill_up; + + my $oi_query = sprintf $fill_up_oi_query, join (', ', ('?')x@{ $self->oe_ids }); + my $oi = selectall_hashref_query($::form, $self->dbh, $oi_query, @{ $self->oe_ids }); + for (@$oi) { + $self->{oi_qty}{ $_->{id} } //= $_->{qty}; + $self->{oi2oe}{ $_->{id} } //= $_->{trans_id}; + } +} + sub available_item_identity_fields { map { [ $_ => $item_identity_fields{$_} ] } @known_item_identity_fields; } @@ -272,9 +293,9 @@ sub available_item_identity_fields { sub init_oe_ids { my ($self) = @_; - die 'oe_ids not initialized in id mode' if !$self->objects_or_ids; - die 'objects not initialized before accessing ids' if $self->objects_or_ids && !defined $self->objects; - die 'objects need to be Order or OrderItem' if any { ref($_) !~ /^SL::DB::Order(?:Item)?$/ } @{ $self->objects }; + croak 'oe_ids not initialized in id mode' if !$self->objects_or_ids; + croak 'objects not initialized before accessing ids' if $self->objects_or_ids && !defined $self->objects; + croak 'objects need to be Order or OrderItem' if any { ref($_) !~ /^SL::DB::Order(?:Item)?$/ } @{ $self->objects }; [ uniq map { ref($_) =~ /Item/ ? $_->trans_id : $_->id } @{ $self->objects } ] } @@ -286,6 +307,10 @@ sub init_oi_qty { {} } sub init_matches { [] } sub init_delivered { my ($self) = @_; + + # is needed in odyn + # $self->ensure_all_orderitems_for_orders; + my $d = { }; for (keys %{ $self->oi_qty }) { my $oe_id = $self->oi2oe->{$_}; @@ -299,6 +324,17 @@ sub init_require_stock_out { $::instance_conf->get_shipped_qty_require_stock_ sub init_item_identity_fields { [ grep $item_identity_fields{$_}, @{ $::instance_conf->get_shipped_qty_item_identity_fields } ] } sub init_fill_up { $::instance_conf->get_shipped_qty_fill_up } +sub init_services_deliverable { + my ($self) = @_; + if ($::form->{type} =~ m/^sales_/) { + $::instance_conf->get_sales_delivery_order_check_service; + } elsif ($::form->{type} =~ m/^purchase_/) { + $::instance_conf->get_purchase_delivery_order_check_service; + } else { + croak "wrong call, no customer or vendor object referenced"; + } +} + 1; __END__ @@ -326,7 +362,7 @@ SL::Helper::ShippedQty - Algorithmic module for calculating shipped qty $helper->calculate($oe_id); $helper->calculate(\@oe_ids); - # if these are items set elivered and shipped_qty + # if these are items set delivered and shipped_qty # if these are orders, iterate through their items and set delivered on order $helper->write_to($objects); @@ -416,7 +452,9 @@ include a bulk mode to speed up multiple objects. =item C -Creates a new helper object. PARAMS may include: +Creates a new helper object, $::form->{type} is mandatory. + +PARAMS may include: =over 4 @@ -456,6 +494,7 @@ than this modules provides. See C for the returned format. + =back =item C