commit c94dbd0eccee66a266ddff4d3f3678766a6da6c4
Author: Tamino Steinert <tamino.steinert@tamino.st>
Date:   Fri Oct 6 12:39:09 2023 +0200

    Order: Nutze Type und ID zum Erstellen von verknüpften Belegen

diff --git a/SL/Controller/Order.pm b/SL/Controller/Order.pm
index 4feaf2d45..b16899938 100644
--- a/SL/Controller/Order.pm
+++ b/SL/Controller/Order.pm
@@ -33,7 +33,7 @@ use SL::DB::RecordLink;
 use SL::DB::Shipto;
 use SL::DB::Translation;
 use SL::DB::ValidityToken;
-use SL::DB::Helper::RecordLink qw(set_record_link_conversions RECORD_ID RECORD_ITEM_ID);
+use SL::DB::Helper::RecordLink qw(set_record_link_conversions RECORD_ID RECORD_TYPE_REF RECORD_ITEM_ID RECORD_ITEM_TYPE_REF);
 use SL::DB::Helper::TypeDataProxy;
 use SL::DB::Helper::Record qw(get_object_name_from_type get_class_from_type);
 use SL::Model::Record;
@@ -120,16 +120,6 @@ sub action_add_from_record {
   my $order = SL::Model::Record->new_from_workflow($record, $self->type, %flags);
   $self->order($order);
 
-  if (ref($record) eq 'SL::DB::Reclamation') {
-    $self->{converted_from_reclamation_id}       = $order->{ RECORD_ID()      };
-    $_   ->{converted_from_reclamation_items_id} = $_    ->{ RECORD_ITEM_ID() } for @{ $order->items_sorted };
-  }
-  if (ref($record) eq 'SL::DB::Order') {
-    $self->{converted_from_oe_id}       = $order->{ RECORD_ID()      };
-    $_   ->{converted_from_oe_items_id} = $_    ->{ RECORD_ITEM_ID() } for @{ $order->items_sorted };
-  }
-
-
   $self->recalc();
   $self->pre_render();
 
@@ -230,8 +220,7 @@ sub action_edit_collective {
 
   # make new order from given orders
   my @multi_orders = map { SL::DB::Order->new(id => $_)->load } @multi_ids;
-  $self->{converted_from_oe_id} = join ' ', map { $_->id } @multi_orders;
-  my $target_type = "sales_order";
+  my $target_type = SALES_ORDER_TYPE();
   my $order = SL::Model::Record->new_from_workflow_multi(\@multi_orders, $target_type, sort_sources_by => 'transdate');
   $self->order($order);
 
@@ -1588,8 +1577,8 @@ sub js_reset_order_and_item_ids_after_save {
 
   $self->js
     ->val('#id', $self->order->id)
-    ->val('#converted_from_oe_id', '')
-    ->val('#converted_from_reclamation_id', '')
+    ->val('#converted_from_record_type_ref', '')
+    ->val('#converted_from_record_id',  '')
     ->val('#order_' . $self->nr_key(), $self->order->number);
 
   my $idx = 0;
@@ -1603,8 +1592,8 @@ sub js_reset_order_and_item_ids_after_save {
   } continue {
     $idx++;
   }
-  $self->js->val('[name="converted_from_orderitems_ids[+]"]', '');
-  $self->js->val('[name="converted_from_reclamation_items_ids[+]"]', '');
+  $self->js->val('[name="converted_from_record_item_type_refs[+]"]', '');
+  $self->js->val('[name="converted_from_record_item_ids[+]"]', '');
   $self->js->val('[name="basket_item_ids[+]"]', '');
 }
 
@@ -2059,27 +2048,24 @@ sub parse_phone_note {
 sub save {
   my ($self) = @_;
 
+  my $is_new = !$self->order->id;
+
   $self->parse_phone_note if $::form->{phone_note}->{subject} || $::form->{phone_note}->{body};
 
   # create first version if none exists
   $self->order->add_order_version(SL::DB::OrderVersion->new(version => 1)) if !$self->order->order_version;
 
+  set_record_link_conversions($self->order,
+    delete $::form->{RECORD_TYPE_REF()}
+      => delete $::form->{RECORD_ID()},
+    delete $::form->{RECORD_ITEM_TYPE_REF()}
+      => delete $::form->{RECORD_ITEM_ID()},
+  );
+
   my @converted_from_oe_ids;
-  if ($::form->{converted_from_oe_id}) {
-    @converted_from_oe_ids = split ' ', $::form->{converted_from_oe_id};
-    set_record_link_conversions(
-      $self->order,
-      'SL::DB::Order'     => \@converted_from_oe_ids,
-      'SL::DB::OrderItem' => $::form->{converted_from_orderitems_ids},
-    );
-  }
-  if ($::form->{converted_from_reclamation_id}) {
-    my @converted_from_reclamation_ids = split ' ', $::form->{converted_from_reclamation_id};
-    set_record_link_conversions(
-      $self->order,
-      'SL::DB::Reclamation'     => \@converted_from_reclamation_ids,
-      'SL::DB::ReclamationItem' => $::form->{converted_from_reclamation_items_ids},
-    );
+  if ($self->order->{RECORD_TYPE_REF()} eq 'SL::DB::Order'
+      && $self->order->{RECORD_ID()}) {
+    @converted_from_oe_ids = split ' ', $self->order->{RECORD_ID()};
   }
 
   # check for purchase basket items
@@ -2103,8 +2089,6 @@ sub save {
     }
   }
 
-  my $is_new = !$self->order->id;
-
   my $objects_to_close = scalar @converted_from_oe_ids
                        ? SL::DB::Manager::Order->get_all(where => [
                            id => \@converted_from_oe_ids,
diff --git a/SL/DB/Helper/RecordLink.pm b/SL/DB/Helper/RecordLink.pm
index aa8adfb6a..65af39e22 100644
--- a/SL/DB/Helper/RecordLink.pm
+++ b/SL/DB/Helper/RecordLink.pm
@@ -71,6 +71,7 @@ sub set_record_link_conversions {
   my $idx = 0;
   my $items = $record->items_sorted;
 
+  $item_ids ||= [];
   croak "more item ids than items in record" if @$item_ids > @$items;
 
   for my $idx (0..$#$item_ids) {
diff --git a/SL/DB/Order.pm b/SL/DB/Order.pm
index 1d3a6ed21..5a5d6d8b1 100644
--- a/SL/DB/Order.pm
+++ b/SL/DB/Order.pm
@@ -526,16 +526,6 @@ sub new_from {
     any { $from_to->{abbr} eq $_ } @abbrs;
   };
 
-  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';
-  } elsif ( ref($source) eq 'SL::DB::Reclamation') {
-    $item_parent_id_column = 'reclamation_id';
-    $item_parent_column    = 'reclamation';
-  }
-
   my %args;
   if (ref($source) eq 'SL::DB::Order') {
     %args = ( map({ ( $_ => $source->$_ ) } qw(amount cp_id currency_id cusordnumber customer_id delivery_customer_id delivery_term_id delivery_vendor_id
@@ -627,16 +617,10 @@ sub new_from {
   $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;
     if (ref($source) eq 'SL::DB::Order') {
       $current_oe_item = SL::DB::OrderItem->new(map({ ( $_ => $source_item->$_ ) }
@@ -668,7 +652,7 @@ sub new_from {
       $current_oe_item->lastcost($source_item->sellprice);
     }
     unless ($params{no_linked_records}) {
-      $current_oe_item->{ RECORD_ITEM_ID() } = $_->{id};
+      $current_oe_item->{ RECORD_ITEM_ID() } = $source_item->{id};
       $current_oe_item->{ RECORD_ITEM_TYPE_REF() } = ref($source_item);
     }
     $current_oe_item;
@@ -756,6 +740,7 @@ sub new_from_multi {
                                attributes       => \%attributes,
                                items            => \@items,
                                %params);
+  $order->{RECORD_ID()} = join ' ', map { $_->id } @$sources; # link all sources
 
   return $order;
 }
diff --git a/templates/design40_webpages/order/form.html b/templates/design40_webpages/order/form.html
index 18f830b1d..98d95e5dc 100644
--- a/templates/design40_webpages/order/form.html
+++ b/templates/design40_webpages/order/form.html
@@ -21,8 +21,8 @@
   [% L.hidden_tag('callback',             FORM.callback) %]
   [% L.hidden_tag('type',                 FORM.type) %]
   [% L.hidden_tag('id',                   SELF.order.id) %]
-  [% L.hidden_tag('converted_from_oe_id', SELF.converted_from_oe_id) %]
-  [% L.hidden_tag('converted_from_reclamation_id', SELF.converted_from_reclamation_id) %]
+  [% L.hidden_tag('converted_from_record_type_ref', SELF.order.converted_from_record_type_ref) %]
+  [% L.hidden_tag('converted_from_record_id',  SELF.order.converted_from_record_id) %]
 
   [% IF !SELF.order.id %]
   [%   L.hidden_tag('form_validity_token', FORM.form_validity_token) %]
diff --git a/templates/design40_webpages/order/tabs/_row.html b/templates/design40_webpages/order/tabs/_row.html
index 7eb3768f8..718b7888e 100644
--- a/templates/design40_webpages/order/tabs/_row.html
+++ b/templates/design40_webpages/order/tabs/_row.html
@@ -15,8 +15,8 @@
                      alt=LxERP.t8('Show details'), title=LxERP.t8('Show details'), class="expand") %]
       [% END %]
       [% L.hidden_tag("orderitem_ids[+]", ID) %]
-      [% L.hidden_tag("converted_from_orderitems_ids[+]", ITEM.converted_from_orderitems_id) %]
-      [% L.hidden_tag("converted_from_reclamation_items_ids[+]", ITEM.converted_from_reclamation_items_id) %]
+      [% L.hidden_tag("converted_from_record_item_type_ref[+]", ITEM.converted_from_record_item_type_ref) %]
+      [% L.hidden_tag("converted_from_record_item_id[+]",       ITEM.converted_from_record_item_id) %]
       [% L.hidden_tag("order.orderitems[+].id", ITEM.id, id='item_' _ ID) %]
       [% L.hidden_tag("order.orderitems[].parts_id", ITEM.parts_id) %]
       [% L.hidden_tag("basket_item_ids[+]", ITEM.basket_item_id) %]
diff --git a/templates/webpages/order/form.html b/templates/webpages/order/form.html
index e9dab0fd8..bfc2837ac 100644
--- a/templates/webpages/order/form.html
+++ b/templates/webpages/order/form.html
@@ -21,8 +21,8 @@
   [% L.hidden_tag('callback',             FORM.callback) %]
   [% L.hidden_tag('type',                 FORM.type) %]
   [% L.hidden_tag('id',                   SELF.order.id) %]
-  [% L.hidden_tag('converted_from_oe_id', SELF.converted_from_oe_id) %]
-  [% L.hidden_tag('converted_from_reclamation_id', SELF.converted_from_reclamation_id) %]
+  [% L.hidden_tag('converted_from_record_type_ref', SELF.order.converted_from_record_type_ref) %]
+  [% L.hidden_tag('converted_from_record_id',  SELF.order.converted_from_record_id) %]
 
   [% IF !SELF.order.id %]
   [%   L.hidden_tag('form_validity_token', FORM.form_validity_token) %]
diff --git a/templates/webpages/order/tabs/_row.html b/templates/webpages/order/tabs/_row.html
index 4411f8057..6b005fbbe 100644
--- a/templates/webpages/order/tabs/_row.html
+++ b/templates/webpages/order/tabs/_row.html
@@ -15,8 +15,8 @@
                      alt=LxERP.t8('Show details'), title=LxERP.t8('Show details'), class="expand") %]
       [%- END %]
       [% L.hidden_tag("orderitem_ids[+]", ID) %]
-      [% L.hidden_tag("converted_from_orderitems_ids[+]", ITEM.converted_from_orderitems_id) %]
-      [% L.hidden_tag("converted_from_reclamation_items_ids[+]", ITEM.converted_from_reclamation_items_id) %]
+      [% L.hidden_tag("converted_from_record_item_type_ref[+]", ITEM.converted_from_record_item_type_ref) %]
+      [% L.hidden_tag("converted_from_record_item_id[+]",       ITEM.converted_from_record_item_id) %]
       [% L.hidden_tag("order.orderitems[+].id", ITEM.id, id='item_' _ ID) %]
       [% L.hidden_tag("order.orderitems[].parts_id", ITEM.parts_id) %]
       [% L.hidden_tag("purchase_basket_item_ids[+]", ITEM.purchase_basket_item_ids) %]
