commit 83b9d2b3008f931f4fb7fdce5c456b658c8f75b3
Author: Tamino Steinert <tamino.steinert@tamino.st>
Date:   Wed Nov 3 09:43:41 2021 +0100

    Workflow: sales_reclamation → credit_note

diff --git a/SL/Controller/Reclamation.pm b/SL/Controller/Reclamation.pm
index 1842bb4ec..8c8443635 100644
--- a/SL/Controller/Reclamation.pm
+++ b/SL/Controller/Reclamation.pm
@@ -70,6 +70,7 @@ __PACKAGE__->run_before('recalc',
                           workflow_save_and_sales_or_purchase_reclamation
                           save_and_order
                           save_and_delivery_order
+                          save_and_credit_note
                        )]);
 
 __PACKAGE__->run_before('get_unalterable_data',
@@ -79,6 +80,7 @@ __PACKAGE__->run_before('get_unalterable_data',
                           workflow_save_and_sales_or_purchase_reclamation
                           save_and_order
                           save_and_delivery_order
+                          save_and_credit_note
                         )]);
 
 #
@@ -602,6 +604,26 @@ sub action_save_and_delivery_order {
   );
 }
 
+# save the reclamation and redirect to the frontend subroutine for a new
+# credit_note
+sub action_save_and_credit_note {
+  my ($self) = @_;
+
+  # always save
+  $self->save_with_render_error();
+
+  if (!$self->reclamation->is_sales) {
+    $self->js->flash('error', t8("Can't convert Purchase Reclamation to Credit Note"));
+    return $self->js->render();
+  }
+
+  $self->save_and_redirect_to(
+    controller => 'is.pl',
+    action     => 'credit_note_from_reclamation',
+    from_id    => $self->reclamation->id,
+  );
+}
+
 # set form elements in respect to a changed customer or vendor
 #
 # This action is called on an change of the customer/vendor picker.
@@ -2233,6 +2255,15 @@ sub _setup_edit_action_bar {
             $::instance_conf->get_reclamation_warn_no_reqdate,
           ],
         ],
+        action => [
+          t8('Save and Credit Note'),
+          call      => [
+            'kivi.Reclamation.save', 'save_and_credit_note',
+            $::instance_conf->get_reclamation_warn_duplicate_parts,
+            $::instance_conf->get_reclamation_warn_no_reqdate,
+          ],
+          only_if   => (any { $self->type eq $_ } (sales_reclamation_type())),
+        ],
       ], # end of combobox "Workflow"
 
       combobox => [
diff --git a/SL/DB/Helper/FlattenToForm.pm b/SL/DB/Helper/FlattenToForm.pm
index 591073e18..9fe1f1fc7 100644
--- a/SL/DB/Helper/FlattenToForm.pm
+++ b/SL/DB/Helper/FlattenToForm.pm
@@ -74,6 +74,7 @@ sub flatten_to_form {
   my $items_name = ref($self) eq 'SL::DB::Order'         ? 'orderitems'
                  : ref($self) eq 'SL::DB::DeliveryOrder' ? 'delivery_order_items'
                  : ref($self) eq 'SL::DB::Invoice'       ? 'invoice'
+                 : ref($self) eq 'SL::DB::Reclamation'   ? 'reclamation_items'
                  : '';
 
   my %cvar_validity = _determine_cvar_validity($self, $vc);
diff --git a/SL/IS.pm b/SL/IS.pm
index fdc70ab3a..a07d238d6 100644
--- a/SL/IS.pm
+++ b/SL/IS.pm
@@ -990,7 +990,7 @@ SQL
                                   dbh          => $dbh);
     }
     # link previous items with invoice items
