X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=bin%2Fmozilla%2Fis.pl;h=837bde7f996d599ce2a4989ce733ba0fb47b21d0;hb=59f6b67c2936ef72e9c5ee3629fe49876bd9f484;hp=76d4b3edbca01d284e4667aeba1f39422915d964;hpb=844a541e0d8f59644540413f675e8f07cd154cf6;p=kivitendo-erp.git diff --git a/bin/mozilla/is.pl b/bin/mozilla/is.pl index 76d4b3edb..837bde7f9 100644 --- a/bin/mozilla/is.pl +++ b/bin/mozilla/is.pl @@ -36,9 +36,11 @@ use SL::FU; use SL::IS; use SL::OE; use SL::MoreCommon qw(restore_form save_form); +use SL::RecordLinks; + use Data::Dumper; use DateTime; -use List::MoreUtils qw(uniq); +use List::MoreUtils qw(any uniq); use List::Util qw(max sum); use List::UtilsBy qw(sort_by); use English qw(-no_match_vars); @@ -89,6 +91,10 @@ sub add { if ($form->{storno}) { $form->{title} = $locale->text('Add Storno Credit Note'); } + + } elsif ($form->{type} eq "invoice_for_advance_payment") { + $form->{title} = $locale->text('Add Invoice for Advance Payment'); + } else { $form->{title} = $locale->text('Add Sales Invoice'); @@ -132,6 +138,11 @@ sub edit { if ($form->{type} eq "credit_note") { $form->{title} = $locale->text('Edit Credit Note'); $form->{title} = $locale->text('Edit Storno Credit Note') if $form->{storno}; + + } elsif ($form->{type} eq "invoice_for_advance_payment") { + $form->{title} = $locale->text('Edit Invoice for Advance Payment'); + $form->{title} = $locale->text('Edit Storno Invoice for Advance Payment') if $form->{storno}; + } else { $form->{title} = $locale->text('Edit Sales Invoice'); $form->{title} = $locale->text('Edit Storno Invoice') if $form->{storno}; @@ -237,8 +248,14 @@ sub prepare_invoice { if ($form->{type} eq "credit_note") { $form->{type} = "credit_note"; $form->{formname} = "credit_note"; + + } elsif ($form->{type} eq "invoice_for_advance_payment") { + $form->{type} = "invoice_for_advance_payment"; + $form->{formname} = "invoice_for_advance_payment"; + } elsif ($form->{formname} eq "proforma" ) { $form->{type} = "invoice"; + } else { $form->{type} = "invoice"; $form->{formname} = "invoice"; @@ -276,12 +293,14 @@ sub prepare_invoice { } sub setup_is_action_bar { + my ($tmpl_var) = @_; my $form = $::form; my $change_never = $::instance_conf->get_is_changeable == 0; my $change_on_same_day_only = $::instance_conf->get_is_changeable == 2 && ($form->current_date(\%::myconfig) ne $form->{gldate}); my $payments_balanced = ($::form->{oldtotalpaid} == 0); my $has_storno = ($::form->{storno} && !$::form->{storno_id}); my $may_edit_create = $::auth->assert('invoice_edit', 1); + my $factur_x_enabled = $tmpl_var->{invoice_obj} && $tmpl_var->{invoice_obj}->customer->create_zugferd_invoices_for_this_customer; my ($is_linked_bank_transaction, $warn_unlinked_delivery_order); if ($::form->{id} && SL::DB::Default->get->payments_changeable != 0 @@ -292,6 +311,21 @@ sub setup_is_action_bar { if ($::instance_conf->get_warn_no_delivery_order_for_invoice && !$form->{id}) { $warn_unlinked_delivery_order = 1 unless $form->{convert_from_do_ids}; } + + my $has_further_invoice_for_advance_payment; + 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 => 'to', to => ['Invoice']); + $has_further_invoice_for_advance_payment = any {'SL::DB::Invoice' eq ref $_ && "invoice_for_advance_payment" eq $_->type} @$lr; + } + + my $has_final_invoice; + 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 => 'to', to => ['Invoice']); + $has_final_invoice = any {'SL::DB::Invoice' eq ref $_ && "invoice" eq $_->invoice_type} @$lr; + } + for my $bar ($::request->layout->get('actionbar')) { $bar->add( action => [ @@ -326,6 +360,7 @@ sub setup_is_action_bar { : !$form->{id} ? t8('This invoice has not been posted yet.') : $is_linked_bank_transaction ? t8('This transaction is linked with a bank transaction. Please undo and redo the bank transaction booking if needed.') : undef, + only_if => $form->{type} ne "invoice_for_advance_payment", ], action => [ t8('Mark as paid'), submit => [ '#form', { action => "mark_as_paid" } ], @@ -333,7 +368,7 @@ sub setup_is_action_bar { disabled => !$may_edit_create ? t8('You must not change this invoice.') : !$form->{id} ? t8('This invoice has not been posted yet.') : undef, - only_if => $::instance_conf->get_is_show_mark_as_paid, + only_if => $::instance_conf->get_is_show_mark_as_paid && $form->{type} ne "invoice_for_advance_payment", ], ], # end of combobox "Post" @@ -375,6 +410,28 @@ sub setup_is_action_bar { : !$form->{id} ? t8('This invoice has not been posted yet.') : undef, ], + action => [ + t8('Further Invoice for Advance Payment'), + submit => [ '#form', { action => "further_invoice_for_advance_payment" } ], + checks => [ 'kivi.validate_form' ], + disabled => !$may_edit_create ? t8('You must not change this invoice.') + : !$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.') + : undef, + only_if => $form->{type} eq "invoice_for_advance_payment", + ], + action => [ + t8('Final Invoice'), + submit => [ '#form', { action => "final_invoice" } ], + checks => [ 'kivi.validate_form' ], + disabled => !$may_edit_create ? t8('You must not change this invoice.') + : !$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.') + : undef, + only_if => $form->{type} eq "invoice_for_advance_payment", + ], action => [ t8('Credit Note'), submit => [ '#form', { action => "credit_note" } ], @@ -423,6 +480,14 @@ sub setup_is_action_bar { : $form->{postal_invoice} ? t8('This customer wants a postal invoices.') : undef, ], + action => [ t8('Factur-X/ZUGFeRD'), + submit => [ '#form', { action => "download_factur_x_xml" } ], + checks => [ 'kivi.validate_form' ], + disabled => !$may_edit_create ? t8('You must not print this invoice.') + : !$form->{id} ? t8('This invoice has not been posted yet.') + : !$factur_x_enabled ? t8('Creating Factur-X/ZUGFeRD invoices is not enabled for this customer.') + : undef, + ], ], # end of combobox "Export" combobox => [ @@ -540,6 +605,7 @@ sub form_header { $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/; } + $TMPL_VAR{is_type_invoice_for_advance_payment} = $form->{type} eq "invoice_for_advance_payment"; $TMPL_VAR{is_type_credit_note} = $form->{type} eq "credit_note"; $TMPL_VAR{is_format_html} = $form->{format} eq 'html'; $TMPL_VAR{dateformat} = $myconfig{dateformat}; @@ -562,7 +628,7 @@ sub form_header { $TMPL_VAR{payment_terms_obj} = get_payment_terms_for_invoice(); $form->{duedate} = $TMPL_VAR{payment_terms_obj}->calc_date(reference_date => $form->{invdate}, due_date => $form->{duedate})->to_kivitendo if $TMPL_VAR{payment_terms_obj}; - setup_is_action_bar(); + setup_is_action_bar(\%TMPL_VAR); $form->header(); @@ -683,6 +749,7 @@ sub form_footer { } print $form->parse_html_template('is/form_footer', { + is_type_invoice_for_advance_payment => ($form->{type} eq "invoice_for_advance_payment"), is_type_credit_note => ($form->{type} eq "credit_note"), totalpaid => $totalpaid, paid_missing => $form->{invtotal} - $totalpaid, @@ -957,6 +1024,12 @@ sub post { $form->isblank("exchangerate", $locale->text('Exchangerate missing!')) if ($form->{currency} ne $form->{defaultcurrency}); + # advance payment allows only one tax + if ($form->{type} eq 'invoice_for_advance_payment') { + my @current_taxaccounts = (split(/ /, $form->{taxaccounts})); + $form->error($locale->text('Cannot post invoice for advance payment with more than one tax')) + if (scalar @current_taxaccounts > 1); + } for my $i (1 .. $form->{paidaccounts}) { if ($form->parse_amount(\%myconfig, $form->{"paid_$i"})) { @@ -1101,6 +1174,85 @@ sub use_as_new { $main::lxdebug->leave_sub(); } +sub further_invoice_for_advance_payment { + my $form = $main::form; + my %myconfig = %main::myconfig; + + $main::auth->assert('invoice_edit'); + + 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)}; + $form->{convert_from_ar_ids} = $form->{id}; + $form->{id} = ''; + $form->{rowcount}--; + $form->{paidaccounts} = 1; + $form->{invdate} = $form->current_date(\%myconfig); + my $terms = get_payment_terms_for_invoice(); + $form->{duedate} = $terms ? $terms->calc_date(reference_date => $form->{invdate})->to_kivitendo : $form->{invdate}; + $form->{employee_id} = SL::DB::Manager::Employee->current->id; + $form->{forex} = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{invdate}, 'buy'); + $form->{exchangerate} = $form->{forex} if $form->{forex}; + + $form->{"converted_from_invoice_id_$_"} = delete $form->{"invoice_id_$_"} for 1 .. $form->{"rowcount"}; + + &display_form; +} + +sub final_invoice { + my $form = $main::form; + my %myconfig = %main::myconfig; + + $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)}; + + $form->{convert_from_ar_ids} = $form->{id}; + $form->{id} = ''; + $form->{type} = 'invoice'; + $form->{title} = t8('Edit Final Invoice'); + $form->{paidaccounts} = 1; + $form->{invdate} = $form->current_date(\%myconfig); + my $terms = get_payment_terms_for_invoice(); + $form->{duedate} = $terms ? $terms->calc_date(reference_date => $form->{invdate})->to_kivitendo : $form->{invdate}; + $form->{employee_id} = SL::DB::Manager::Employee->current->id; + $form->{forex} = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{invdate}, 'buy'); + $form->{exchangerate} = $form->{forex} if $form->{forex}; + + foreach my $i (1 .. $form->{"rowcount"}) { + delete $form->{"id_$i"}; + delete $form->{"invoice_id_$i"}; + delete $form->{"parts_id_$i"}; + delete $form->{"partnumber_$i"}; + delete $form->{"description_$i"}; + } + + remove_emptied_rows(1); + + my $i = 0; + foreach my $ri (@$related_invoices) { + foreach my $item (@{$ri->items_sorted}) { + $i++; + $form->{"id_$i"} = $item->parts_id; + $form->{"partnumber_$i"} = $item->part->partnumber; + $form->{"discount_$i"} = $item->discount*100.0; + $form->{"sellprice_$i"} = $item->fxsellprice; + $form->{$_ . "_" . $i} = $item->$_ for qw(description longdescription qty price_factor_id unit sellprice active_price_source active_discount_source); + + $form->{$_ . "_" . $i} = $form->format_amount(\%myconfig, $form->{$_ . "_" . $i}) for qw(qty sellprice discount); + } + } + $form->{rowcount} = $i; + + update(); + $::dispatcher->end_request; +} + sub storno { $main::lxdebug->enter_sub(); @@ -1230,7 +1382,6 @@ sub credit_note { &prepare_invoice; - &display_form; $main::lxdebug->leave_sub();