From: Bernd Bleßmann Date: Wed, 7 Feb 2018 12:29:18 +0000 (+0100) Subject: SL::DB::Order->new_from implementiert. X-Git-Tag: release-3.5.4~469 X-Git-Url: http://wagnertech.de/git?a=commitdiff_plain;h=b14755d0d16684f8c000fdce8d27309a226a15cd;p=kivitendo-erp.git SL::DB::Order->new_from implementiert. Im Moment nur von Angeboten zu Aufträgen (Ein- und Verkauf). --- diff --git a/SL/DB/Order.pm b/SL/DB/Order.pm index 7d5e2fe4a..ec1212568 100644 --- a/SL/DB/Order.pm +++ b/SL/DB/Order.pm @@ -189,6 +189,90 @@ sub convert_to_delivery_order { return $delivery_order; } +sub _clone_orderitem_cvar { + my ($cvar) = @_; + + my $cloned = $_->clone_and_reset; + $cloned->sub_module('orderitems'); + + return $cloned; +} + +sub new_from { + my ($class, $source, %params) = @_; + + croak("Unsupported source object type '" . ref($source) . "'") unless ref($source) eq 'SL::DB::Order'; + croak("A destination type must be given parameter") unless $params{destination_type}; + + my $destination_type = delete $params{destination_type}; + my $src_dst_allowed = ('sales_quotation' eq $source->type && 'sales_order' eq $destination_type) + || ('request_quotation' eq $source->type && 'purchase_order' eq $destination_type); + croak("Cannot convert from '" . $source->type . "' to '" . $destination_type . "'") unless $src_dst_allowed; + + my ($item_parent_id_column, $item_parent_column); + + if (ref($source) eq 'SL::DB::Order') { + $item_parent_id_column = 'trans_id'; + $item_parent_column = 'order'; + } + + my %args = ( map({ ( $_ => $source->$_ ) } qw(amount cp_id currency_id cusordnumber customer_id delivery_customer_id delivery_term_id delivery_vendor_id + department_id employee_id globalproject_id intnotes marge_percent marge_total language_id netamount notes + ordnumber payment_id quonumber reqdate salesman_id shippingpoint shipvia taxincluded taxzone_id + transaction_description vendor_id + )), + quotation => 0, + closed => 0, + delivered => 0, + transdate => DateTime->today_local, + ); + + # Custom shipto addresses (the ones specific to the sales/purchase + # record and not to the customer/vendor) are only linked from + # shipto → delivery_orders. Meaning delivery_orders.shipto_id + # will not be filled in that case. + if (!$source->shipto_id && $source->id) { + $args{custom_shipto} = $source->custom_shipto->clone($class) if $source->can('custom_shipto') && $source->custom_shipto; + + } else { + $args{shipto_id} = $source->shipto_id; + } + + my $order = $class->new(%args); + $order->assign_attributes(%{ $params{attributes} }) if $params{attributes}; + my $items = delete($params{items}) || $source->items_sorted; + my %item_parents; + + my @items = map { + my $source_item = $_; + my $source_item_id = $_->$item_parent_id_column; + my @custom_variables = map { _clone_orderitem_cvar($_) } @{ $source_item->custom_variables }; + + $item_parents{$source_item_id} ||= $source_item->$item_parent_column; + my $item_parent = $item_parents{$source_item_id}; + + my $current_oe_item = SL::DB::OrderItem->new(map({ ( $_ => $source_item->$_ ) } + qw(active_discount_source active_price_source base_qty cusordnumber + description discount lastcost longdescription + marge_percent marge_price_factor marge_total + ordnumber parts_id price_factor price_factor_id pricegroup_id + project_id qty reqdate sellprice serialnumber ship subtotal transdate unit + )), + custom_variables => \@custom_variables, + ); + $current_oe_item->{"converted_from_orderitems_id"} = $_->{id} if ref($item_parent) eq 'SL::DB::Order'; + $current_oe_item; + } @{ $items }; + + @items = grep { $params{item_filter}->($_) } @items if $params{item_filter}; + @items = grep { $_->qty * 1 } @items if $params{skip_items_zero_qty}; + @items = grep { $_->qty >=0 } @items if $params{skip_items_negative_qty}; + + $order->items(\@items); + + return $order; +} + sub number { my $self = shift; @@ -283,6 +367,61 @@ nothing is created or changed in the database. At the moment only sales quotations and sales orders can be converted. +=head2 C + +Creates a new C instance and copies as much +information from C<$source> as possible. At the moment only sales orders from +sales quotations and purchase orders from requests for quotations can be +created. + +The C field will be set to the current date. + +The conversion copies the order items as well. + +Returns the new order instance. The object returned is not +saved. + +C<%params> can include the following options +(C is mandatory): + +=over 4 + +=item C + +(mandatory) +The type of the newly created object. Can be C or +C for now. + +=item C + +An optional array reference of RDBO instances for the items to use. If +missing then the method C will be called on +C<$source>. This option can be used to override the sorting, to +exclude certain positions or to add additional ones. + +=item C + +If trueish then items with a negative quantity are skipped. Items with +a quantity of 0 are not affected by this option. + +=item C + +If trueish then items with a quantity of 0 are skipped. + +=item C + +An optional code reference that is called for each item with the item +as its sole parameter. Items for which the code reference returns a +falsish value will be skipped. + +=item C + +An optional hash reference. If it exists then it is passed to C +allowing the caller to set certain attributes for the new delivery +order. + +=back + =head2 C Creates and saves a new sales process. Can only be called for sales