# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1335, USA.
#======================================================================
#
# Genereal Ledger
use strict;
use POSIX qw(strftime);
-use List::Util qw(sum);
+use List::Util qw(first sum);
+use SL::DB::RecordTemplate;
+use SL::DB::Tax;
use SL::FU;
use SL::GL;
+use SL::Helper::Flash qw(flash);
use SL::IS;
-use SL::PE;
use SL::ReportGenerator;
-
+use SL::DBUtils qw(selectrow_query selectall_hashref_query);
+use SL::Webdav;
+use SL::Locale::String qw(t8);
+use SL::Helper::GlAttachments qw(count_gl_attachments);
require "bin/mozilla/common.pl";
-require "bin/mozilla/drafts.pl";
require "bin/mozilla/reportgenerator.pl";
# this is for our long dates
# $locale->text('Nov')
# $locale->text('Dec')
+sub load_record_template {
+ $::auth->assert('gl_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 'gl_transaction';
+
+ $template->substitute_variables;
+ my $payment_suggestion = $::form->{form_defaults}->{amount_1};
+
+ # 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 } };
+
+ my $dummy_form = {};
+ GL->transaction(\%::myconfig, $dummy_form);
+
+ # Fill $::form from the template.
+ my $today = DateTime->today_local;
+ $::form->{title} = "Add";
+ $::form->{transdate} = $today->to_kivitendo;
+ $::form->{duedate} = $today->to_kivitendo;
+ $::form->{rowcount} = @{ $template->items };
+ $::form->{paidaccounts} = 1;
+ $::form->{$_} = $template->$_ for qw(department_id taxincluded ob_transaction cb_transaction reference description);
+ $::form->{$_} = $dummy_form->{$_} for qw(closedto revtrans previous_id previous_gldate);
+
+ 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->{"accno_id_${row}"} = $item->chart_id;
+ $::form->{"previous_accno_id_${row}"} = $item->chart_id;
+ $::form->{"debit_${row}"} = $::form->format_amount(\%::myconfig, ($payment_suggestion ? $payment_suggestion : $item->amount1), 2) if $item->amount1 * 1;
+ $::form->{"credit_${row}"} = $::form->format_amount(\%::myconfig, ($payment_suggestion ? $payment_suggestion : $item->amount2), 2) if $item->amount2 * 1;
+ $::form->{"taxchart_${row}"} = $item->tax_id . '--' . $tax->rate;
+ $::form->{"${_}_${row}"} = $item->$_ for qw(source memo 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('gl_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->{"accno_id_${_}"},
+ amount1 => $::form->parse_amount(\%::myconfig, $::form->{"debit_${_}"}),
+ amount2 => $::form->parse_amount(\%::myconfig, $::form->{"credit_${_}"}),
+ tax_id => (split m{--}, $::form->{"taxchart_${_}"})[0],
+ project_id => $::form->{"project_id_${_}"} || undef,
+ source => $::form->{"source_${_}"},
+ memo => $::form->{"memo_${_}"},
+ }
+ } (1..($::form->{rowcount} || 1));
+
+ $template->assign_attributes(
+ template_type => 'gl_transaction',
+ template_name => $new_name,
+
+ currency_id => $::instance_conf->get_currency_id,
+ department_id => $::form->{department_id} || undef,
+ project_id => $::form->{globalproject_id} || undef,
+ taxincluded => $::form->{taxincluded} ? 1 : 0,
+ ob_transaction => $::form->{ob_transaction} ? 1 : 0,
+ cb_transaction => $::form->{cb_transaction} ? 1 : 0,
+ reference => $::form->{reference},
+ description => $::form->{description},
+
+ 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();
- $main::auth->assert('general_ledger');
+ $main::auth->assert('gl_transactions');
my $form = $main::form;
my %myconfig = %main::myconfig;
- return $main::lxdebug->leave_sub() if (load_draft_maybe());
-
$form->{title} = "Add";
$form->{callback} = "gl.pl?action=add" unless $form->{callback};
$form->{credit} = 0;
$form->{tax} = 0;
- # departments
- $form->all_departments(\%myconfig);
- if (@{ $form->{all_departments} || [] }) {
- $form->{selectdepartment} = "<option>\n";
-
- map {
- $form->{selectdepartment} .=
- "<option>$_->{description}--$_->{id}\n"
- } (@{ $form->{all_departments} || [] });
- }
+ $::form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all;
$form->{show_details} = $myconfig{show_form_details} unless defined $form->{show_details};
sub prepare_transaction {
$main::lxdebug->enter_sub();
- $main::auth->assert('general_ledger');
+ $main::auth->assert('gl_transactions');
my $form = $main::form;
my %myconfig = %main::myconfig;
$form->{amount} = $form->format_amount(\%myconfig, $form->{amount}, 2);
- # departments
- $form->all_departments(\%myconfig);
- if (@{ $form->{all_departments} || [] }) {
- $form->{selectdepartment} = "<option>\n";
-
- map {
- $form->{selectdepartment} .=
- "<option>$_->{description}--$_->{id}\n"
- } (@{ $form->{all_departments} || [] });
- }
+ $::form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all;
my $i = 1;
my $tax = 0;
$form->{"project_id_$j"} = $ref->{project_id};
} else {
- $form->{"accno_$i"} = "$ref->{accno}--$ref->{tax_id}";
+ $form->{"accno_id_$i"} = $ref->{chart_id};
for (qw(fx_transaction source memo)) { $form->{"${_}_$i"} = $ref->{$_} }
if ($ref->{amount} < 0) {
$form->{totaldebit} -= $ref->{amount};
$form->{totalcredit} += $ref->{amount};
$form->{"credit_$i"} = $ref->{amount};
}
- $form->{"taxchart_$i"} = "0--0.00";
+ $form->{"taxchart_$i"} = $ref->{id}."--0.00000";
$form->{"project_id_$i"} = $ref->{project_id};
$i++;
}
sub edit {
$main::lxdebug->enter_sub();
- $main::auth->assert('general_ledger');
+ $main::auth->assert('gl_transactions');
my $form = $main::form;
my %myconfig = %main::myconfig;
$form->{show_details} = $myconfig{show_form_details} unless defined $form->{show_details};
+ if ($form->{id} && $::instance_conf->get_webdav) {
+ my $webdav = SL::Webdav->new(
+ type => 'general_ledger',
+ number => $form->{id},
+ );
+ my @all_objects = $webdav->get_all_objects;
+ @{ $form->{WEBDAV} } = map { { name => $_->filename,
+ type => t8('File'),
+ link => File::Spec->catfile($_->full_filedescriptor),
+ } } @all_objects;
+ }
form_header();
display_rows();
form_footer();
sub search {
$::lxdebug->enter_sub;
- $::auth->assert('general_ledger');
+ $::auth->assert('general_ledger | gl_transactions');
- $::form->all_departments(\%::myconfig);
$::form->get_lists(
projects => { key => "ALL_PROJECTS", all => 1 },
- employees => "ALL_EMPLOYEES",
);
+ $::form->{ALL_EMPLOYEES} = SL::DB::Manager::Employee->get_all_sorted(query => [ deleted => 0 ]);
+ $::form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all;
- my $onload = "focus()"
- . qq|;setupDateFormat('|. $::myconfig{dateformat} . qq|', '| . $::locale->text("Falsches Datumsformat!") . qq|')|
- . qq|;setupPoints('|. $::myconfig{numberformat} . qq|', '| . $::locale->text("wrongformat") . qq|')|;
+ setup_gl_search_action_bar();
$::form->header;
print $::form->parse_html_template('gl/search', {
- onload => $onload,
- department_label => sub { ("$_[0]{description}--$_[0]{id}")x2 },
employee_label => sub { "$_[0]{id}--$_[0]{name}" },
});
sub generate_report {
$main::lxdebug->enter_sub();
- $main::auth->assert('general_ledger');
+ $main::auth->assert('general_ledger | gl_transactions');
my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;
- # generate_report wird beim ersten Aufruf per Weiter-Knopf und POST mit der hidden Variablen sort mit Wert "datesort" (früher "transdate" als Defaultsortiervariable) übertragen
+ # generate_report wird beim ersten Aufruf per Weiter-Knopf und POST mit der hidden Variablen sort mit Wert "datesort" (früher "transdate" als Defaultsortiervariable) übertragen
# <form method=post action=gl.pl>
# <input type=hidden name=sort value=datesort> # form->{sort} setzen
# <input type=hidden name=nextsub value=generate_report>
# anhand von neuer Variable datesort wird jetzt $form->{sort} auf transdate oder gldate gesetzt
- # damit ist die Hidden Variable "sort" wahrscheinlich sogar überflüssig
+ # damit ist die Hidden Variable "sort" wahrscheinlich sogar überflüssig
- # ändert man die Sortierreihenfolge per Klick auf eine der Überschriften wird die Variable "sort" per GET übergeben, z.B. id,transdate, gldate, ...
+ # ändert man die Sortierreihenfolge per Klick auf eine der Überschriften wird die Variable "sort" per GET übergeben, z.B. id,transdate, gldate, ...
# gl.pl?action=generate_report&employee=18383--Jan%20B%c3%bcren&datesort=transdate&category=X&l_transdate=Y&l_gldate=Y&l_id=Y&l_reference=Y&l_description=Y&l_source=Y&l_debit=Y&l_credit=Y&sort=gldate&sortdir=0
if ( $form->{sort} eq 'datesort' ) { # sollte bei einem Post (Aufruf aus Suchmaske) immer wahr sein
my $ml = ($form->{ml} =~ /(A|E|Q)/) ? -1 : 1;
my @columns = qw(
- gldate transdate id reference description
- notes source debit debit_accno
+ transdate gldate id reference description
+ notes source doccnt debit debit_accno
credit credit_accno debit_tax debit_tax_accno
credit_tax credit_tax_accno projectnumbers balance employee
);
# add employee here, so that variable is still known and passed in url when choosing a different sort order in resulting table
- my @hidden_variables = qw(accno source reference department description notes project_id datefrom dateto employee datesort category l_subtotal);
+ my @hidden_variables = qw(accno source reference description notes project_id datefrom dateto employee_id datesort category l_subtotal department_id);
push @hidden_variables, map { "l_${_}" } @columns;
- foreach ( @hidden_variables ) {
- print URL "$_\n";
- };
+
+ my $employee = $form->{employee_id} ? SL::DB::Employee->new(id => $form->{employee_id})->load->name : '';
my (@options, @date_options);
push @options, $locale->text('Account') . " : $form->{accno} $form->{account_description}" if ($form->{accno});
push @options, $locale->text('Reference') . " : $form->{reference}" if ($form->{reference});
push @options, $locale->text('Description') . " : $form->{description}" if ($form->{description});
push @options, $locale->text('Notes') . " : $form->{notes}" if ($form->{notes});
- push @options, $locale->text('Employee') . " : $form->{employee_name}" if ($form->{employee_name});
- my $datesorttext = $form->{datesort} eq 'transdate' ? $locale->text('Invoice Date') : $locale->text('Booking Date');
+ push @options, $locale->text('Employee') . " : $employee" if $employee;
+ my $datesorttext = $form->{datesort} eq 'transdate' ? $locale->text('Transdate') : $locale->text('Gldate');
push @date_options, "$datesorttext" if ($form->{datesort} and ($form->{datefrom} or $form->{dateto}));
push @date_options, $locale->text('From'), $locale->date(\%myconfig, $form->{datefrom}, 1) if ($form->{datefrom});
push @date_options, $locale->text('Bis'), $locale->date(\%myconfig, $form->{dateto}, 1) if ($form->{dateto});
push @options, join(' ', @date_options) if (scalar @date_options);
- if ($form->{department}) {
- my ($department) = split /--/, $form->{department};
- push @options, $locale->text('Department') . " : $department";
+ if ($form->{department_id}) {
+ my $department = SL::DB::Manager::Department->find_by( id => $form->{department_id} );
+ push @options, $locale->text('Department') . " : " . $department->description;
}
-
my $callback = build_std_url('action=generate_report', grep { $form->{$_} } @hidden_variables);
- print URL $callback;
- close URL;
$form->{l_credit_accno} = 'Y';
$form->{l_debit_accno} = 'Y';
$form->{l_datesort} = 'Y';
$form->{l_debit_tax_accno} = 'Y';
$form->{l_balance} = $form->{accno} ? 'Y' : '';
+ $form->{l_doccnt} = $form->{l_source} ? 'Y' : '';
my %column_defs = (
'id' => { 'text' => $locale->text('ID'), },
- 'transdate' => { 'text' => $locale->text('Invoice Date'), },
- 'gldate' => { 'text' => $locale->text('Booking Date'), },
+ 'transdate' => { 'text' => $locale->text('Transdate'), },
+ 'gldate' => { 'text' => $locale->text('Gldate'), },
'reference' => { 'text' => $locale->text('Reference'), },
'source' => { 'text' => $locale->text('Source'), },
+ 'doccnt' => { 'text' => $locale->text('Document Count'), },
'description' => { 'text' => $locale->text('Description'), },
'notes' => { 'text' => $locale->text('Notes'), },
'debit' => { 'text' => $locale->text('Debit'), },
$report->set_columns(%column_defs);
$report->set_column_order(@columns);
- $report->set_export_options('generate_report', @hidden_variables, qw(sort sortdir));
+ $form->{l_attachments} = 'Y';
+ $report->set_export_options('generate_report', @hidden_variables, qw(sort sortdir l_attachments));
$report->set_sort_indicator($form->{sort} eq 'accno' ? 'debit_accno' : $form->{sort}, $form->{sortdir});
my $row = { };
map { $row->{$_} = { 'data' => '', 'align' => $column_alignment{$_} } } @columns;
+ if ( $form->{l_doccnt} ) {
+ $row->{doccnt}->{data} = SL::Helper::GlAttachments->count_gl_pdf_attachments($ref->{id},$ref->{type});
+ }
+
my $sh = "";
if ($form->{balance} < 0) {
$sh = " S";
my $row_set = [ $row ];
- if (($form->{l_subtotal} eq 'Y')
+ if ( ($form->{l_subtotal} eq 'Y' && !$form->{report_generator_csv_options_for_import} )
&& (($idx == (scalar @{ $form->{GL} } - 1))
|| ($ref->{ $form->{sort} } ne $form->{GL}->[$idx + 1]->{ $form->{sort} }))) {
push @{ $row_set }, create_subtotal_row(\%subtotals, \@columns, \%column_alignment, [ qw(debit credit) ], 'listsubtotal');
$idx++;
}
- $report->add_separator();
-
# = 0 for balanced ledger
my $balanced_ledger = $totals{debit} + $totals{debit_tax} - $totals{credit} - $totals{credit_tax};
$row->{balance}->{data} = $data;
- $report->add_data($row);
+ if ( !$form->{report_generator_csv_options_for_import} ) {
+ $report->add_separator();
+ $report->add_data($row);
+ }
my $raw_bottom_info_text;
$report->set_options('raw_bottom_info_text' => $raw_bottom_info_text);
+ setup_gl_transactions_action_bar(num_rows => scalar(@{$form->{GL}}));
+
$report->generate_with_headers();
$main::lxdebug->leave_sub();
}
+sub show_draft {
+ $::form->{transdate} = DateTime->today_local->to_kivitendo if !$::form->{transdate};
+ $::form->{gldate} = $::form->{transdate} if !$::form->{gldate};
+ update();
+}
+
sub update {
+ my %params = @_;
+
$main::lxdebug->enter_sub();
- $main::auth->assert('general_ledger');
+ $main::auth->assert('gl_transactions');
my $form = $main::form;
my %myconfig = %main::myconfig;
my $creditcount = 0;
my ($debitcredit, $amount);
+ my $dbh = SL::DB->client->dbh;
+ my ($notax_id) = selectrow_query($form, $dbh, "SELECT id FROM tax WHERE taxkey = 0 LIMIT 1", );
+ my $zerotaxes = selectall_hashref_query($form, $dbh, "SELECT id FROM tax WHERE rate = 0", );
+
my @flds =
qw(accno debit credit projectnumber fx_transaction source memo tax taxchart);
for my $i (1 .. $form->{rowcount}) {
+ $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) for qw(debit credit tax);
- unless (($form->{"debit_$i"} eq "") && ($form->{"credit_$i"} eq "")) {
- for (qw(debit credit tax)) {
- $form->{"${_}_$i"} =
- $form->parse_amount(\%myconfig, $form->{"${_}_$i"});
- }
+ next if !$form->{"debit_$i"} && !$form->{"credit_$i"} && !$params{keep_rows_without_amount};
- push @a, {};
- $debitcredit = ($form->{"debit_$i"} == 0) ? "0" : "1";
- if ($debitcredit) {
- $debitcount++;
- } else {
- $creditcount++;
- }
+ push @a, {};
+ $debitcredit = ($form->{"debit_$i"} == 0) ? "0" : "1";
+ if ($debitcredit) {
+ $debitcount++;
+ } else {
+ $creditcount++;
+ }
- if (($debitcount >= 2) && ($creditcount == 2)) {
- $form->{"credit_$i"} = 0;
- $form->{"tax_$i"} = 0;
- $creditcount--;
- $form->{creditlock} = 1;
- }
- if (($creditcount >= 2) && ($debitcount == 2)) {
- $form->{"debit_$i"} = 0;
- $form->{"tax_$i"} = 0;
- $debitcount--;
- $form->{debitlock} = 1;
- }
- if (($creditcount == 1) && ($debitcount == 2)) {
- $form->{creditlock} = 1;
- }
- if (($creditcount == 2) && ($debitcount == 1)) {
- $form->{debitlock} = 1;
- }
- if ($debitcredit && $credittax) {
- $form->{"taxchart_$i"} = "0--0.00";
- }
- if (!$debitcredit && $debittax) {
- $form->{"taxchart_$i"} = "0--0.00";
- }
- $amount =
- ($form->{"debit_$i"} == 0)
- ? $form->{"credit_$i"}
- : $form->{"debit_$i"};
- my $j = $#a;
- if (($debitcredit && $credittax) || (!$debitcredit && $debittax)) {
- $form->{"taxchart_$i"} = "0--0.00";
- $form->{"tax_$i"} = 0;
- }
- my ($taxkey, $rate) = split(/--/, $form->{"taxchart_$i"});
- if ($taxkey > 1) {
- if ($debitcredit) {
- $debittax = 1;
- } else {
- $credittax = 1;
- }
- if ($form->{taxincluded}) {
- $form->{"tax_$i"} = $amount / ($rate + 1) * $rate;
- } else {
- $form->{"tax_$i"} = $amount * $rate;
- }
+ if (($debitcount >= 2) && ($creditcount == 2)) {
+ $form->{"credit_$i"} = 0;
+ $form->{"tax_$i"} = 0;
+ $creditcount--;
+ $form->{creditlock} = 1;
+ }
+ if (($creditcount >= 2) && ($debitcount == 2)) {
+ $form->{"debit_$i"} = 0;
+ $form->{"tax_$i"} = 0;
+ $debitcount--;
+ $form->{debitlock} = 1;
+ }
+ if (($creditcount == 1) && ($debitcount == 2)) {
+ $form->{creditlock} = 1;
+ }
+ if (($creditcount == 2) && ($debitcount == 1)) {
+ $form->{debitlock} = 1;
+ }
+ if ($debitcredit && $credittax) {
+ $form->{"taxchart_$i"} = "$notax_id--0.00";
+ }
+ if (!$debitcredit && $debittax) {
+ $form->{"taxchart_$i"} = "$notax_id--0.00";
+ }
+ $amount =
+ ($form->{"debit_$i"} == 0)
+ ? $form->{"credit_$i"}
+ : $form->{"debit_$i"};
+ my $j = $#a;
+ if (($debitcredit && $credittax) || (!$debitcredit && $debittax)) {
+ $form->{"taxchart_$i"} = "$notax_id--0.00";
+ $form->{"tax_$i"} = 0;
+ }
+ my ($taxkey, $rate) = split(/--/, $form->{"taxchart_$i"});
+ my $iswithouttax = grep { $_->{id} == $taxkey } @{ $zerotaxes };
+ if (!$iswithouttax) {
+ if ($debitcredit) {
+ $debittax = 1;
} else {
- $form->{"tax_$i"} = 0;
+ $credittax = 1;
}
+ };
+ my ($tmpnetamount,$tmpdiff);
+ ($tmpnetamount,$form->{"tax_$i"},$tmpdiff) = $form->calculate_tax($amount,$rate,$form->{taxincluded} *= 1,2);
- for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
- $count++;
- }
+ for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
+ $count++;
}
for my $i (1 .. $count) {
for (@flds) { delete $form->{"${_}_$i"} }
}
- $form->{rowcount} = $count + 1;
+ $form->{rowcount} = $count + ($params{dont_add_new_row} ? 0 : 1);
- &display_form;
+ display_form();
$main::lxdebug->leave_sub();
}
my ($init) = @_;
$main::lxdebug->enter_sub();
- $main::auth->assert('general_ledger');
+ $main::auth->assert('gl_transactions');
my $form = $main::form;
my %myconfig = %main::myconfig;
my ($init) = @_;
$main::lxdebug->enter_sub();
- $main::auth->assert('general_ledger');
+ $main::auth->assert('gl_transactions');
my $form = $main::form;
my %myconfig = %main::myconfig;
my $cgi = $::request->{cgi};
+ my %balances = GL->get_chart_balances(map { $_->{id} } @{ $form->{ALL_CHARTS} });
+
$form->{debit_1} = 0 if !$form->{"debit_1"};
$form->{totaldebit} = 0;
$form->{totalcredit} = 0;
$project_labels{$item->{"id"}} = $item->{"projectnumber"};
}
- my %chart_labels = ();
- my @chart_values = ();
- my %charts = ();
- my $taxchart_init;
- foreach my $item (@{ $form->{ALL_CHARTS} }) {
- if ($item->{charttype} eq 'H'){ #falls überschrift
- next; #überspringen (Bug 1150)
- }
- my $key = $item->{accno} . "--" . $item->{tax_id};
- $taxchart_init = $item->{tax_id} unless (@chart_values);
- push(@chart_values, $key);
- $chart_labels{$key} = $item->{accno} . "--" . $item->{description};
- $charts{$item->{accno}} = $item;
- }
-
- my %taxchart_labels = ();
- my @taxchart_values = ();
- my %taxcharts = ();
- foreach my $item (@{ $form->{ALL_TAXCHARTS} }) {
- my $key = $item->{id} . "--" . $item->{rate};
- $taxchart_init = $key if ($taxchart_init == $item->{id});
- push(@taxchart_values, $key);
- $taxchart_labels{$key} = $item->{taxdescription} . " " . $item->{rate} * 100 . ' %';
- $taxcharts{$item->{id}} = $item;
- }
+ my %charts_by_id = map { ($_->{id} => $_) } @{ $::form->{ALL_CHARTS} };
+ my $default_chart = $::form->{ALL_CHARTS}[0];
+ my $transdate = $::form->{transdate} ? DateTime->from_kivitendo($::form->{transdate}) : DateTime->today_local;
my ($source, $memo, $source_hidden, $memo_hidden);
for my $i (1 .. $form->{rowcount}) {
<input type="hidden" name="memo_$i" value="$form->{"memo_$i"}" size="16">|;
}
- my $selected_accno_full;
- my ($accno_row) = split(/--/, $form->{"accno_$i"});
- my $item = $charts{$accno_row};
- $selected_accno_full = "$item->{accno}--$item->{tax_id}";
+ my %taxchart_labels = ();
+ my @taxchart_values = ();
+
+ my $accno_id = $::form->{"accno_id_$i"};
+ my $chart = $charts_by_id{$accno_id} // $default_chart;
+ $accno_id = $chart->{id};
+ my ($first_taxchart, $default_taxchart, $taxchart_to_use);
- my $selected_taxchart = $form->{"taxchart_$i"};
- my ($selected_accno, $selected_tax_id) = split(/--/, $selected_accno_full);
- my ($previous_accno, $previous_tax_id) = split(/--/, $form->{"previous_accno_$i"});
+ foreach my $item ( GL->get_active_taxes_for_chart($accno_id, $transdate) ) {
+ my $key = $item->id . "--" . $item->rate;
+ $first_taxchart //= $item;
+ $default_taxchart = $item if $item->{is_default};
+ $taxchart_to_use = $item if $key eq $form->{"taxchart_$i"};
- if ($previous_accno &&
- ($previous_accno eq $selected_accno) &&
- ($previous_tax_id ne $selected_tax_id)) {
- my $item = $taxcharts{$selected_tax_id};
- $selected_taxchart = "$item->{id}--$item->{rate}";
+ push(@taxchart_values, $key);
+ $taxchart_labels{$key} = $item->taxdescription . " " . $item->rate * 100 . ' %';
}
- $selected_accno = '' if ($init);
- $selected_taxchart ||= $taxchart_init;
+ $taxchart_to_use //= $default_taxchart // $first_taxchart;
+ my $selected_taxchart = $taxchart_to_use->id . '--' . $taxchart_to_use->rate;
my $accno = qq|<td>| .
- NTI($cgi->popup_menu('-name' => "accno_$i",
- '-id' => "accno_$i",
- '-onChange' => "setTaxkey($i)",
- '-style' => 'width:200px',
- '-values' => \@chart_values,
- '-labels' => \%chart_labels,
- '-default' => $selected_accno_full))
- . $cgi->hidden('-name' => "previous_accno_$i",
- '-default' => $selected_accno_full)
+ $::request->presenter->chart_picker("accno_id_$i", $accno_id, style => "width: 300px") .
+ $::request->presenter->hidden_tag("previous_accno_id_$i", $accno_id)
. qq|</td>|;
my $tax_ddbox = qq|<td>| .
NTI($cgi->popup_menu('-name' => "taxchart_$i",
- '-id' => "taxchart_$i",
- '-style' => 'width:200px',
- '-values' => \@taxchart_values,
- '-labels' => \%taxchart_labels,
- '-default' => $selected_taxchart))
+ '-id' => "taxchart_$i",
+ '-style' => 'width:200px',
+ '-values' => \@taxchart_values,
+ '-labels' => \%taxchart_labels,
+ '-default' => $selected_taxchart))
. qq|</td>|;
my ($fx_transaction, $checked);
<input type="hidden" name="project_id_$i" value="$form->{"project_id_$i"}">|;
my $copy2credit = $i == 1 ? 'onkeyup="copy_debit_to_credit()"' : '';
+ my $balance = $form->format_amount(\%::myconfig, $balances{$accno_id} // 0, 2, 'DRCR');
print qq|<tr valign=top>
$accno
- <td id="chart_balance_$i" align="right"> </td>
+ <td id="chart_balance_$i" align="right">${balance}</td>
$fx_transaction
<td><input name="debit_$i" size="8" value="$form->{"debit_$i"}" accesskey=$i $copy2credit $debitreadonly></td>
<td><input name="credit_$i" size=8 value="$form->{"credit_$i"}" $creditreadonly></td>
}
-sub form_header {
- my ($init) = @_;
- $main::lxdebug->enter_sub();
-
- $main::auth->assert('general_ledger');
-
- my $form = $main::form;
- my %myconfig = %main::myconfig;
- my $locale = $main::locale;
-
- my @old_project_ids = ();
- map({ push(@old_project_ids, $form->{"project_id_$_"})
- if ($form->{"project_id_$_"}); } (1..$form->{"rowcount"}));
-
- $form->get_lists("projects" => { "key" => "ALL_PROJECTS",
- "all" => 0,
- "old_id" => \@old_project_ids },
- "charts" => { "key" => "ALL_CHARTS",
- "transdate" => $form->{transdate} },
- "taxcharts" => "ALL_TAXCHARTS");
-
- GL->get_chart_balances('charts' => $form->{ALL_CHARTS});
-
- my $title = $form->{title};
- $form->{title} = $locale->text("$title General Ledger Transaction");
- my $readonly = ($form->{id}) ? "readonly" : "";
-
- my $show_details_checked = $form->{show_details} ? "checked" : '';
- my $ob_transaction_checked = $form->{ob_transaction} ? "checked" : '';
- my $cb_transaction_checked = $form->{cb_transaction} ? "checked" : '';
-
- # $locale->text('Add General Ledger Transaction')
- # $locale->text('Edit General Ledger Transaction')
-
- map { $form->{$_} =~ s/\"/"/g }
- qw(reference description chart taxchart);
-
- $form->{javascript} = qq|<script type="text/javascript">
- <!--
- function setTaxkey(row) {
- var accno = document.getElementById('accno_' + row);
- var taxkey = accno.options[accno.selectedIndex].value;
- var reg = /--([0-9]*)/;
- var found = reg.exec(taxkey);
- var index = found[1];
- index = parseInt(index);
- var tax = 'taxchart_' + row;
- for (var i = 0; i < document.getElementById(tax).options.length; ++i) {
- var reg2 = new RegExp("^"+ index, "");
- if (reg2.exec(document.getElementById(tax).options[i].value)) {
- document.getElementById(tax).options[i].selected = true;
- break;
- }
- }
- };
-
- function copy_debit_to_credit() {
- var txt = document.getElementsByName('debit_1')[0].value;
- document.getElementsByName('credit_2')[0].value = txt;
- };
- //-->
- </script>
- <script type="text/javascript" src="js/show_form_details.js"></script>
- <script type="text/javascript" src="js/jquery.js"></script>
-|;
-
- $form->{selectdepartment} =~ s/ selected//;
- $form->{selectdepartment} =~
- s/option>\Q$form->{department}\E/option selected>$form->{department}/;
-
- my $description;
- if ((my $rows = $form->numtextrows($form->{description}, 50)) > 1) {
- $description =
- qq|<textarea name=description rows=$rows cols=50 wrap=soft $readonly >$form->{description}</textarea>|;
- } else {
- $description =
- qq|<input name=description size=50 value="$form->{description}" $readonly>|;
- }
-
- my $taxincluded = ($form->{taxincluded}) ? "checked" : "";
-
- if ($init) {
- $taxincluded = "checked";
- }
-
- my $department;
- $department = qq|
- <tr>
- <th align=right nowrap>| . $locale->text('Department') . qq|</th>
- <td colspan=3><select name=department>$form->{selectdepartment}</select></td>
- <input type=hidden name=selectdepartment value="$form->{selectdepartment}">
- </tr>
-| if $form->{selectdepartment};
- if ($init) {
- $form->{fokus} = "gl.reference";
- } else {
- $form->{fokus} = qq|gl.accno_$form->{rowcount}|;
- }
-
- # use JavaScript Calendar or not
- $form->{jsscript} = 1;
- my $jsscript = "";
- my ($button1, $button2);
- if ($form->{jsscript}) {
-
- # with JavaScript Calendar
- $button1 = qq|
- <td><input name=transdate id=transdate size=11 title="$myconfig{dateformat}" value="$form->{transdate}" $readonly onBlur=\"check_right_date_format(this)\">
- <input type=button name=transdate id="trigger1" value=|
- . $locale->text('button') . qq|></td>
- |;
-
- #write Trigger
- $jsscript =
- Form->write_trigger(\%myconfig, "1", "transdate", "BL", "trigger1");
- } else {
+sub _get_radieren {
+ return ($::instance_conf->get_gl_changeable == 2) ? ($::form->current_date(\%::myconfig) eq $::form->{gldate}) : ($::instance_conf->get_gl_changeable == 1);
+}
- # without JavaScript Calendar
- $button1 =
- qq|<td><input name=transdate id=transdate size=11 title="$myconfig{dateformat}" value="$form->{transdate}" $readonly onBlur=\"check_right_date_format(this)\"></td>|;
+sub setup_gl_action_bar {
+ my %params = @_;
+ my $form = $::form;
+ my $change_never = $::instance_conf->get_gl_changeable == 0;
+ my $change_on_same_day_only = $::instance_conf->get_gl_changeable == 2 && ($form->current_date(\%::myconfig) ne $form->{gldate});
+
+ for my $bar ($::request->layout->get('actionbar')) {
+ $bar->add(
+ action => [
+ t8('Update'),
+ submit => [ '#form', { action => 'update' } ],
+ id => 'update_button',
+ accesskey => 'enter',
+ ],
+ action => [
+ t8('Post'),
+ submit => [ '#form', { action => 'post' } ],
+ disabled => $form->{locked} ? t8('The billing period has already been locked.')
+ : $form->{storno} ? t8('A canceled general ledger transaction cannot be posted.')
+ : ($form->{id} && $change_never) ? t8('Changing general ledger transaction has been disabled in the configuration.')
+ : ($form->{id} && $change_on_same_day_only) ? t8('General ledger transactions can only be changed on the day they are posted.')
+ : undef,
+ ],
+ combobox => [
+ action => [ t8('Storno'),
+ submit => [ '#form', { action => 'storno' } ],
+ confirm => t8('Do you really want to cancel this general ledger transaction?'),
+ disabled => !$form->{id} ? t8('This general ledger transaction has not been posted yet.') : undef,
+ ],
+ action => [ t8('Delete'),
+ submit => [ '#form', { action => 'delete' } ],
+ confirm => t8('Do you really want to delete this object?'),
+ disabled => !$form->{id} ? t8('This invoice has not been posted yet.')
+ : $form->{locked} ? t8('The billing period has already been locked.')
+ : $change_never ? t8('Changing invoices has been disabled in the configuration.')
+ : $change_on_same_day_only ? t8('Invoices can only be changed on the day they are posted.')
+ : undef,
+ ],
+ ], # end of combobox "Storno"
+
+ combobox => [
+ action => [ t8('more') ],
+ action => [
+ t8('History'),
+ call => [ 'set_history_window', $form->{id} * 1, 'id' ],
+ disabled => !$form->{id} ? t8('This invoice has not been posted yet.') : undef,
+ ],
+ action => [
+ t8('Follow-Up'),
+ call => [ 'follow_up_window' ],
+ disabled => !$form->{id} ? t8('This invoice has not been posted yet.') : undef,
+ ],
+ action => [
+ t8('Record templates'),
+ call => [ 'kivi.RecordTemplate.popup', 'gl_transaction' ],
+ ],
+ action => [
+ t8('Drafts'),
+ call => [ 'kivi.Draft.popup', 'gl', 'unknown', $form->{draft_id}, $form->{draft_description} ],
+ disabled => $form->{id} ? t8('This invoice has already been posted.')
+ : $form->{locked} ? t8('The billing period has already been locked.')
+ : undef,
+ ],
+ ], # end of combobox "more"
+ );
}
+}
- $form->{previous_id} ||= "--";
- $form->{previous_gldate} ||= "--";
-
- $jsscript .= $form->parse_html_template('gl/form_header_chart_balances_js');
-
- $form->header;
-
- print qq|
-<body onLoad="focus()">
-
-<script type="text/javascript" src="js/follow_up.js"></script>
-
-<form method=post name="gl" action=gl.pl>
-|;
-
- $form->hide_form(qw(id closedto locked storno storno_id previous_id previous_gldate));
-
- print qq|
-<input type=hidden name=title value="$title">
-
-<input type="hidden" name="follow_up_trans_id_1" value="| . H($form->{id}) . qq|">
-<input type="hidden" name="follow_up_trans_type_1" value="gl_transaction">
-<input type="hidden" name="follow_up_trans_info_1" value="| . H($form->{id}) . qq|">
-<input type="hidden" name="follow_up_rowcount" value="1">
-
-<table width=100%>
- <tr>
- <th class=listtop>$form->{title}</th>
- </tr>| .
-
- ($form->{saved_message} ? qq|
- <tr>
- <td>$form->{saved_message}</th>
- </tr>| : '') .
-
-qq|
- <tr height="5"></tr>
- <tr>
- <td>
- <table width=100%>
- <tr>
- <td colspan="6" align="left">|
- . $locale->text("Previous transnumber text")
- . " $form->{previous_id} "
- . $locale->text("Previous transdate text")
- . " $form->{previous_gldate}"
- . qq|</td>
- </tr>
- <tr>
- <th align=right>| . $locale->text('Reference') . qq|</th>
- <td><input name=reference size=20 value="$form->{reference}" $readonly></td>
- <td align=left>
- <table>
- <tr>
- <th align=right nowrap>| . $locale->text('Date') . qq|</th>
- $button1
- </tr>
- </table>
- </td>
- </tr>|;
- if ($form->{id}) {
- print qq|
- <tr>
- <th align=right>| . $locale->text('Belegnummer') . qq|</th>
- <td><input name=id size=20 value="$form->{id}" $readonly></td>
- <td align=left>
- <table>
- <tr>
- <th align=right width=50%>| . $locale->text('Buchungsdatum') . qq|</th>
- <td align=left><input name=gldate size=11 title="$myconfig{dateformat}" value=$form->{gldate} $readonly onBlur=\"check_right_date_format(this)\"></td>
- </tr>
- </table>
- </td>
- </tr>|;
- }
- print qq|
- $department|;
- if ($form->{id}) {
- print qq|
- <tr>
- <th align=right width=1%>| . $locale->text('Description') . qq|</th>
- <td width=1%>$description</td>
- <td>
- <table>
- <tr>
- <th align=left>| . $locale->text('MwSt. inkl.') . qq|</th>
- <td><input type=checkbox name=taxincluded value=1 $taxincluded></td>
- </tr>
- </table>
- </td>
- <td align=left>
- <table width=100%>
- <tr>
- <th align=right width=50%>| . $locale->text('Mitarbeiter') . qq|</th>
- <td align=left><input name=employee size=20 value="| . H($form->{employee}) . qq|" readonly></td>
- </tr>
- </table>
- </td>
- </tr>|;
- } else {
- print qq|
- <tr>
- <th align=left width=1%>| . $locale->text('Description') . qq|</th>
- <td width=1%>$description</td>
- <td>
- <table>
- <tr>
- <th align=left>| . $locale->text('MwSt. inkl.') . qq|</th>
- <td><input type=checkbox name=taxincluded value=1 $taxincluded></td>
- </tr>
- </table>
- </td>
- </tr>|;
- }
+sub setup_gl_search_action_bar {
+ my %params = @_;
- print qq|
- <tr>
- <tr><td colspan=4><table><tr>
- <td>
- | . $locale->text('OB Transaction') . qq|<input type="checkbox" name="ob_transaction" value="1" $ob_transaction_checked>
- </td>
- <td>
- | . $locale->text('CB Transaction') . qq|<input type="checkbox" name="cb_transaction" value="1" $cb_transaction_checked>
- </td>
- </tr></table></td></tr>
- <tr>
- <td width="1%" align="right" nowrap>| . $locale->text('Show details') . qq|</td>
- <td width="1%"><input type="checkbox" onclick="show_form_details();" name="show_details" value="1" $show_details_checked></td>
- </tr>|;
-
- print qq|
- <tr>
- <td colspan=4>
- <table width=100%>
- <tr class=listheading>
- <th class=listheading style="width:15%">|
- . $locale->text('Account') . qq|</th>
- <th class=listheading style="width:10%">| . $locale->text('Chart balance') . qq|</th>
- <th class=listheading style="width:10%">|
- . $locale->text('Debit') . qq|</th>
- <th class=listheading style="width:10%">|
- . $locale->text('Credit') . qq|</th>
- <th class=listheading style="width:10%">|
- . $locale->text('Tax') . qq|</th>
- <th class=listheading style="width:5%">|
- . $locale->text('Taxkey') . qq|</th>|;
-
- if ($form->{show_details}) {
- print qq|
- <th class=listheading style="width:20%">| . $locale->text('Source') . qq|</th>
- <th class=listheading style="width:20%">| . $locale->text('Memo') . qq|</th>
- <th class=listheading style="width:20%">| . $locale->text('Project Number') . qq|</th>
-|;
+ for my $bar ($::request->layout->get('actionbar')) {
+ $bar->add(
+ action => [
+ t8('Search'),
+ submit => [ '#form', { action => 'continue', nextsub => 'generate_report' } ],
+ accesskey => 'enter',
+ ],
+ );
}
-
- print qq|
- </tr>
-
-$jsscript
-|;
- $main::lxdebug->leave_sub();
-
}
-sub form_footer {
- $main::lxdebug->enter_sub();
-
- $main::auth->assert('general_ledger');
-
- my $form = $main::form;
- my %myconfig = %main::myconfig;
- my $locale = $main::locale;
- my $cgi = $::request->{cgi};
-
- my $follow_ups_block;
- if ($form->{id}) {
- my $follow_ups = FU->follow_ups('trans_id' => $form->{id});
-
- if (@{ $follow_ups} ) {
- my $num_due = sum map { $_->{due} * 1 } @{ $follow_ups };
- $follow_ups_block = qq|<p>| . $locale->text("There are #1 unfinished follow-ups of which #2 are due.", scalar @{ $follow_ups }, $num_due) . qq|</p>|;
- }
+sub setup_gl_transactions_action_bar {
+ my %params = @_;
+
+ for my $bar ($::request->layout->get('actionbar')) {
+ $bar->add(
+ combobox => [
+ action => [ $::locale->text('Create new') ],
+ action => [
+ $::locale->text('GL Transaction'),
+ submit => [ '#create_new_form', { action => 'gl_transaction' } ],
+ ],
+ action => [
+ $::locale->text('AR Transaction'),
+ submit => [ '#create_new_form', { action => 'ar_transaction' } ],
+ ],
+ action => [
+ $::locale->text('AP Transaction'),
+ submit => [ '#create_new_form', { action => 'ap_transaction' } ],
+ ],
+ action => [
+ $::locale->text('Sales Invoice'),
+ submit => [ '#create_new_form', { action => 'sales_invoice' } ],
+ ],
+ action => [
+ $::locale->text('Vendor Invoice'),
+ submit => [ '#create_new_form', { action => 'vendor_invoice' } ],
+ ],
+ ], # end of combobox "Create new"
+ );
}
+}
- my ($dec) = ($form->{totaldebit} =~ /\.(\d+)/);
- $dec = length $dec;
- my $decimalplaces = ($dec > 2) ? $dec : 2;
- my $radieren = ($form->current_date(\%myconfig) eq $form->{gldate}) ? 1 : 0;
-
- map {
- $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2, " ")
- } qw(totaldebit totalcredit);
-
- print qq|
- <tr class=listtotal>
- <th colspan="3" align=right class=listtotal> $form->{totaldebit}</th>
- <th align=right class=listtotal> $form->{totalcredit}</th>
- <td colspan=6></td>
- </tr>
- </table>
- </td>
- </tr>
-</table>
+sub form_header {
+ $::lxdebug->enter_sub;
+ $::auth->assert('gl_transactions');
-<input name=callback type=hidden value="$form->{callback}">
+ my ($init) = @_;
-$follow_ups_block
+ $::request->layout->add_javascripts("autocomplete_chart.js", "kivi.File.js", "kivi.GL.js", "kivi.RecordTemplate.js");
-<br>
-|;
+ my @old_project_ids = grep { $_ } map{ $::form->{"project_id_$_"} } 1..$::form->{rowcount};
- my $transdate = $form->datetonum($form->{transdate}, \%myconfig);
- my $closedto = $form->datetonum($form->{closedto}, \%myconfig);
+ $::form->get_lists("projects" => { "key" => "ALL_PROJECTS",
+ "all" => 0,
+ "old_id" => \@old_project_ids },
- if ($form->{id}) {
+ "charts" => { "key" => "ALL_CHARTS",
+ "transdate" => $::form->{transdate} });
- if (!$form->{storno}) {
- print qq|<input class=submit type=submit name=action value="| . $locale->text('Storno') . qq|">|;
- }
+ # we cannot book on charttype header
+ @{ $::form->{ALL_CHARTS} } = grep { $_->{charttype} ne 'H' } @{ $::form->{ALL_CHARTS} };
+ $::form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all;
- # Löschen und Ändern von Buchungen nicht mehr möglich (GoB) nur am selben Tag möglich
- if (!$form->{locked} && $radieren) {
- print qq|
- <input class=submit type=submit name=action value="| . $locale->text('Post') . qq|" accesskey="b">
- <input class=submit type=submit name=action value="| . $locale->text('Delete') . qq|">|;
- }
+ my $title = $::form->{title};
+ $::form->{title} = $::locale->text("$title General Ledger Transaction");
+ # $locale->text('Add General Ledger Transaction')
+ # $locale->text('Edit General Ledger Transaction')
- print qq|
- <input class=submit type=submit name=action id=update_button value="| . $locale->text('Update') . qq|">
- <input type="button" class="submit" onclick="follow_up_window()" value="|
- . $locale->text('Follow-Up')
- . qq|"> |;
+ map { $::form->{$_} =~ s/\"/"/g }
+ qw(chart taxchart);
+ if ($init) {
+ $::request->{layout}->focus("#reference");
+ $::form->{taxincluded} = "1";
} else {
- if ($form->{draft_id}) {
- my $remove_draft_checked = $form->{remove_draft} ? 'checked' : '';
- print qq|<p>\n|
- . qq| <input name="remove_draft" id="remove_draft" type="checkbox" class="checkbox" ${remove_draft_checked}>|
- . qq| <label for="remove_draft">| . $locale->text('Remove Draft') . qq|</label>\n|
- . qq|</p>\n|;
- }
-
- print qq|
- <input class=submit type=submit name=action id=update_button value="| . $locale->text('Update') . qq|">
- <input class=submit type=submit name=action value="| . $locale->text('Post') . qq|"> |
- . NTI($cgi->submit('-name' => 'action', '-value' => $locale->text('Save draft'), '-class' => 'submit'))
- . $cgi->hidden('-name' => 'draft_id', '-default' => [$form->{draft_id}])
- . $cgi->hidden('-name' => 'draft_description', '-default' => [$form->{draft_description}]);
+ $::request->{layout}->focus("#accno_id_$::form->{rowcount}_name");
}
- print "
- </form>
+ $::form->{previous_id} ||= "--";
+ $::form->{previous_gldate} ||= "--";
-</body>
-</html>
-";
- $main::lxdebug->leave_sub();
-
-}
+ setup_gl_action_bar();
-sub delete {
- $main::lxdebug->enter_sub();
-
- my $form = $main::form;
- my $locale = $main::locale;
-
- $form->header;
+ $::form->header;
+ print $::form->parse_html_template('gl/form_header', {
+ hide_title => $title,
+ readonly => $::form->{id} && ($::form->{locked} || !_get_radieren()),
+ });
- print qq|
-<body>
+ $::lxdebug->leave_sub;
-<form method=post action=gl.pl>
-|;
+}
- map { $form->{$_} =~ s/\"/"/g } qw(reference description);
+sub form_footer {
+ $::lxdebug->enter_sub;
+ $::auth->assert('gl_transactions');
- delete $form->{header};
+ my ($follow_ups, $follow_ups_due);
- foreach my $key (keys %$form) {
- next if (($key eq 'login') || ($key eq 'password') || ('' ne ref $form->{$key}));
- print qq|<input type="hidden" name="$key" value="$form->{$key}">\n|;
+ if ($::form->{id}) {
+ $follow_ups = FU->follow_ups('trans_id' => $::form->{id}, 'not_done' => 1);
+ $follow_ups_due = sum map { $_->{due} * 1 } @{ $follow_ups || [] };
}
- print qq|
-<h2 class=confirm>| . $locale->text('Confirm!') . qq|</h2>
-
-<h4>|
- . $locale->text('Are you sure you want to delete Transaction')
- . qq| $form->{reference}</h4>
-
-<input name=action class=submit type=submit value="|
- . $locale->text('Yes') . qq|">
-</form>
-|;
- $main::lxdebug->leave_sub();
+ print $::form->parse_html_template('gl/form_footer', {
+ radieren => _get_radieren(),
+ follow_ups => $follow_ups,
+ follow_ups_due => $follow_ups_due,
+ });
+ $::lxdebug->leave_sub;
}
-sub yes {
+sub delete {
$main::lxdebug->enter_sub();
my $form = $main::form;
if (GL->delete_transaction(\%myconfig, \%$form)){
# saving the history
if(!exists $form->{addition} && $form->{id} ne "") {
- $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
+ $form->{snumbers} = qq|gltransaction_| . $form->{id};
$form->{addition} = "DELETED";
+ $form->{what_done} = "gl_transaction";
$form->save_history;
}
# /saving the history
my $debitcredit;
my %split_safety = ();
+ my $dbh = SL::DB->client->dbh;
+ my ($notax_id) = selectrow_query($form, $dbh, "SELECT id FROM tax WHERE taxkey = 0 LIMIT 1", );
+ my $zerotaxes = selectall_hashref_query($form, $dbh, "SELECT id FROM tax WHERE rate = 0", );
+
my @flds = qw(accno debit credit projectnumber fx_transaction source memo tax taxchart);
for my $i (1 .. $form->{rowcount}) {
$form->{debitlock} = 1;
}
if ($debitcredit && $credittax) {
- $form->{"taxchart_$i"} = "0--0.00";
+ $form->{"taxchart_$i"} = "$notax_id--0.00";
}
if (!$debitcredit && $debittax) {
- $form->{"taxchart_$i"} = "0--0.00";
+ $form->{"taxchart_$i"} = "$notax_id--0.00";
}
my $amount = ($form->{"debit_$i"} == 0)
? $form->{"credit_$i"}
: $form->{"debit_$i"};
my $j = $#a;
if (($debitcredit && $credittax) || (!$debitcredit && $debittax)) {
- $form->{"taxchart_$i"} = "0--0.00";
+ $form->{"taxchart_$i"} = "$notax_id--0.00";
$form->{"tax_$i"} = 0;
}
my ($taxkey, $rate) = split(/--/, $form->{"taxchart_$i"});
- if ($taxkey > 1) {
+ my $iswithouttax = grep { $_->{id} == $taxkey } @{ $zerotaxes };
+ if (!$iswithouttax) {
if ($debitcredit) {
$debittax = 1;
} else {
$credittax = 1;
}
- if ($form->{taxincluded}) {
- $form->{"tax_$i"} = $amount / ($rate + 1) * $rate;
- if ($debitcredit) {
- $form->{"debit_$i"} = $form->{"debit_$i"} - $form->{"tax_$i"};
- } else {
- $form->{"credit_$i"} = $form->{"credit_$i"} - $form->{"tax_$i"};
- }
+
+ my ($tmpnetamount,$tmpdiff);
+ ($tmpnetamount,$form->{"tax_$i"},$tmpdiff) = $form->calculate_tax($amount,$rate,$form->{taxincluded} *= 1,2);
+ if ($debitcredit) {
+ $form->{"debit_$i"} = $tmpnetamount;
} else {
- $form->{"tax_$i"} = $amount * $rate;
+ $form->{"credit_$i"} = $tmpnetamount;
}
+
} else {
$form->{"tax_$i"} = 0;
}
}
if ($split_safety{-1} > 1 && $split_safety{1} > 1) {
- $::form->error($::locale->text("Split entry detected. The values you have entered will result in an entry with more than one position on both debit and credit. Due to known problems involving accounting software Lx-Office does not allow these."));
+ $::form->error($::locale->text("Split entry detected. The values you have entered will result in an entry with more than one position on both debit and credit. " .
+ "Due to known problems involving accounting software kivitendo does not allow these."));
}
for my $i (1 .. $count) {
$form->{taxincluded} = 0 if !$taxtotal;
# this is just for the wise guys
+
+ $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));
if ($form->round_amount($debit, 2) != $form->round_amount($credit, 2)) {
$form->error($err[$errno]);
}
- undef($form->{callback});
# saving the history
if(!exists $form->{addition} && $form->{id} ne "") {
- $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
- $form->{addition} = "SAVED";
- $form->{what_done} = $locale->text("Buchungsnummer") . " = " . $form->{id};
+ $form->{snumbers} = qq|gltransaction_| . $form->{id};
+ $form->{addition} = "POSTED";
+ $form->{what_done} = "gl transaction";
$form->save_history;
}
# /saving the history
+ if ($form->{callback} =~ /BankTransaction/) {
+ print $form->redirect_header($form->{callback});
+ $form->redirect($locale->text('GL transaction posted.') . ' ' . $locale->text('ID') . ': ' . $form->{id});
+ }
+ # remove or clarify
+ undef($form->{callback});
$main::lxdebug->leave_sub();
}
sub post {
$main::lxdebug->enter_sub();
- $main::auth->assert('general_ledger');
+ $main::auth->assert('gl_transactions');
my $form = $main::form;
my $locale = $main::locale;
- if ($::myconfig{mandatory_departments} && !$form->{department}) {
- $form->{saved_message} = $::locale->text('You have to specify a department.');
- update();
- exit;
+ if ($::myconfig{mandatory_departments} && !$form->{department_id}) {
+ $form->error($locale->text('You have to specify a department.'));
}
$form->{title} = $locale->text("$form->{title} General Ledger Transaction");
$form->{storno} = 0;
post_transaction();
+ if ($::instance_conf->get_webdav) {
+ SL::Webdav->new(type => 'general_ledger',
+ number => $form->{id},
+ )->webdav_path;
+ }
- remove_draft() if $form->{remove_draft};
-
- $form->{callback} = build_std_url("action=add&DONT_LOAD_DRAFT=1", "show_details");
- $form->redirect($form->{callback});
+ $form->{callback} = build_std_url("action=add", "show_details");
+ $form->redirect($::locale->text("General ledger transaction '#1' posted", $form->{reference}));
$main::lxdebug->leave_sub();
}
sub post_as_new {
$main::lxdebug->enter_sub();
- $main::auth->assert('general_ledger');
+ $main::auth->assert('gl_transactions');
my $form = $main::form;
sub storno {
$main::lxdebug->enter_sub();
- $main::auth->assert('general_ledger');
+ $main::auth->assert('gl_transactions');
my $form = $main::form;
my %myconfig = %main::myconfig;
# saving the history
if(!exists $form->{addition} && $form->{id} ne "") {
- $form->{snumbers} = "ordnumber_$form->{ordnumber}";
+ $form->{snumbers} = qq|gltransaction_| . $form->{id};
$form->{addition} = "STORNO";
+ $form->{what_done} = "gl_transaction";
$form->save_history;
}
# /saving the history
call_sub($main::form->{nextsub});
}
+sub get_tax_dropdown {
+ my $transdate = $::form->{transdate} ? DateTime->from_kivitendo($::form->{transdate}) : DateTime->today_local;
+ my @tax_accounts = GL->get_active_taxes_for_chart($::form->{accno_id}, $transdate);
+ my $html = $::form->parse_html_template("gl/update_tax_accounts", { TAX_ACCOUNTS => \@tax_accounts });
+
+ print $::form->ajax_response_header, $html;
+}
+
+sub get_chart_balance {
+ my %balances = GL->get_chart_balances($::form->{accno_id});
+ my $balance = $::form->format_amount(\%::myconfig, $balances{ $::form->{accno_id} }, 2, 'DRCR');
+
+ print $::form->ajax_response_header, $balance;
+}
+
1;