From 72e545d62bd1eb0d65e9afc0c05b97306864a15a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bernd=20Ble=C3=9Fmann?= Date: Mon, 20 Dec 2021 15:40:51 +0100 Subject: [PATCH] Anzahlungs-Rg.: Workflow vom Auftrag: alle Anzahlugns-Rg. und Schluss-Rg. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Wird der Workflow vom Auftrag aus begonnen, so werden alle Anzahlungs- und die Schlussrechnung vom Auftrag aus gemacht. Der Einstieg über eine Anzahlungs-Rg. und dann der Workflow "weitere Anzahlungs-Rg." (...) und hieraus Schluss-Rg. bleibt bestehen. --- SL/Controller/Order.pm | 36 +++++++++++++++++++++++++++----- SL/IS.pm | 47 +++++++++++++++++++++++++++++++++++------- bin/mozilla/is.pl | 14 ++++++++----- bin/mozilla/oe.pl | 6 +++--- 4 files changed, 83 insertions(+), 20 deletions(-) diff --git a/SL/Controller/Order.pm b/SL/Controller/Order.pm index 7d421ef01..b4328a1e2 100644 --- a/SL/Controller/Order.pm +++ b/SL/Controller/Order.pm @@ -57,11 +57,11 @@ use Rose::Object::MakeMethods::Generic __PACKAGE__->run_before('check_auth'); __PACKAGE__->run_before('recalc', - only => [ qw(save save_as_new save_and_delivery_order save_and_invoice save_and_invoice_for_advance_payment save_and_ap_transaction + only => [ qw(save save_as_new save_and_delivery_order save_and_invoice save_and_invoice_for_advance_payment save_and_final_invoice save_and_ap_transaction print send_email) ]); __PACKAGE__->run_before('get_unalterable_data', - only => [ qw(save save_as_new save_and_delivery_order save_and_invoice save_and_invoice_for_advance_payment save_and_ap_transaction + only => [ qw(save save_as_new save_and_delivery_order save_and_invoice save_and_invoice_for_advance_payment save_and_final_invoice save_and_ap_transaction print send_email) ]); # @@ -698,6 +698,16 @@ sub action_save_and_invoice_for_advance_payment { ); } +sub action_save_and_final_invoice { + my ($self) = @_; + + $self->save_and_redirect_to( + controller => 'oe.pl', + action => 'oe_invoice_from_order', + new_invoice_type => 'final_invoice', + ); +} + # workflow from sales order to sales quotation sub action_sales_quotation { $_[0]->workflow_sales_or_request_for_quotation(); @@ -1990,6 +2000,12 @@ sub setup_edit_action_bar { $has_invoice_for_advance_payment = any {'SL::DB::Invoice' eq ref $_ && "invoice_for_advance_payment" eq $_->type} @$lr; } + my $has_final_invoice; + if ($self->order->id && $self->type eq sales_order_type()) { + my $lr = $self->order->linked_records(direction => 'to', to => ['Invoice']); + $has_final_invoice = any {'SL::DB::Invoice' eq ref $_ && "final_invoice" eq $_->type} @$lr; + } + for my $bar ($::request->layout->get('actionbar')) { $bar->add( combobox => [ @@ -2057,15 +2073,25 @@ sub setup_edit_action_bar { ], ], action => [ - t8('Save and Invoice for Advance Payment'), + ($has_invoice_for_advance_payment ? t8('Save and Further Invoice for Advance Payment') : t8('Save and Invoice for Advance Payment')), call => [ 'kivi.Order.save', 'save_and_invoice_for_advance_payment', $::instance_conf->get_order_warn_duplicate_parts ], checks => [ 'kivi.Order.check_save_active_periodic_invoices', @req_trans_cost_art, @req_cusordnumber, ], - disabled => $has_invoice_for_advance_payment ? t8('This order has already an invoice for advanced payment.') - : undef, + disabled => $has_final_invoice ? t8('This order has already a final invoice.') + : undef, only_if => (any { $self->type eq $_ } (sales_order_type())), ], + action => [ + t8('Save and Final Invoice'), + call => [ 'kivi.Order.save', 'save_and_final_invoice', $::instance_conf->get_order_warn_duplicate_parts ], + checks => [ 'kivi.Order.check_save_active_periodic_invoices', + @req_trans_cost_art, @req_cusordnumber, + ], + disabled => $has_final_invoice ? t8('This order has already a final invoice.') + : undef, + only_if => (any { $self->type eq $_ } (sales_order_type())) && $has_invoice_for_advance_payment, + ], action => [ t8('Save and AP Transaction'), call => [ 'kivi.Order.save', 'save_and_ap_transaction', $::instance_conf->get_order_warn_duplicate_parts ], diff --git a/SL/IS.pm b/SL/IS.pm index 8b79376d2..ba4c2a183 100644 --- a/SL/IS.pm +++ b/SL/IS.pm @@ -578,7 +578,9 @@ sub invoice_details { $form->{username} = $myconfig->{name}; $form->{$_} = $form->format_amount($myconfig, $form->{$_}, 2) for @separate_totals; - foreach my $invoice_for_advance_payment (@{$self->_get_invoices_for_advance_payment($form->{convert_from_ar_ids} || $form->{id})}) { + my $id_for_iap = $form->{convert_from_oe_ids} || $form->{convert_from_ar_ids} || $form->{id}; + my $from_order = !!$form->{convert_from_oe_ids}; + foreach my $invoice_for_advance_payment (@{$self->_get_invoices_for_advance_payment($id_for_iap, $from_order)}) { # Collect VAT of invoices for advance payment. # Set sellprices to fxsellprices for items, because # the PriceTaxCalculator sets fxsellprice from sellprice before calculating. @@ -1090,7 +1092,9 @@ SQL my $iap_amounts; if ($form->{type} eq 'final_invoice') { - my $invoices_for_advance_payment = $self->_get_invoices_for_advance_payment($form->{convert_from_ar_ids} || $form->{id}); + my $id_for_iap = $form->{convert_from_oe_ids} || $form->{convert_from_ar_ids} || $form->{id}; + my $from_order = !!$form->{convert_from_oe_ids}; + my $invoices_for_advance_payment = $self->_get_invoices_for_advance_payment($id_for_iap, $from_order); if (scalar @$invoices_for_advance_payment > 0) { # reverse booking for invoices for advance payment foreach my $invoice_for_advance_payment (@$invoices_for_advance_payment) { @@ -1587,15 +1591,44 @@ SQL } sub _get_invoices_for_advance_payment { - my ($self, $id) = @_; + my ($self, $id, $id_is_from_order) = @_; return [] if !$id; - my $invoice_obj = SL::DB::Invoice->new(id => $id*1)->load; - my $links = $invoice_obj->linked_records(direction => 'from', from => ['Invoice'], recursive => 1); + # Search all related invoices for advance payment. + # Case 1: + # (order) -> invoice for adv. payment 1 -> invoice for adv. payment 2 -> invoice for adv. payment 3 -> final invoice + # + # Case 2: + # order -> invoice for adv. payment 1 + # | |`-> invoice for adv. payment 2 + # | `--> invoice for adv. payment 3 + # `----> final invoice + # + # The id is currently that from the last invoice for adv. payment (3 in this example), + # that from the final invoice or that from the order. + + my $invoice_obj; + my $order_obj; + my $links; + + if (!$id_is_from_order) { + $invoice_obj = SL::DB::Invoice->load_cached($id*1); + $links = $invoice_obj->linked_records(direction => 'from', from => ['Order']); + $order_obj = $links->[0]; + } else { + $order_obj = SL::DB::Order->load_cached($id*1); + } + + if ($order_obj) { + $links = $order_obj ->linked_records(direction => 'to', to => ['Invoice']); + } else { + $links = $invoice_obj->linked_records(direction => 'from', from => ['Invoice'], recursive => 1); + } + my @related_invoices = grep {'SL::DB::Invoice' eq ref $_ && "invoice_for_advance_payment" eq $_->type} @$links; - push @related_invoices, $invoice_obj if "invoice_for_advance_payment" eq $invoice_obj->type; + push @related_invoices, $invoice_obj if !$order_obj && "invoice_for_advance_payment" eq $invoice_obj->type; return \@related_invoices; } @@ -2109,7 +2142,7 @@ sub _delete_invoice { # if we delete a final invoice, the reverse bookings for the clearing account in the invoice for advance payment # must be deleted as well - my $invoices_for_advance_payment = $self->_get_invoices_for_advance_payment($form->{convert_from_ar_ids} || $form->{id}); + my $invoices_for_advance_payment = $self->_get_invoices_for_advance_payment($form->{id}); # Todo: allow only if invoice for advance payment is not paid. # die if any { $_->paid } for @$invoices_for_advance_payment; diff --git a/bin/mozilla/is.pl b/bin/mozilla/is.pl index b4e1a7bcd..93d5dbe6c 100644 --- a/bin/mozilla/is.pl +++ b/bin/mozilla/is.pl @@ -336,6 +336,13 @@ sub setup_is_action_bar { $has_final_invoice = any {'SL::DB::Invoice' eq ref $_ && "final_invoice" eq $_->invoice_type} @$lr; } + my $is_invoice_for_advance_payment_from_order; + if ($form->{id} && $form->{type} eq "invoice_for_advance_payment") { + my $invoice_obj = SL::DB::Invoice->load_cached($form->{id}); + my $lr = $invoice_obj->linked_records(direction => 'from', from => ['Order']); + $is_invoice_for_advance_payment_from_order = scalar @$lr >= 1; + } + for my $bar ($::request->layout->get('actionbar')) { $bar->add( action => [ @@ -428,6 +435,7 @@ sub setup_is_action_bar { : !$form->{id} ? t8('This invoice has not been posted yet.') : $has_further_invoice_for_advance_payment ? t8('This invoice has already a further invoice for advanced payment.') : $has_final_invoice ? t8('This invoice has already a final invoice.') + : $is_invoice_for_advance_payment_from_order ? t8('This invoice was added from an order. See there.') : undef, only_if => $form->{type} eq "invoice_for_advance_payment", ], @@ -439,6 +447,7 @@ sub setup_is_action_bar { : !$form->{id} ? t8('This invoice has not been posted yet.') : $has_further_invoice_for_advance_payment ? t8('This invoice has a further invoice for advanced payment.') : $has_final_invoice ? t8('This invoice has already a final invoice.') + : $is_invoice_for_advance_payment_from_order ? t8('This invoice was added from an order. See there.') : undef, only_if => $form->{type} eq "invoice_for_advance_payment", ], @@ -1213,11 +1222,6 @@ sub final_invoice { $main::auth->assert('invoice_edit'); - # search all related invoices for advance payment - # - # (order) -> invoice for adv. payment 1 -> invoice for adv. payment 2 -> invoice for adv. payment 3 -> final invoice - # - # we are currently in the last invoice for adv. payment (3 in this example) my $related_invoices = IS->_get_invoices_for_advance_payment($form->{id}); delete @{ $form }{qw(printed emailed queued invnumber invdate exchangerate forex deliverydate datepaid_1 gldate_1 acc_trans_id_1 source_1 memo_1 paid_1 exchangerate_1 AP_paid_1 storno locked)}; diff --git a/bin/mozilla/oe.pl b/bin/mozilla/oe.pl index b9edf4c96..96764ebdf 100644 --- a/bin/mozilla/oe.pl +++ b/bin/mozilla/oe.pl @@ -1654,7 +1654,7 @@ sub invoice { $::dispatcher->end_request; } - _oe_remove_delivered_or_billed_rows(id => $form->{id}, type => 'billed'); + _oe_remove_delivered_or_billed_rows(id => $form->{id}, type => 'billed') if $form->{new_invoice_type} ne 'final_invoice'; $form->{cp_id} *= 1; @@ -1699,8 +1699,8 @@ sub invoice { if ( $form->{type} eq 'sales_order' || $form->{type} eq 'sales_quotation') { - $form->{title} = ($form->{new_invoice_type} eq 'invoice_for_advance_payment') - ? $locale->text('Add Invoice for Advance Payment') + $form->{title} = ($form->{new_invoice_type} eq 'invoice_for_advance_payment') ? $locale->text('Add Invoice for Advance Payment') + : ($form->{new_invoice_type} eq 'final_invoice') ? $locale->text('Add Final Invoice') : $locale->text('Add Sales Invoice'); $form->{script} = 'is.pl'; $script = "is"; -- 2.20.1