ActionBar: Setup in ir.pl in eigene Funktion ausgelagert
[kivitendo-erp.git] / bin / mozilla / ar.pl
index 9416ac7..ecd357e 100644 (file)
@@ -37,14 +37,21 @@ use List::Util qw(sum first max);
 use List::UtilsBy qw(sort_by);
 
 use SL::AR;
+use SL::Controller::Base;
 use SL::FU;
 use SL::GL;
 use SL::IS;
+use SL::DB::Business;
+use SL::DB::Chart;
+use SL::DB::Currency;
 use SL::DB::Default;
+use SL::DB::Employee;
 use SL::DB::Invoice;
+use SL::DB::RecordTemplate;
+use SL::DB::Tax;
+use SL::Helper::Flash qw(flash);
 use SL::ReportGenerator;
 
-require "bin/mozilla/arap.pl";
 require "bin/mozilla/common.pl";
 require "bin/mozilla/reportgenerator.pl";
 
@@ -79,6 +86,130 @@ use strict;
 # $locale->text('Nov')
 # $locale->text('Dec')
 
+sub load_record_template {
+  $::auth->assert('ar_transactions');
+
+  # Load existing template and verify that its one for this module.
+  my $template = SL::DB::RecordTemplate
+    ->new(id => $::form->{id})
+    ->load(
+      with_object => [ qw(customer payment currency record_items record_items.chart) ],
+    );
+
+  die "invalid template type" unless $template->template_type eq 'ar_transaction';
+
+  $template->substitute_variables;
+
+  # Clean the current $::form before rebuilding it from the template.
+  my $form_defaults = delete $::form->{form_defaults};
+  delete @{ $::form }{ grep { !m{^(?:script|login)$}i } keys %{ $::form } };
+
+  # Fill $::form from the template.
+  my $today                   = DateTime->today_local;
+  $::form->{title}            = "Add";
+  $::form->{currency}         = $template->currency->name;
+  $::form->{direct_debit}     = $template->direct_debit;
+  $::form->{globalproject_id} = $template->project_id;
+  $::form->{AR_chart_id}      = $template->ar_ap_chart_id;
+  $::form->{transdate}        = $today->to_kivitendo;
+  $::form->{duedate}          = $today->to_kivitendo;
+  $::form->{rowcount}         = @{ $template->items };
+  $::form->{paidaccounts}     = 1;
+  $::form->{$_}               = $template->$_ for qw(department_id ordnumber taxincluded employee_id notes);
+
+  if ($template->customer) {
+    $::form->{customer_id} = $template->customer_id;
+    $::form->{customer}    = $template->customer->name;
+    $::form->{duedate}     = $template->customer->payment->calc_date(reference_date => $today)->to_kivitendo if $template->customer->payment;
+  }
+
+  my $row = 0;
+  foreach my $item (@{ $template->items }) {
+    $row++;
+
+    my $active_taxkey = $item->chart->get_active_taxkey;
+    my $taxes         = SL::DB::Manager::Tax->get_all(
+      where   => [ chart_categories => { like => '%' . $item->chart->category . '%' }],
+      sort_by => 'taxkey, rate',
+    );
+
+    my $tax   = first { $item->tax_id          == $_->id } @{ $taxes };
+    $tax    //= first { $active_taxkey->tax_id == $_->id } @{ $taxes };
+    $tax    //= $taxes->[0];
+
+    if (!$tax) {
+      $row--;
+      next;
+    }
+
+    $::form->{"AR_amount_chart_id_${row}"}          = $item->chart_id;
+    $::form->{"previous_AR_amount_chart_id_${row}"} = $item->chart_id;
+    $::form->{"amount_${row}"}                      = $::form->format_amount(\%::myconfig, $item->amount1, 2);
+    $::form->{"taxchart_${row}"}                    = $item->tax_id . '--' . $tax->rate;
+    $::form->{"project_id_${row}"}                  = $item->project_id;
+  }
+
+  $::form->{$_} = $form_defaults->{$_} for keys %{ $form_defaults // {} };
+
+  flash('info', $::locale->text("The record template '#1' has been loaded.", $template->template_name));
+
+  update(
+    keep_rows_without_amount => 1,
+    dont_add_new_row         => 1,
+  );
+}
+
+sub save_record_template {
+  $::auth->assert('ar_transactions');
+
+  my $template = $::form->{record_template_id} ? SL::DB::RecordTemplate->new(id => $::form->{record_template_id})->load : SL::DB::RecordTemplate->new;
+  my $js       = SL::ClientJS->new(controller => SL::Controller::Base->new);
+  my $new_name = $template->template_name_to_use($::form->{record_template_new_template_name});
+
+  $js->dialog->close('#record_template_dialog');
+
+  my @items = grep {
+    $_->{chart_id} && (($_->{tax_id} // '') ne '')
+  } map {
+    +{ chart_id   => $::form->{"AR_amount_chart_id_${_}"},
+       amount1    => $::form->parse_amount(\%::myconfig, $::form->{"amount_${_}"}),
+       tax_id     => (split m{--}, $::form->{"taxchart_${_}"})[0],
+       project_id => $::form->{"project_id_${_}"} || undef,
+     }
+  } (1..($::form->{rowcount} || 1));
+
+  $template->assign_attributes(
+    template_type  => 'ar_transaction',
+    template_name  => $new_name,
+
+    currency_id    => SL::DB::Manager::Currency->find_by(name => $::form->{currency})->id,
+    ar_ap_chart_id => $::form->{AR_chart_id}      || undef,
+    customer_id    => $::form->{customer_id}      || undef,
+    department_id  => $::form->{department_id}    || undef,
+    project_id     => $::form->{globalproject_id} || undef,
+    employee_id    => $::form->{employee_id}      || undef,
+    taxincluded    => $::form->{taxincluded}  ? 1 : 0,
+    direct_debit   => $::form->{direct_debit} ? 1 : 0,
+    ordnumber      => $::form->{ordnumber},
+    notes          => $::form->{notes},
+
+    items          => \@items,
+  );
+
+  eval {
+    $template->save;
+    1;
+  } or do {
+    return $js
+      ->flash('error', $::locale->text("Saving the record template '#1' failed.", $new_name))
+      ->render;
+  };
+
+  return $js
+    ->flash('info', $::locale->text("The record template '#1' has been saved.", $new_name))
+    ->render;
+}
+
 sub add {
   $main::lxdebug->enter_sub();
 
@@ -172,34 +303,14 @@ sub create_links {
   IS->get_customer(\%myconfig, \%$form);
 
   $form->{$_}          = $saved{$_} for keys %saved;
-  $form->{oldcustomer} = "$form->{customer}--$form->{customer_id}";
   $form->{rowcount}    = 1;
   $form->{AR_chart_id} = $form->{acc_trans} && $form->{acc_trans}->{AR} ? $form->{acc_trans}->{AR}->[0]->{chart_id} : $form->{AR_links}->{AR}->[0]->{chart_id};
 
   # currencies
   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
 
-  $form->{selectcurrency} = "";
-  map { $form->{selectcurrency} .= "<option>$_\n" } $form->get_all_currencies(\%myconfig);
-
-  # customers
-  if (@{ $form->{all_customer} || [] }) {
-    $form->{customer} = "$form->{customer}--$form->{customer_id}";
-    map { $form->{selectcustomer} .= "<option>$_->{name}--$_->{id}\n" }
-      (@{ $form->{all_customer} });
-  }
-
   $form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all;
 
-  $form->{employee} = "$form->{employee}--$form->{employee_id}";
-
-  # sales staff
-  if (@{ $form->{all_employees} || [] }) {
-    $form->{selectemployee} = "";
-    map { $form->{selectemployee} .= "<option>$_->{name}--$_->{id}\n" }
-      (@{ $form->{all_employees} || [] });
-  }
-
   # build the popup menus
   $form->{taxincluded} = ($form->{id}) ? $form->{taxincluded} : "checked";
 
@@ -225,9 +336,9 @@ sub form_header {
   $form->{invoice_obj} = _retrieve_invoice_object();
 
   my ($title, $readonly, $exchangerate, $rows);
-  my ($notes, $customer, $employee, $amount, $project);
+  my ($notes, $amount, $project);
 
-  $form->{initial_focus} = !($form->{amount_1} * 1) ? 'customer' : 'row_' . $form->{rowcount};
+  $form->{initial_focus} = !($form->{amount_1} * 1) ? 'customer_id' : 'row_' . $form->{rowcount};
 
   $title = $form->{title};
   # $locale->text('Add Accounts Receivables Transaction')
@@ -241,12 +352,6 @@ sub form_header {
                       : ($::instance_conf->get_ar_changeable == 1);
   $readonly = ($form->{radier}) ? "" : $readonly;
 
-  # set option selected
-  foreach my $item (qw(customer currency employee)) {
-    $form->{"select$item"} =~ s/ selected//;
-    $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
-  }
-
   $form->{forex}        = $form->check_exchangerate( \%myconfig, $form->{currency}, $form->{transdate}, 'buy');
   $form->{exchangerate} = $form->{forex} if $form->{forex};
 
@@ -284,11 +389,10 @@ sub form_header {
     }
   }
 
-  my $follow_up_vc         =  $form->{customer};
-  $follow_up_vc            =~ s/--.*?//;
+  my $follow_up_vc         = $form->{customer_id} ? SL::DB::Customer->load_cached($form->{customer_id})->name : '';
   my $follow_up_trans_info =  "$form->{invnumber} ($follow_up_vc)";
 
-  $::request->layout->add_javascripts("autocomplete_chart.js", "show_vc_details.js", "show_history.js", "follow_up.js", "kivi.Draft.js", "kivi.GL.js");
+  $::request->layout->add_javascripts("autocomplete_chart.js", "autocomplete_customer.js", "show_vc_details.js", "show_history.js", "follow_up.js", "kivi.Draft.js", "kivi.GL.js", "kivi.File.js", "kivi.RecordTemplate.js");
 
   my $transdate = $::form->{transdate} ? DateTime->from_kivitendo($::form->{transdate}) : DateTime->today_local;
   my $first_taxchart;
@@ -388,6 +492,16 @@ sub form_header {
 
   $form->{totalpaid} = sum map { $_->{paid} } @payments;
 
+  my $employees = SL::DB::Manager::Employee->get_all_sorted(
+    where => [
+      or => [
+        (id     => $::form->{employee_id}) x !!$::form->{employee_id},
+        deleted => undef,
+        deleted => 0,
+      ],
+    ],
+  );
+
   $form->header;
   print $::form->parse_html_template('ar/form_header', {
     paid_missing         => $::form->{invtotal} - $::form->{totalpaid},
@@ -400,6 +514,8 @@ sub form_header {
     title_str            => $title,
     follow_up_trans_info => $follow_up_trans_info,
     today                => DateTime->today,
+    currencies           => scalar(SL::DB::Manager::Currency->get_all_sorted),
+    employees            => $employees,
   });
 
   $main::lxdebug->leave_sub();
@@ -443,16 +559,11 @@ sub form_footer {
 }
 
 sub mark_as_paid {
-  $main::lxdebug->enter_sub();
+  $::auth->assert('ar_transactions');
 
-  $main::auth->assert('ar_transactions');
+  SL::DB::Invoice->new(id => $::form->{id})->load->mark_as_paid;
 
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-
-  &mark_as_paid_common(\%myconfig,"ar");
-
-  $main::lxdebug->leave_sub();
+  $::form->redirect($::locale->text("Marked as paid"));
 }
 
 sub show_draft {
@@ -462,6 +573,7 @@ sub show_draft {
 }
 
 sub update {
+  my %params = @_;
   $main::lxdebug->enter_sub();
 
   $main::auth->assert('ar_transactions');
@@ -486,7 +598,7 @@ sub update {
 
   for my $i (1 .. $form->{rowcount}) {
     $form->{"amount_$i"} = $form->parse_amount(\%myconfig, $form->{"amount_$i"});
-    if ($form->{"amount_$i"}) {
+    if ($form->{"amount_$i"} || $params{keep_rows_without_amount}) {
       push @a, {};
       my $j = $#a;
       my ($taxkey, $rate) = split(/--/, $form->{"taxchart_$i"});
@@ -501,7 +613,7 @@ sub update {
   }
 
   $form->redo_rows(\@flds, \@a, $count, $form->{rowcount});
-  $form->{rowcount} = $count + 1;
+  $form->{rowcount} = $count + ($params{dont_add_new_row} ? 0 : 1);
   map { $form->{invtotal} += $form->{"amount_$_"} } (1 .. $form->{rowcount});
 
   $form->{forex}        = $form->check_exchangerate( \%myconfig, $form->{currency}, $form->{transdate}, 'buy');
@@ -509,7 +621,9 @@ sub update {
 
   $form->{invdate} = $form->{transdate};
 
-  &check_name("customer");
+  if (($form->{previous_customer_id} || $form->{customer_id}) != $form->{customer_id}) {
+    IS->get_customer(\%myconfig, $form);
+  }
 
   $form->{invtotal} =
     ($form->{taxincluded}) ? $form->{invtotal} : $form->{invtotal} + $totaltax;
@@ -534,7 +648,7 @@ sub update {
   $form->{oldinvtotal}  = $form->{invtotal};
   $form->{oldtotalpaid} = $form->{totalpaid};
 
-  &display_form;
+  display_form();
 
   $main::lxdebug->leave_sub();
 }
@@ -621,7 +735,7 @@ sub post {
   # check if there is an invoice number, invoice and due date
   $form->isblank("transdate", $locale->text('Invoice Date missing!'));
   $form->isblank("duedate",   $locale->text('Due Date missing!'));
-  $form->isblank("customer",  $locale->text('Customer missing!'));
+  $form->isblank("customer_id", $locale->text('Customer missing!'));
 
   if ($myconfig{mandatory_departments} && !$form->{department_id}) {
     $form->{saved_message} = $::locale->text('You have to specify a department.');
@@ -667,8 +781,7 @@ sub post {
   }
 
   # if oldcustomer ne customer redo form
-  my ($customer) = split /--/, $form->{customer};
-  if ($form->{oldcustomer} ne "$customer--$form->{customer_id}") {
+  if (($form->{previous_customer_id} || $form->{customer_id}) != $form->{customer_id}) {
     update();
     $::dispatcher->end_request;
   }
@@ -688,7 +801,7 @@ sub post {
   }
   # /saving the history
 
-  $form->redirect($locale->text('Transaction posted!')) unless $inline;
+  $form->redirect($locale->text("AR transaction posted.")) unless $inline;
 
   $main::lxdebug->leave_sub();
 }
@@ -806,18 +919,11 @@ sub search {
   my $locale   = $main::locale;
   my $cgi      = $::request->{cgi};
 
-  # setup customer selection
-  $form->all_vc(\%myconfig, "customer", "AR");
-
   $form->{title}    = $locale->text('AR Transactions');
 
-  # Auch in Rechnungsübersicht nach Kundentyp filtern - jan
-  $form->get_lists("projects"       => { "key" => "ALL_PROJECTS", "all" => 1 },
-                   "customers"      => "ALL_VC",
-                   "business_types" => "ALL_BUSINESS_TYPES");
   $form->{ALL_EMPLOYEES} = SL::DB::Manager::Employee->get_all_sorted(query => [ deleted => 0 ]);
-  $form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all;
-  $form->{SHOW_BUSINESS_TYPES} = scalar @{ $form->{ALL_BUSINESS_TYPES} } > 0;
+  $form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all_sorted;
+  $form->{ALL_BUSINESS_TYPES} = SL::DB::Manager::Business->get_all_sorted;
 
   $form->{CT_CUSTOM_VARIABLES}                  = CVar->get_configs('module' => 'CT');
   ($form->{CT_CUSTOM_VARIABLES_FILTER_CODE},
@@ -828,6 +934,8 @@ sub search {
   # constants and subs for template
   $form->{vc_keys}   = sub { "$_[0]->{name}--$_[0]->{id}" };
 
+  $::request->layout->add_javascripts("autocomplete_project.js");
+
   $form->header;
   print $form->parse_html_template('ar/search', { %myconfig });
 
@@ -866,8 +974,6 @@ sub ar_transactions {
 
   my ($callback, $href, @columns);
 
-  ($form->{customer}, $form->{customer_id}) = split(/--/, $form->{customer});
-
   report_generator_set_default_sort('transdate', 1);
 
   AR->ar_transactions(\%myconfig, \%$form);