$form->{item} nach $form->{part_type} umbenannt
[kivitendo-erp.git] / bin / mozilla / ap.pl
index dddf6c5..52559ed 100644 (file)
@@ -32,7 +32,8 @@
 #======================================================================
 
 use POSIX qw(strftime);
-use List::Util qw(sum);
+use List::Util qw(max sum);
+use List::UtilsBy qw(sort_by);
 
 use SL::AP;
 use SL::FU;
@@ -41,10 +42,10 @@ use SL::IS;
 use SL::PE;
 use SL::ReportGenerator;
 use SL::DB::Default;
+use SL::DB::PurchaseInvoice;
 
 require "bin/mozilla/arap.pl";
 require "bin/mozilla/common.pl";
-require "bin/mozilla/drafts.pl";
 require "bin/mozilla/reportgenerator.pl";
 
 use strict;
@@ -87,17 +88,15 @@ sub add {
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
 
-  $main::auth->assert('general_ledger');
-
-  return $main::lxdebug->leave_sub() if (load_draft_maybe());
+  $main::auth->assert('ap_transactions');
 
   $form->{title} = "Add";
 
-  $form->{callback} = "ap.pl?action=add&DONT_LOAD_DRAFT=1" unless $form->{callback};
+  $form->{callback} = "ap.pl?action=add" unless $form->{callback};
 
   AP->get_transdate(\%myconfig, $form);
   $form->{initial_transdate} = $form->{transdate};
-  &create_links;
+  create_links(dont_save => 1);
   $form->{transdate} = $form->{initial_transdate};
   &display_form;
 
@@ -109,11 +108,11 @@ sub edit {
 
   my $form     = $main::form;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
 
   $form->{title} = "Edit";
 
-  &create_links;
+  create_links();
   &display_form;
 
   $main::lxdebug->leave_sub();
@@ -124,7 +123,7 @@ sub display_form {
 
   my $form     = $main::form;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
 
   &form_header;
   &form_footer;
@@ -135,18 +134,25 @@ sub display_form {
 sub create_links {
   $main::lxdebug->enter_sub();
 
+  my %params   = @_;
+
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
 
   $form->create_links("AP", \%myconfig, "vendor");
-  my $taxincluded = $form->{taxincluded};
-  my $duedate     = $form->{duedate};
+  my %saved;
+  if (!$params{dont_save}) {
+    %saved = map { ($_ => $form->{$_}) } qw(direct_debit taxincluded);
+    $saved{duedate} = $form->{duedate} if $form->{duedate};
+    $saved{currency} = $form->{currency} if $form->{currency};
+    $saved{taxincluded} = $form->{taxincluded} if $form->{taxincluded};
+  }
 
   IR->get_vendor(\%myconfig, \%$form);
-  $form->{taxincluded} = $taxincluded;
-  $form->{duedate}   = $duedate if $duedate;
+
+  $form->{$_}        = $saved{$_} for keys %saved;
   $form->{oldvendor} = "$form->{vendor}--$form->{vendor_id}";
   $form->{rowcount}  = 1;
 
@@ -156,6 +162,7 @@ sub create_links {
   # currencies
   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
 
+  $form->{selectcurrency} = "";
   map { my $quoted = H($_); $form->{selectcurrency} .= "<option value=\"${quoted}\">${quoted}\n" } $form->get_all_currencies(\%myconfig);
 
   # vendors
@@ -182,6 +189,25 @@ sub create_links {
   $main::lxdebug->leave_sub();
 }
 
+sub _sort_payments {
+  my @fields   = qw(acc_trans_id gldate datepaid source memo paid AP_paid paid_project_id);
+  my @payments =
+    grep { $_->{paid} != 0 }
+    map  {
+      my $idx = $_;
+      +{ map { ($_ => delete($::form->{"${_}_${idx}"})) } @fields }
+    } (1..$::form->{paidaccounts});
+
+  @payments = sort_by { DateTime->from_kivitendo($_->{datepaid}) } @payments;
+
+  $::form->{paidaccounts} = max scalar(@payments), 1;
+
+  foreach my $idx (1 .. scalar(@payments)) {
+    my $payment = $payments[$idx - 1];
+    $::form->{"${_}_${idx}"} = $payment->{$_} for @fields;
+  }
+}
+
 sub form_header {
   $main::lxdebug->enter_sub();
 
@@ -190,10 +216,12 @@ sub form_header {
   my $locale   = $main::locale;
   my $cgi      = $::request->{cgi};
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
+
+  $::form->{invoice_obj} = SL::DB::PurchaseInvoice->new(id => $::form->{id})->load if $::form->{id};
 
   $form->{title_} = $form->{title};
-  $form->{title} = $locale->text($form->{title} .' Accounts Payables Transaction');
+  $form->{title} = $form->{title} eq 'Add' ? $locale->text('Add Accounts Payables Transaction') : $locale->text('Edit Accounts Payables Transaction');
 
   # type=submit $locale->text('Add Accounts Payables Transaction')
   # type=submit $locale->text('Edit Accounts Payables Transaction')
@@ -291,8 +319,6 @@ sub form_header {
     $taxcharts{$item->{id}} = $item;
   }
 
-  $form->{jsscript} = 1;
-
   my $follow_up_vc         =  $form->{vendor};
   $follow_up_vc            =~ s/--.*?//;
   my $follow_up_trans_info =  "$form->{invnumber} ($follow_up_vc)";
@@ -300,6 +326,7 @@ sub form_header {
   $form->{javascript} .= qq|<script type="text/javascript" src="js/common.js"></script>|;
   $form->{javascript} .= qq|<script type="text/javascript" src="js/show_vc_details.js"></script>|;
   $form->{javascript} .= qq|<script type="text/javascript" src="js/follow_up.js"></script>|;
+  $form->{javascript} .= qq|<script type="text/javascript" src="js/kivi.Draft.js"></script>|;
 
   $form->header();
 
@@ -369,9 +396,15 @@ sub form_header {
 
   $form->{totalpaid} = 0;
 
+  _sort_payments();
+
   if ( $form->{'paid_'. $form->{paidaccounts}} ) {
     $form->{paidaccounts}++;
   }
+
+  # default account for current assets (i.e. 1801 - SKR04)
+  $form->{accno_arap} = IS->get_standard_accno_current_assets(\%myconfig, \%$form);
+
   for my $i (1 .. $form->{paidaccounts}) {
     $form->{totalpaid} += $form->{"paid_$i"};
 
@@ -396,6 +429,11 @@ sub form_header {
       $changeable = (($form->{"gldate_$i"} eq '') || $form->current_date(\%myconfig) eq $form->{"gldate_$i"});
     }
 
+    #deaktivieren von gebuchten Zahlungen ausserhalb der Bücherkontrolle, vorher prüfen ob heute eingegeben
+    if ($form->date_closed($form->{"gldate_$i"})) {
+       $changeable = 0;
+    }
+
     $form->{'paidaccount_changeable_'. $i} = $changeable;
 
     $form->{'labelpaid_project_id_'. $i} = $project_labels{$form->{'paid_project_id_'. $i}};
@@ -403,19 +441,21 @@ sub form_header {
 
   $form->{paid_missing} = $form->{invtotal_unformatted} - $form->{totalpaid};
 
-  print $form->parse_html_template('ap/form_header');
+  print $form->parse_html_template('ap/form_header', {
+    today => DateTime->today,
+  });
 
   $main::lxdebug->leave_sub();
 }
 
 sub form_footer {
   $::lxdebug->enter_sub;
-  $::auth->assert('general_ledger');
+  $::auth->assert('ap_transactions');
 
   my $num_due;
   my $num_follow_ups;
   if ($::form->{id}) {
-    my $follow_ups = FU->follow_ups('trans_id' => $::form->{id});
+    my $follow_ups = FU->follow_ups('trans_id' => $::form->{id}, 'not_done' => 1);
 
     if (@{ $follow_ups }) {
       $num_due        = sum map { $_->{due} * 1 } @{ $follow_ups };
@@ -448,7 +488,7 @@ sub mark_as_paid {
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
 
   &mark_as_paid_common(\%myconfig,"ap");
 
@@ -461,7 +501,7 @@ sub update {
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
 
   my $display = shift;
 
@@ -476,23 +516,15 @@ sub update {
   my $count = 0;
   my (@a, $j, $totaltax);
   for my $i (1 .. $form->{rowcount}) {
-    $form->{"amount_$i"} =
-      $form->parse_amount(\%myconfig, $form->{"amount_$i"});
-    $form->{"tax_$i"} = $form->parse_amount(\%myconfig, $form->{"tax_$i"});
+    $form->{"amount_$i"} = $form->parse_amount(\%myconfig, $form->{"amount_$i"});
     if ($form->{"amount_$i"}) {
       push @a, {};
       $j = $#a;
       my ($taxkey, $rate) = split(/--/, $form->{"taxchart_$i"});
-      if ($taxkey > 1) {
-        if ($form->{taxincluded}) {
-          $form->{"tax_$i"} = $form->{"amount_$i"} / ($rate + 1) * $rate;
-        } else {
-          $form->{"tax_$i"} = $form->{"amount_$i"} * $rate;
-        }
-      } else {
-        $form->{"tax_$i"} = 0;
-      }
-      $form->{"tax_$i"} = $form->round_amount($form->{"tax_$i"}, 2);
+
+      # calculate tax exactly the same way as AP in post_transaction via form->calculate_tax
+      my $tmpnetamount;
+      ($tmpnetamount,$form->{"tax_$i"}) = $form->calculate_tax($form->{"amount_$i"},$rate,$form->{taxincluded},2);
 
       $totaltax += $form->{"tax_$i"};
       map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
@@ -557,7 +589,8 @@ sub post_payment {
   my %myconfig = %main::myconfig;
   my $locale   = $main::locale;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
+  $form->mtime_ischanged('ap');
 
   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
 
@@ -569,8 +602,13 @@ sub post_payment {
 
       $form->isblank("datepaid_$i", $locale->text('Payment date missing!'));
 
+      $form->error($locale->text('Cannot post transaction above the maximum future booking date!'))
+        if ($form->date_max_future($form->{"datepaid_$i"}, \%myconfig));
+
+      #Zusätzlich noch das Buchungsdatum in die Bücherkontrolle einbeziehen
+      # (Dient zur Prüfung ob ZE oder ZA geprüft werden soll)
       $form->error($locale->text('Cannot post payment for a closed period!'))
-        if ($form->date_closed($form->{"datepaid_$i"}, \%myconfig));
+        if ($form->date_closed($form->{"datepaid_$i"})  && !$form->date_closed($form->{"gldate_$i"}, \%myconfig));
 
       if ($form->{defaultcurrency} && ($form->{currency} ne $form->{defaultcurrency})) {
         $form->{"exchangerate_$i"} = $form->{exchangerate}
@@ -583,9 +621,15 @@ sub post_payment {
 
   ($form->{AP})      = split /--/, $form->{AP};
   ($form->{AP_paid}) = split /--/, $form->{AP_paid};
-  $form->redirect($locale->text('Payment posted!'))
-      if (AP->post_payment(\%myconfig, \%$form));
+  if (AP->post_payment(\%myconfig, \%$form)) {
+    $form->{snumbers}  = qq|invnumber_| . $form->{invnumber};
+    $form->{what_done} = 'invoice';
+    $form->{addition}  = "PAYMENT POSTED";
+    $form->save_history;
+    $form->redirect($locale->text('Payment posted!'))
+  } else {
     $form->error($locale->text('Cannot post payment!'));
+  };
 
 
   $main::lxdebug->leave_sub();
@@ -599,14 +643,16 @@ sub post {
   my %myconfig = %main::myconfig;
   my $locale   = $main::locale;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
+  $form->mtime_ischanged('ap');
 
   my ($inline) = @_;
 
-  # check if there is a vendor, invoice and due date
+  # check if there is a vendor, invoice, due date and invnumber
   $form->isblank("transdate", $locale->text("Invoice Date missing!"));
   $form->isblank("duedate",   $locale->text("Due Date missing!"));
   $form->isblank("vendor",    $locale->text('Vendor missing!'));
+  $form->isblank("invnumber", $locale->text('Invoice Number missing!'));
 
   if ($myconfig{mandatory_departments} && !$form->{department}) {
     $form->{saved_message} = $::locale->text('You have to specify a department.');
@@ -616,6 +662,9 @@ sub post {
 
   my $closedto  = $form->datetonum($form->{closedto},  \%myconfig);
   my $transdate = $form->datetonum($form->{transdate}, \%myconfig);
+
+  $form->error($locale->text('Cannot post transaction above the maximum future booking date!'))
+    if ($form->date_max_future($form->{"transdate"}, \%myconfig));
   $form->error($locale->text('Cannot post transaction for a closed period!')) if ($form->date_closed($form->{"transdate"}, \%myconfig));
 
   my $zero_amount_posting = 1;
@@ -638,8 +687,13 @@ sub post {
 
       $form->isblank("datepaid_$i", $locale->text('Payment date missing!'));
 
+      $form->error($locale->text('Cannot post transaction above the maximum future booking date!'))
+      if ($form->date_max_future($form->{"datepaid_$i"}, \%myconfig));
+
+      #Zusätzlich noch das Buchungsdatum in die Bücherkontrolle einbeziehen
+      # (Dient zur Prüfung ob ZE oder ZA geprüft werden soll)
       $form->error($locale->text('Cannot post payment for a closed period!'))
-        if ($form->date_closed($form->{"datepaid_$i"}, \%myconfig));
+        if ($form->date_closed($form->{"datepaid_$i"})  && !$form->date_closed($form->{"gldate_$i"}, \%myconfig));
 
       if ($form->{defaultcurrency} && ($form->{currency} ne $form->{defaultcurrency})) {
         $form->{"exchangerate_$i"} = $form->{exchangerate}
@@ -655,7 +709,7 @@ sub post {
   my ($vendor) = split /--/, $form->{vendor};
   if ($form->{oldvendor} ne "$vendor--$form->{vendor_id}") {
     &update;
-    ::end_of_request();
+    $::dispatcher->end_request;
   }
   my ($debitaccno,    $debittaxkey)    = split /--/, $form->{AP_amountselected};
   my ($taxkey,        $NULL)           = split /--/, $form->{taxchartselected};
@@ -670,12 +724,12 @@ sub post {
   if (AP->post_transaction(\%myconfig, \%$form)) {
     # saving the history
     if(!exists $form->{addition} && $form->{id} ne "") {
-      $form->{snumbers} = qq|invnumber_| . $form->{invnumber};
-      $form->{addition} = "POSTED";
+      $form->{snumbers}  = qq|invnumber_| . $form->{invnumber};
+      $form->{addition}  = "POSTED";
+      $form->{what_done} = "invoice";
       $form->save_history;
     }
     # /saving the history
-    remove_draft() if $form->{remove_draft};
     # Dieser Text wird niemals ausgegeben: Probleme beim redirect?
     $form->redirect($locale->text('Transaction posted!')) unless $inline;
   } else {
@@ -691,13 +745,17 @@ sub post_as_new {
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
 
   $form->{postasnew} = 1;
   # saving the history
   if(!exists $form->{addition} && $form->{id} ne "") {
-    $form->{snumbers} = qq|invnumber_| . $form->{invnumber};
-    $form->{addition} = "POSTED AS NEW";
+    # does this work? post_as_new for ap doesn't immediately save the
+    # invoice, because the invnumber has to be entered by hand.
+    # And the value of $form->{postasnew} isn't checked when calling post
+    $form->{snumbers}  = qq|invnumber_| . $form->{invnumber};
+    $form->{addition}  = "POSTED AS NEW";
+    $form->{what_done} = "invoice";
     $form->save_history;
   }
   # /saving the history
@@ -712,7 +770,7 @@ sub use_as_new {
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
 
   map { delete $form->{$_} } qw(printed emailed queued invnumber invdate deliverydate id datepaid_1 gldate_1 acc_trans_id_1 source_1 memo_1 paid_1 exchangerate_1 AP_paid_1 storno);
   $form->{paidaccounts} = 1;
@@ -729,7 +787,7 @@ sub delete {
   my $form     = $main::form;
   my $locale   = $main::locale;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
 
   $form->{title} = $locale->text('Confirm!');
 
@@ -769,13 +827,14 @@ sub yes {
   my %myconfig = %main::myconfig;
   my $locale   = $main::locale;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
 
   if (AP->delete_transaction(\%myconfig, \%$form)) {
     # saving the history
     if(!exists $form->{addition}) {
-      $form->{snumbers} = qq|invnumber_| . $form->{invnumber};
-      $form->{addition} = "DELETED";
+      $form->{snumbers}  = qq|invnumber_| . $form->{invnumber};
+      $form->{addition}  = "DELETED";
+      $form->{what_done} = "invoice";
       $form->save_history;
     }
     # /saving the history
@@ -789,7 +848,7 @@ sub yes {
 sub search {
   $main::lxdebug->enter_sub();
 
-  $main::auth->assert('general_ledger | vendor_invoice_edit');
+  $main::auth->assert('vendor_invoice_edit');
 
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
@@ -799,15 +858,12 @@ sub search {
   $form->all_vc(\%myconfig, "vendor", "AP");
 
   $form->{title}    = $locale->text('AP Transactions');
-  $::request->{layout}->focus('#vendor');
-  $form->{jsscript} = 1;
 
   $form->get_lists("projects"     => { "key" => "ALL_PROJECTS", "all" => 1 },
                    "departments"  => "ALL_DEPARTMENTS",
                    "vendors"      => "ALL_VC");
 
   # constants and subs for template
-  $form->{jsscript}  = 1;
   $form->{vc_keys}   = sub { "$_[0]->{name}--$_[0]->{id}" };
 
   $form->header;
@@ -844,7 +900,7 @@ sub ap_transactions {
   my %myconfig = %main::myconfig;
   my $locale   = $main::locale;
 
-  $main::auth->assert('general_ledger | vendor_invoice_edit');
+  $main::auth->assert('vendor_invoice_edit');
 
   ($form->{vendor}, $form->{vendor_id}) = split(/--/, $form->{vendor});
 
@@ -859,10 +915,11 @@ sub ap_transactions {
   my @columns =
     qw(transdate id type invnumber ordnumber name netamount tax amount paid datepaid
        due duedate transaction_description notes employee globalprojectnumber
-       vendornumber country ustid taxzone payment_terms charts);
+       vendornumber country ustid taxzone payment_terms charts direct_debit);
 
   my @hidden_variables = map { "l_${_}" } @columns;
-  push @hidden_variables, "l_subtotal", qw(open closed vendor invnumber ordnumber transaction_description notes project_id transdatefrom transdateto department);
+  push @hidden_variables, "l_subtotal", qw(open closed vendor invnumber ordnumber transaction_description notes project_id transdatefrom transdateto department
+                                           parts_partnumber parts_description);
 
   my $href = build_std_url('action=ap_transactions', grep { $form->{$_} } @hidden_variables);
 
@@ -887,12 +944,13 @@ sub ap_transactions {
     'vendornumber'            => { 'text' => $locale->text('Vendor Number'), },
     'country'                 => { 'text' => $locale->text('Country'), },
     'ustid'                   => { 'text' => $locale->text('USt-IdNr.'), },
-    'taxzone'                 => { 'text' => $locale->text('Steuersatz'), },
+    'taxzone'                 => { 'text' => $locale->text('Tax rate'), },
     'payment_terms'           => { 'text' => $locale->text('Payment Terms'), },
     'charts'                  => { 'text' => $locale->text('Buchungskonto'), },
+    'direct_debit'            => { 'text' => $locale->text('direct debit'), },
   );
 
-  foreach my $name (qw(id transdate duedate invnumber ordnumber name datepaid employee shippingpoint shipvia transaction_description)) {
+  foreach my $name (qw(id transdate duedate invnumber ordnumber name datepaid employee shippingpoint shipvia transaction_description direct_debit)) {
     my $sortdir                 = $form->{sort} eq $name ? 1 - $form->{sortdir} : $form->{sortdir};
     $column_defs{$name}->{link} = $href . "&sort=$name&sortdir=$sortdir";
   }
@@ -911,11 +969,14 @@ sub ap_transactions {
 
   my @options;
   push @options, $locale->text('Vendor')                  . " : $form->{vendor}"                         if ($form->{vendor});
+  push @options, $locale->text('Contact Person')          . " : $form->{cp_name}"                        if ($form->{cp_name});
   push @options, $locale->text('Department')              . " : " . (split /--/, $form->{department})[0] if ($form->{department});
   push @options, $locale->text('Invoice Number')          . " : $form->{invnumber}"                      if ($form->{invnumber});
   push @options, $locale->text('Order Number')            . " : $form->{ordnumber}"                      if ($form->{ordnumber});
   push @options, $locale->text('Notes')                   . " : $form->{notes}"                          if ($form->{notes});
   push @options, $locale->text('Transaction description') . " : $form->{transaction_description}"        if ($form->{transaction_description});
+  push @options, $locale->text('Part Description')        . " : $form->{parts_description}"              if $form->{parts_description};
+  push @options, $locale->text('Part Number')             . " : $form->{parts_partnumber}"               if $form->{parts_partnumber};
   push @options, $locale->text('From') . " " . $locale->date(\%myconfig, $form->{transdatefrom}, 1)      if ($form->{transdatefrom});
   push @options, $locale->text('Bis')  . " " . $locale->date(\%myconfig, $form->{transdateto},   1)      if ($form->{transdateto});
   push @options, $locale->text('Open')                                                                   if ($form->{open});
@@ -967,6 +1028,8 @@ sub ap_transactions {
         :                     $locale->text("AP Transaction (abbreviation)");
     }
 
+    $ap->{direct_debit} = $ap->{direct_debit} ? $::locale->text('yes') : $::locale->text('no');
+
     my $row = { };
 
     foreach my $column (@columns) {
@@ -1007,7 +1070,7 @@ sub storno {
   my %myconfig = %main::myconfig;
   my $locale   = $main::locale;
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('ap_transactions');
 
   if (IS->has_storno(\%myconfig, $form, 'ap')) {
     $form->{title} = $locale->text("Cancel Accounts Payables Transaction");
@@ -1021,8 +1084,9 @@ sub storno {
 
   # saving the history
   if(!exists $form->{addition} && $form->{id} ne "") {
-    $form->{snumbers} = "ordnumber_$form->{ordnumber}";
-    $form->{addition} = "STORNO";
+    $form->{snumbers}  = qq|invnumber_| . $form->{invnumber};
+    $form->{addition}  = "STORNO";
+    $form->{what_done} = "invoice";
     $form->save_history;
   }
   # /saving the history