-    foreach (qw(delivery_order_items orderitems invoice)) {
+    foreach (qw(delivery_order_items orderitems invoice reclamation_items)) {
       if (!$form->{useasnew} && $form->{"converted_from_${_}_id_$i"}) {
         RecordLinks->create_links('dbh'        => $dbh,
                                   'mode'       => 'ids',
@@ -1529,27 +1529,18 @@ SQL
 
   Common::webdav_folder($form);
 
-  if ($form->{convert_from_ar_ids}) {
-    RecordLinks->create_links('dbh'        => $dbh,
-                              'mode'       => 'ids',
-                              'from_table' => 'ar',
-                              'from_ids'   => $form->{convert_from_ar_ids},
-                              'to_table'   => 'ar',
-                              'to_id'      => $form->{id},
-    );
-    delete $form->{convert_from_ar_ids};
-  }
-
   # Link this record to the records it was created from.
-  if ($form->{convert_from_oe_ids}) {
-    RecordLinks->create_links('dbh'        => $dbh,
-                              'mode'       => 'ids',
-                              'from_table' => 'oe',
-                              'from_ids'   => $form->{convert_from_oe_ids},
-                              'to_table'   => 'ar',
-                              'to_id'      => $form->{id},
+  foreach (qw(oe ar reclamations)) {
+    if ($form->{"convert_from_${_}_ids"}) {
+      RecordLinks->create_links('dbh'        => $dbh,
+                                'mode'       => 'ids',
+                                'from_table' => $_,
+                                'from_ids'   => $form->{"convert_from_${_}_ids"},
+                                'to_table'   => 'ar',
+                                'to_id'      => $form->{id},
       );
-    delete $form->{convert_from_oe_ids};
+      delete $form->{"convert_from_${_}_ids"};
+    }
   }
 
   my @convert_from_do_ids = map { $_ * 1 } grep { $_ } split m/\s+/, $form->{convert_from_do_ids};
diff --git a/bin/mozilla/io.pl b/bin/mozilla/io.pl
index 738c5c142..e1629dae4 100644
--- a/bin/mozilla/io.pl
+++ b/bin/mozilla/io.pl
@@ -257,9 +257,11 @@ sub display_row {
     my $record_item = $record->id && $record->items ? $record->items->[$i-1] : _make_record_item($i);
 
     # undo formatting
+    $main::lxdebug->dump(0, "TST: before parse_amount", $form->{"sellprice_$i"});
     map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) }
       qw(qty discount sellprice lastcost price_new price_old)
         unless ($form->{simple_save});
+    $main::lxdebug->dump(0, "TST: after parse_amount", $form->{"sellprice_$i"});
 
     if ($form->{"prices_$i"} && ($form->{"new_pricegroup_$i"} != $form->{"old_pricegroup_$i"})) {
       $form->{"sellprice_$i"} = $form->{"price_new_$i"};
@@ -474,7 +476,7 @@ sub display_row {
       push @hidden_vars, qw(invoice_id converted_from_orderitems_id converted_from_delivery_order_items_id converted_from_invoice_id);
     }
     if ($::form->{type} =~ /credit_note/) {
-      push @hidden_vars, qw(invoice_id converted_from_invoice_id);
+      push @hidden_vars, qw(invoice_id converted_from_invoice_id converted_from_reclamation_items_id);
     }
    if ($is_delivery_order) {
       map { $form->{"${_}_${i}"} = $form->format_amount(\%myconfig, $form->{"${_}_${i}"}) } qw(sellprice discount lastcost);
@@ -831,7 +833,8 @@ sub remove_emptied_rows {
                 stock_out stock_in has_sernumber reqdate orderitems_id
                 active_price_source active_discount_source delivery_order_items_id
                 invoice_id converted_from_orderitems_id
-                converted_from_delivery_order_items_id converted_from_invoice_id);
+                converted_from_delivery_order_items_id converted_from_invoice_id
+                converted_from_reclamation_items_id);
 
   my $ic_cvar_configs = CVar->get_configs(module => 'IC');
   push @flds, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs };
diff --git a/bin/mozilla/is.pl b/bin/mozilla/is.pl
index 398ed4f87..f68c0162d 100644
--- a/bin/mozilla/is.pl
+++ b/bin/mozilla/is.pl
@@ -645,7 +645,7 @@ sub form_header {
     title creditlimit creditremaining tradediscount business closedto locked shipped storno storno_id
     max_dunning_level dunning_amount dunning_description
     taxaccounts cursor_fokus
-    convert_from_do_ids convert_from_oe_ids convert_from_ar_ids useasnew
+    convert_from_reclamations_ids convert_from_do_ids convert_from_oe_ids convert_from_ar_ids useasnew
     invoice_id
     show_details
   ), @custom_hiddens,
@@ -1412,6 +1412,56 @@ sub credit_note {
   $main::lxdebug->leave_sub();
 }
 
+sub credit_note_from_reclamation {
+  $main::lxdebug->enter_sub();
+
+  $main::auth->assert('invoice_edit');
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
+
+
+  my $from_id = delete $form->{from_id};
+  my $reclamation = SL::DB::Reclamation->new(id => $from_id)->load;
+
+  $reclamation->flatten_to_form($form, format_amounts => 1);
+
+  # set new persistent ids for credit note and link previous reclamation id
+  $form->{convert_from_reclamations_ids} = $form->{id};
+  $form->{id}     = '';
+
+  $form->{"converted_from_reclamation_items_id_$_"} = delete $form->{"reclamation_items_id_$_"} for 1 .. $form->{"rowcount"};
+
+  $form->{transdate} = $form->{invdate} = $form->current_date(\%myconfig);
+  $form->{duedate} =
+    $form->current_date(\%myconfig, $form->{invdate}, $form->{terms} * 1);
+
+  $form->{title}  = $locale->text('Add Credit Note');
+  $form->{script} = 'is.pl';
+
+  # bo creates the id, reset it
+  map { delete $form->{$_} }
+    qw(id invnumber subject message cc bcc printed emailed queued);
+  $form->{ $form->{vc} } =~ s/--.*//g;
+
+  $form->{type} = "credit_note";
+
+  my $currency = $form->{currency};
+  &invoice_links;
+  $form->{currency}     = $currency;
+  $form->{forex}        = $form->check_exchangerate( \%myconfig, $form->{currency}, $form->{invdate}, 'buy');
+  $form->{exchangerate} = $form->{forex} || '';
+
+  $form->{creditremaining} -= ($form->{oldinvtotal} - $form->{ordtotal});
+
+  &prepare_invoice;
+
+  &display_form;
+
+  $main::lxdebug->leave_sub();
+}
+
 sub display_form {
   $::lxdebug->enter_sub;
 
