X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;ds=sidebyside;f=bin%2Fmozilla%2Far.pl;h=f506cd9cfa22b2922e5bb9d6ba3b768adcdbd6c1;hb=1c603341fc02e3a5a7b5126cd7df6478d2e34700;hp=eaa0f2224abe8f7729b062db2a2f053d86fed3e1;hpb=de65162142f6a4341bd56db0ab13645924639f3b;p=kivitendo-erp.git diff --git a/bin/mozilla/ar.pl b/bin/mozilla/ar.pl index eaa0f2224..f506cd9cf 100644 --- a/bin/mozilla/ar.pl +++ b/bin/mozilla/ar.pl @@ -31,12 +31,25 @@ # #====================================================================== +use POSIX qw(strftime); +use List::Util qw(sum first); + use SL::AR; +use SL::FU; use SL::IS; use SL::PE; -use Data::Dumper; +use SL::ReportGenerator; + +# use strict; +#use warnings; + +# imports +our ($cgi, $form, $lxdebug, $locale, %myconfig); -require "$form->{path}/arap.pl"; +require "bin/mozilla/arap.pl"; +require "bin/mozilla/common.pl"; +require "bin/mozilla/drafts.pl"; +require "bin/mozilla/reportgenerator.pl"; 1; @@ -73,20 +86,38 @@ require "$form->{path}/arap.pl"; sub add { $lxdebug->enter_sub(); + $auth->assert('general_ledger'); + + return $lxdebug->leave_sub() if (load_draft_maybe()); + + # saving the history + if(!exists $form->{addition} && ($form->{id} ne "")) { + $form->{snumbers} = qq|invnumber_| . $form->{invnumber}; + $form->{addition} = "ADDED"; + $form->save_history($form->dbconnect(\%myconfig)); + } + # /saving the history + $form->{title} = "Add"; - $form->{callback} = - "$form->{script}?action=add&path=$form->{path}&login=$form->{login}&password=$form->{password}" - unless $form->{callback}; + $form->{callback} = "ar.pl?action=add" unless $form->{callback}; + AR->get_transdate(\%myconfig, $form); + $form->{initial_transdate} = $form->{transdate}; &create_links; + $form->{transdate} = $form->{initial_transdate}; &display_form; - $lxdebug->leave_sub(); } sub edit { $lxdebug->enter_sub(); + $auth->assert('general_ledger'); + + # show history button + $form->{javascript} = qq||; + #/show hhistory button + $form->{javascript} .= qq||; $form->{title} = "Edit"; &create_links; @@ -98,6 +129,8 @@ sub edit { sub display_form { $lxdebug->enter_sub(); + $auth->assert('general_ledger'); + &form_header; &form_footer; @@ -107,18 +140,28 @@ sub display_form { sub create_links { $lxdebug->enter_sub(); + $auth->assert('general_ledger'); + + my ($duedate, $taxincluded, @curr); + $form->create_links("AR", \%myconfig, "customer"); $duedate = $form->{duedate}; $taxincluded = $form->{taxincluded}; - + my $id = $form->{id}; IS->get_customer(\%myconfig, \%$form); + $form->{taxincluded} = $taxincluded; + $form->{id} = $id; $form->{duedate} = $duedate if $duedate; $form->{oldcustomer} = "$form->{customer}--$form->{customer_id}"; - $form->{rowcount} = 1; + $form->{rowcount} = 1; + + # notes + $form->{notes} = $form->{intnotes} unless $form->{notes}; + # currencies - @curr = split /:/, $form->{currencies}; + @curr = split(/:/, $form->{currencies}); chomp $curr[0]; $form->{defaultcurrency} = $curr[0]; @@ -154,154 +197,7 @@ sub create_links { # build the popup menus $form->{taxincluded} = ($form->{id}) ? $form->{taxincluded} : "checked"; - map { - $tax .= - qq|{taxkey}--$_->{rate}\">$_->{taxdescription} | - . ($_->{rate} * 100) . qq| %| - } @{ $form->{TAX} }; - $form->{taxchart} = $tax; - $form->{selecttaxchart} = $tax; - - # forex - $form->{forex} = $form->{exchangerate}; - $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1; - foreach $key (keys %{ $form->{AR_links} }) { - - foreach $ref (@{ $form->{AR_links}{$key} }) { - if ($key eq "AR_paid") { - $form->{"select$key"} .= - "{accno}\">$ref->{accno}--$ref->{description}\n"; - } else { - $form->{"select$key"} .= - "{accno}--$ref->{taxkey}\">$ref->{accno}--$ref->{description}\n"; - } - } - - $form->{$key} = $form->{"select$key"}; - - # if there is a value we have an old entry - my $j = 0; - my $k = 0; - print(STDERR Dumper($form->{acc_trans})); - for $i (1 .. scalar @{ $form->{acc_trans}{$key} }) { - if ($key eq "AR_paid") { - $j++; - $form->{"AR_paid_$j"} = - "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}"; - - # reverse paid - $form->{"paid_$j"} = $form->{acc_trans}{$key}->[$i - 1]->{amount} * -1; - $form->{"datepaid_$j"} = - $form->{acc_trans}{$key}->[$i - 1]->{transdate}; - $form->{"source_$j"} = $form->{acc_trans}{$key}->[$i - 1]->{source}; - $form->{"memo_$j"} = $form->{acc_trans}{$key}->[$i - 1]->{memo}; - - $form->{"forex_$j"} = $form->{"exchangerate_$i"} = - $form->{acc_trans}{$key}->[$i - 1]->{exchangerate}; - $form->{"AR_paid_$j"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}"; - $form->{paidaccounts}++; - } else { - - $akey = $key; - $akey =~ s/AR_//; - - if ($key eq "AR_tax") { - $form->{"${key}_$form->{acc_trans}{$key}->[$i-1]->{accno}"} = - "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}"; - $form->{"${akey}_$form->{acc_trans}{$key}->[$i-1]->{accno}"} = - $form->round_amount( - $form->{acc_trans}{$key}->[$i - 1]->{amount} / $exchangerate, - 2); - - if ($form->{"$form->{acc_trans}{$key}->[$i-1]->{accno}_rate"} > 0) { - $totaltax += - $form->{"${akey}_$form->{acc_trans}{$key}->[$i-1]->{accno}"}; - $taxrate += - $form->{"$form->{acc_trans}{$key}->[$i-1]->{accno}_rate"}; - } else { - $totalwithholding += - $form->{"${akey}_$form->{acc_trans}{$key}->[$i-1]->{accno}"}; - $withholdingrate += - $form->{"$form->{acc_trans}{$key}->[$i-1]->{accno}_rate"}; - } - print(STDERR $form->{acc_trans}{$key}->[$i - 1]->{amount}, " ACC_TRANS\n"); - print(STDERR "$key KEY, $k Zeile\n"); - $index = $form->{acc_trans}{$key}->[$i - 1]->{index}; - $form->{"tax_$index"} = $form->{acc_trans}{$key}->[$i - 1]->{amount}; - - } else { - $k++; - $form->{"${akey}_$k"} = - $form->round_amount( - $form->{acc_trans}{$key}->[$i - 1]->{amount} / $exchangerate, - 2); - if ($akey eq 'amount') { - $form->{rowcount}++; - $totalamount += $form->{"${akey}_$i"}; - - $form->{"oldprojectnumber_$k"} = $form->{"projectnumber_$k"} = - "$form->{acc_trans}{$key}->[$i-1]->{projectnumber}"; - $form->{taxrate} = $form->{acc_trans}{$key}->[$i - 1]->{rate}; - $form->{"project_id_$k"} = - "$form->{acc_trans}{$key}->[$i-1]->{project_id}"; - } - $form->{"${key}_$k"} = - "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}"; - $form->{"${key}_$i"} = - "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}"; - $form->{"select${key}"} =~ - /{acc_trans}{$key}->[$i-1]->{accno}--[^\"]*)\">$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}<\/option>\n/; - $test = $1; - $form->{"${key}_$k"} = $1; - if ($akey eq 'amount') { - $form->{"taxchart_$k"} = $form->{taxchart}; - $form->{"taxchart_$k"} =~ - /{acc_trans}{$key}->[$i-1]->{taxkey}--[^\"]*)/; - $form->{"taxchart_$k"} = $1; - } - } - } - } - } - - $form->{taxincluded} = $taxincluded if ($form->{id}); - $form->{paidaccounts} = 1 if not defined $form->{paidaccounts}; - - if ($form->{taxincluded} && $form->{taxrate} && $totalamount) { - - # add tax to amounts and invtotal - for $i (1 .. $form->{rowcount}) { - $taxamount = - ($totaltax + $totalwithholding) * $form->{"amount_$i"} / $totalamount; - $tax = $form->round_amount($taxamount, 2); - $diff += ($taxamount - $tax); - $form->{"amount_$i"} += $tax; - } - $form->{amount_1} += $form->round_amount($diff, 2); - } - - # check if calculated is equal to stored - if ($form->{taxincluded} && $form->{taxrate} && $withholdingrate) { - if ($form->{"taxrate"} > 0) { - $taxamount = - $form->round_amount( - ($form->{amount_1} - ($form->{amount_1} / ($form->{taxrate} + 1))), - 2); - } else { - $taxamount = - $form->round_amount( - ($totalamount + $totaltax + $totalwithholding) * $withholdingrate / - (1 - $withholdingrate), - 2 - ) * $form->{"taxrate"} / $withholdingrate; - } - } else { - $taxamount = $totalamount * $form->{"taxrate"}; - } - $taxamount = $form->round_amount($taxamount, 2); - $form->{tax} = $taxamount; - - $form->{invtotal} = $totalamount + $totaltax + $totalwithholding; + AR->setup_form($form); $form->{locked} = ($form->datetonum($form->{transdate}, \%myconfig) <= @@ -313,6 +209,15 @@ sub create_links { sub form_header { $lxdebug->enter_sub(); + $auth->assert('general_ledger'); + + my ($title, $readonly, $exchangerate, $rows); + my ($taxincluded, $notes, $department, $customer, $employee, $amount, $project); + my ($jsscript, $button1, $button2, $onload); + my ($selectAR_amount, $selectAR_paid, $ARselected, $tax); + my (@column_index, %column_data); + + $title = $form->{title}; $form->{title} = $locale->text("$title Accounts Receivables Transaction"); @@ -324,7 +229,7 @@ sub form_header { |; - + # show history button js + $form->{javascript} .= qq||; + #/show history button js + $form->{javascript} .= qq||; $readonly = ($form->{id}) ? "readonly" : ""; $form->{radier} = @@ -347,19 +255,23 @@ sub form_header { $readonly = ($form->{radier}) ? "" : $readonly; # set option selected - foreach $item (qw(customer currency department employee)) { + foreach my $item (qw(customer currency department employee)) { $form->{"select$item"} =~ s/ selected//; $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/; } - $selectAR_amount_unquoted = $form->{selectAR_amount}; - $taxchart = $form->{taxchart}; - map { $form->{$_} =~ s/\"/"/g } qw(AR_amount selectAR_amount AR taxchart); + + $form->{forex} = $form->check_exchangerate( \%myconfig, $form->{currency}, $form->{transdate}, 'buy'); + $form->{exchangerate} = $form->{forex} if $form->{forex}; # format amounts $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate}); + if ($form->{exchangerate} == 0) { + $form->{exchangerate} = ""; + } + $form->{creditlimit} = $form->format_amount(\%myconfig, $form->{creditlimit}, 0, "0"); $form->{creditremaining} = @@ -382,8 +294,6 @@ sub form_header { } } - $taxincluded = ""; - $taxincluded = qq| {taxincluded}> @@ -406,11 +316,10 @@ sub form_header { | if $form->{selectdepartment}; - $n = ($form->{creditremaining} =~ /-/) ? "0" : "1"; + my $n = ($form->{creditremaining} =~ /-/) ? "0" : "1"; - $customer = - ($form->{selectcustomer}) - ? qq|$form->{selectcustomer}| + $customer = ($form->{selectcustomer}) + ? qq|$form->{selectcustomer}| : qq||; $employee = qq| @@ -427,25 +336,84 @@ sub form_header { |; } + 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" => { "key" => "ALL_TAXCHARTS", + "module" => "AR" },); + + map({ $_->{link_split} = [ split(/:/, $_->{link}) ]; } + @{ $form->{ALL_CHARTS} }); + + my %project_labels = (); + my @project_values = (""); + foreach my $item (@{ $form->{"ALL_PROJECTS"} }) { + push(@project_values, $item->{"id"}); + $project_labels{$item->{"id"}} = $item->{"projectnumber"}; + } + + my (%AR_amount_labels, @AR_amount_values); + my (%AR_labels, @AR_values); + my (%AR_paid_labels, @AR_paid_values); + my %charts; + my $taxchart_init; + + foreach my $item (@{ $form->{ALL_CHARTS} }) { + if (grep({ $_ eq "AR_amount" } @{ $item->{link_split} })) { + $taxchart_init = $item->{tax_id} if ($taxchart_init eq ""); + my $key = "$item->{accno}--$item->{tax_id}"; + push(@AR_amount_values, $key); + $AR_amount_labels{$key} = + "$item->{accno}--$item->{description}"; + + } elsif (grep({ $_ eq "AR" } @{ $item->{link_split} })) { + push(@AR_values, $item->{accno}); + $AR_labels{$item->{accno}} = "$item->{accno}--$item->{description}"; + + } elsif (grep({ $_ eq "AR_paid" } @{ $item->{link_split} })) { + push(@AR_paid_values, $item->{accno}); + $AR_paid_labels{$item->{accno}} = + "$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 eq $item->{id}); + push(@taxchart_values, $key); + $taxchart_labels{$key} = + "$item->{taxdescription} " . ($item->{rate} * 100) . ' %'; + $taxcharts{$item->{id}} = $item; + } + $form->{fokus} = "arledger.customer"; # use JavaScript Calendar or not - $form->{jsscript} = $jscalendar; + $form->{jsscript} = 1; $jsscript = ""; if ($form->{jsscript}) { # with JavaScript Calendar $button1 = qq| - {transdate}> + text('button') - . qq|> + . $locale->text('button') . qq|> |; $button2 = qq| - {duedate}> + text('button') - . qq|> + . $locale->text('button') . qq|> |; #write Trigger @@ -456,15 +424,26 @@ sub form_header { # without JavaScript Calendar $button1 = - qq|{transdate}>|; + qq||; $button2 = - qq|{duedate}>|; + qq||; } - $form->header; + my $follow_up_vc = $form->{customer}; + $follow_up_vc =~ s/--.*?//; + my $follow_up_trans_info = "$form->{invnumber} ($follow_up_vc)"; + $form->{javascript} .= + qq|| . + qq|| . + qq||; + + $form->header; + $onload = qq|focus()|; + $onload .= qq|;setupDateFormat('|. $myconfig{dateformat} .qq|', '|. $locale->text("Falsches Datumsformat!") .qq|')|; + $onload .= qq|;setupPoints('|. $myconfig{numberformat} .qq|', '|. $locale->text("wrongformat") .qq|')|; print qq| - + {script}> @@ -473,6 +452,12 @@ sub form_header { {closedto}> {locked}> + + + + + +| . ($form->{saved_message} ? qq|$form->{saved_message}| : "") . qq| @@ -487,7 +472,7 @@ sub form_header { | . $locale->text('Customer') . qq| - $customer + $customer @@ -540,7 +525,7 @@ sub form_header { | . $locale->text('Due Date') . qq| $button2 - + @@ -548,9 +533,6 @@ sub form_header { $jsscript - - - {rowcount}> @@ -563,53 +545,94 @@ $jsscript | . $locale->text('Tax') . qq| | - . $locale->text('Korrektur') . qq| - | . $locale->text('Taxkey') . qq| | . $locale->text('Project') . qq| |; - - $amount = $locale->text('Amount'); $project = $locale->text('Project'); - for $i (1 .. $form->{rowcount}) { + for my $i (1 .. $form->{rowcount}) { # format amounts - $form->{"amount_$i"} = $form->format_amount(\%myconfig, $form->{"amount_$i"}, 2); + $form->{"amount_$i"} = + $form->format_amount(\%myconfig, $form->{"amount_$i"}, 2); $form->{"tax_$i"} = $form->format_amount(\%myconfig, $form->{"tax_$i"}, 2); - $selectAR_amount = $selectAR_amount_unquoted; - $selectAR_amount =~ s/option value=\"$form->{"AR_amount_$i"}\"/option value=\"$form->{"AR_amount_$i"}\" selected/; - $tax = $taxchart; - $tax_selected = $form->{"taxchart_$i"}; - $tax =~ s/value=\"$tax_selected\"/value=\"$tax_selected\" selected/; - $tax = - qq|$tax|; + + my $selected_accno_full; + my ($accno_row) = split(/--/, $form->{"AR_amount_$i"}); + my $item = $charts{$accno_row}; + $selected_accno_full = "$item->{accno}--$item->{tax_id}"; + + 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_AR_amount_$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}"; + } + + if (!$form->{"taxchart_$i"}) { + if ($form->{"AR_amount_$i"} =~ m/.--./) { + $selected_taxchart = join '--', map { ($_->{id}, $_->{rate}) } first { $_->{id} == $item->{tax_id} } @{ $form->{ALL_TAXCHARTS} }; + } else { + $selected_taxchart = $taxchart_init; + } + } + + $selectAR_amount = + NTI($cgi->popup_menu('-name' => "AR_amount_$i", + '-id' => "AR_amount_$i", + '-style' => 'width:400px', + '-onChange' => "setTaxkey(this, $i)", + '-values' => \@AR_amount_values, + '-labels' => \%AR_amount_labels, + '-default' => $selected_accno_full)) + . $cgi->hidden('-name' => "previous_AR_amount_$i", + '-default' => $selected_accno_full); + + $tax = qq|| . + NTI($cgi->popup_menu('-name' => "taxchart_$i", + '-id' => "taxchart_$i", + '-style' => 'width:200px', + '-values' => \@taxchart_values, + '-labels' => \%taxchart_labels, + '-default' => $selected_taxchart)) + . qq||; + + my $projectnumber = + NTI($cgi->popup_menu('-name' => "project_id_$i", + '-values' => \@project_values, + '-labels' => \%project_labels, + '-default' => $form->{"project_id_$i"} )); print qq| - $selectAR_amount - {"amount_$i"}> - {"tax_$i"}> - + $selectAR_amount + {"amount_$i"}> + $form->{"tax_$i"} $tax - - {"project_id_$i"}> - + $projectnumber |; $amount = ""; $project = ""; } - - - + $form->{invtotal_unformatted} = $form->{invtotal}; $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2); + $ARselected = + NTI($cgi->popup_menu('-name' => "ARselected", '-id' => "ARselected", + '-style' => 'width:400px', + '-values' => \@AR_values, '-labels' => \%AR_labels, + '-default' => $form->{ARselected})); + print qq| @@ -617,8 +640,7 @@ $jsscript - $form->{selectAR} - + ${ARselected} $form->{invtotal} {oldinvtotal}> @@ -647,16 +669,15 @@ $jsscript - | - . $locale->text('Incoming Payments') - . qq| + | + . $locale->text('Incoming Payments') . qq| |; if ($form->{currency} eq $form->{defaultcurrency}) { - @column_index = qw(datepaid source memo paid AR_paid); + @column_index = qw(datepaid source memo paid AR_paid paid_project_id); } else { - @column_index = qw(datepaid source memo paid exchangerate AR_paid); + @column_index = qw(datepaid source memo paid exchangerate AR_paid paid_project_id); } $column_data{datepaid} = "" . $locale->text('Date') . ""; @@ -665,6 +686,7 @@ $jsscript $column_data{AR_paid} = "" . $locale->text('Account') . ""; $column_data{source} = "" . $locale->text('Source') . ""; $column_data{memo} = "" . $locale->text('Memo') . ""; + $column_data{paid_project_id} = "" . $locale->text('Project Number') . ""; print " @@ -674,22 +696,36 @@ $jsscript "; + my @triggers = (); + my $totalpaid = 0; + $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"}); - for $i (1 .. $form->{paidaccounts}) { + for my $i (1 .. $form->{paidaccounts}) { print " "; - $form->{"selectAR_paid_$i"} = $form->{selectAR_paid}; - $form->{"selectAR_paid_$i"} =~ - s/option value=\"$form->{"AR_paid_$i"}\">/option value=\"$form->{"AR_paid_$i"}\" selected>/; + $selectAR_paid = + NTI($cgi->popup_menu('-name' => "AR_paid_$i", + '-id' => "AR_paid_$i", + '-values' => \@AR_paid_values, + '-labels' => \%AR_paid_labels, + '-default' => $form->{"AR_paid_$i"})); + + $totalpaid += $form->{"paid_$i"}; # format amounts - $form->{"paid_$i"} = - $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2); + if ($form->{"paid_$i"}) { + $form->{"paid_$i"} = + $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2); + } $form->{"exchangerate_$i"} = $form->format_amount(\%myconfig, $form->{"exchangerate_$i"}); + if ($form->{"exchangerate_$i"} == 0) { + $form->{"exchangerate_$i"} = ""; + } + $exchangerate = qq| |; if ($form->{currency} ne $form->{defaultcurrency}) { if ($form->{"forex_$i"}) { @@ -706,27 +742,52 @@ $jsscript |; $column_data{paid} = - qq|{"paid_$i"}>|; + qq||; $column_data{AR_paid} = - qq|$form->{"selectAR_paid_$i"}|; + qq|${selectAR_paid}|; $column_data{exchangerate} = qq|$exchangerate|; $column_data{datepaid} = - qq|{"datepaid_$i"}>|; + qq| + |; $column_data{source} = qq||; $column_data{memo} = qq||; + $column_data{paid_project_id} = + qq|| + . NTI($cgi->popup_menu('-name' => "paid_project_id_$i", + '-values' => \@project_values, + '-labels' => \%project_labels, + '-default' => $form->{"paid_project_id_$i"} )) + . qq||; + map { print qq|$column_data{$_}\n| } @column_index; print " "; + push(@triggers, "datepaid_$i", "BL", "trigger_datepaid_$i"); } - map { $form->{$_} =~ s/\"/"/g } qw(selectAR_paid); + + my $paid_missing = $form->{invtotal_unformatted} - $totalpaid; + print qq| + + + + | . $locale->text('Total') . qq| + | . H($form->format_amount(\%myconfig, $totalpaid, 2)) . qq| + + + + + | . $locale->text('Missing amount') . qq| + | . H($form->format_amount(\%myconfig, $paid_missing, 2)) . qq| + +| . $form->write_trigger(\%myconfig, scalar(@triggers) / 3, @triggers) . + qq| {paidaccounts}> - @@ -743,57 +804,91 @@ $jsscript sub form_footer { $lxdebug->enter_sub(); + $auth->assert('general_ledger'); + + my ($transdate, $closedto); + + 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|| . $locale->text("There are #1 unfinished follow-ups of which #2 are due.", scalar @{ $follow_ups }, $num_due) . qq||; + } + } + print qq| - +$follow_ups_block -{path}> -{login}> -{password}> + + + +| +. $cgi->hidden('-name' => 'draft_id', '-default' => [$form->{draft_id}]) +. $cgi->hidden('-name' => 'draft_description', '-default' => [$form->{draft_description}]) +. qq| |; + if (!$form->{id} && $form->{draft_id}) { + print(NTI($cgi->checkbox('-name' => 'remove_draft', '-id' => 'remove_draft', + '-value' => 1, '-checked' => $form->{remove_draft}, + '-label' => '')) . + qq| | . + $locale->text("Remove draft when posting") . + qq||); + } + $transdate = $form->datetonum($form->{transdate}, \%myconfig); $closedto = $form->datetonum($form->{closedto}, \%myconfig); - if ($form->{id} && $form->{radier}) { + print qq|\n|; - print qq| -|; + # ToDO: - insert a global check for stornos, so that a storno is only possible a limited time after saving it + print qq| | + if ($form->{id} && !IS->has_storno(\%myconfig, $form, 'ar') && !IS->is_storno(\%myconfig, $form, 'ar') && (($total_paid == 0) || ($total_paid eq ""))); - if (!$form->{revtrans}) { - if (!$form->{locked}) { - print qq| - - -|; - } + if ($form->{id}) { + if ($form->{radier}) { + print qq| + + |; } - if ($transdate > $closedto) { print qq| - -|; + |; } + print qq| + + |; } else { if ($transdate > $closedto) { - print qq| - |; + print qq| | . + NTI($cgi->submit('-name' => 'action', '-value' => $locale->text('Save draft'), '-class' => 'submit')); } } if ($form->{menubar}) { - require "$form->{path}/menu.pl"; + require "bin/mozilla/menu.pl"; &menubar; } + # button for saving history + if($form->{id} ne "") { + print qq| {id}); name=history id=history value=| . $locale->text('history') . qq|> |; + } + # /button for saving history + # mark_as_paid button + if($form->{id} ne "") { + print qq||; + } + # /mark_as_paid button print " @@ -805,60 +900,51 @@ sub form_footer { $lxdebug->leave_sub(); } -sub update { +sub mark_as_paid { $lxdebug->enter_sub(); - my $display = shift; + $auth->assert('general_ledger'); - # if ($display) { - # goto TAXCALC; - # } + &mark_as_paid_common(\%myconfig,"ar"); - $form->{invtotal} = 0; + $lxdebug->leave_sub(); +} -# $form->{selectAR_amount} = $form->{AR_amount}; -# $form->{selectAR_amount} =~ -# s/value=\"$form->{AR_amountselected}\"/value=\"$form->{AR_amountselected}\" selected/; +sub update { + $lxdebug->enter_sub(); - $form->{selectAR} = $form->{AR}; + $auth->assert('general_ledger'); + + my $display = shift; - $form->{selectAR} =~ - s/value=\"$form->{ARselected}\"/value=\"$form->{ARselected}\" selected/; + my ($totaltax, $exchangerate, $totalpaid); - ($AR_amountaccno, $AR_amounttaxkey) = - split(/--/, $form->{AR_amountselected}); - $form->{selecttaxchart} = $form->{taxchart}; - $form->{selecttaxchart} =~ - s/value=\"$AR_amounttaxkey--([^\"]*)\"/value=\"$AR_amounttaxkey--$1\" selected/; + $form->{invtotal} = 0; - $form->{rate} = $1; + delete @{ $form }{ grep { m/^tax_\d+$/ } keys %{ $form } }; map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate creditlimit creditremaining); - @flds = qw(amount AR_amount projectnumber oldprojectnumber project_id); - $count = 0; - @a = (); + my @flds = qw(amount AR_amount projectnumber oldprojectnumber project_id); + my $count = 0; + my @a = (); - for $i (1 .. $form->{rowcount}) { - $form->{"amount_$i"} = - $form->parse_amount(\%myconfig, $form->{"amount_$i"}); - $form->{"tax_$i"} = - $form->parse_amount(\%myconfig, $form->{"tax_$i"}); + 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"}); if ($form->{"amount_$i"}) { push @a, {}; - $j = $#a; - if (!$form->{"korrektur_$i"}) { - ($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; - } + my $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"} = 0; + $form->{"tax_$i"} = $form->{"amount_$i"} * $rate; } + } else { + $form->{"tax_$i"} = 0; } $form->{"tax_$i"} = $form->round_amount($form->{"tax_$i"}, 2); @@ -872,27 +958,29 @@ sub update { $form->{rowcount} = $count + 1; map { $form->{invtotal} += $form->{"amount_$_"} } (1 .. $form->{rowcount}); - $form->{exchangerate} = $exchangerate - if ( - $form->{forex} = ( - $exchangerate = - $form->check_exchangerate( - \%myconfig, $form->{currency}, $form->{transdate}, 'buy' - ))); + $form->{forex} = $form->check_exchangerate( \%myconfig, $form->{currency}, $form->{transdate}, 'buy'); + $form->{exchangerate} = $form->{forex} if $form->{forex}; + + $form->{invdate} = $form->{transdate}; $form->{invdate} = $form->{transdate}; - $save_AR = $form->{AR}; - &check_name(customer); - $form->{AR} = $save_AR; - &check_project; + my %saved_variables = map +( $_ => $form->{$_} ), qw(AR AR_amount_1 taxchart_1); + &check_name("customer"); + + $form->{AR} = $saved_variables{AR}; + if ($saved_variables{AR_amount_1} =~ m/.--./) { + map { $form->{$_} = $saved_variables{$_} } qw(AR_amount_1 taxchart_1); + } else { + delete $form->{taxchart_1}; + } $form->{invtotal} = ($form->{taxincluded}) ? $form->{invtotal} : $form->{invtotal} + $totaltax; - for $i (1 .. $form->{paidaccounts}) { - if ($form->{"paid_$i"}) { + for my $i (1 .. $form->{paidaccounts}) { + if ($form->parse_amount(\%myconfig, $form->{"paid_$i"})) { map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) @@ -900,13 +988,8 @@ sub update { $totalpaid += $form->{"paid_$i"}; - $form->{"exchangerate_$i"} = $exchangerate - if ( - $form->{"forex_$i"} = ( - $exchangerate = - $form->check_exchangerate( - \%myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'buy' - ))); + $form->{"forex_$i"} = $form->check_exchangerate( \%myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'buy'); + $form->{"exchangerate_$i"} = $form->{"forex_$i"} if $form->{"forex_$i"}; } } @@ -921,65 +1004,114 @@ sub update { $lxdebug->leave_sub(); } +# +# ToDO: fix $closedto and $invdate +# +sub post_payment { + $lxdebug->enter_sub(); + + $auth->assert('general_ledger'); + + $form->{defaultcurrency} = $form->get_default_currency(\%myconfig); + + for my $i (1 .. $form->{paidaccounts}) { + + if ($form->parse_amount(\%myconfig, $form->{"paid_$i"})) { + my $datepaid = $form->datetonum($form->{"datepaid_$i"}, \%myconfig); + + $form->isblank("datepaid_$i", $locale->text('Payment date missing!')); + + $form->error($locale->text('Cannot post payment for a closed period!')) if ($form->date_closed($form->{"datepaid_$i"}, \%myconfig)); + + if ($form->{currency} ne $form->{defaultcurrency}) { +# $form->{"exchangerate_$i"} = $form->{exchangerate} if ($invdate == $datepaid); + $form->isblank("exchangerate_$i", $locale->text('Exchangerate for payment missing!')); + } + } + } + + ($form->{AR}) = split /--/, $form->{AR}; + ($form->{AR_paid}) = split /--/, $form->{AR_paid}; + $form->redirect($locale->text('Payment posted!')) if (AR->post_payment(\%myconfig, \%$form)); + $form->error($locale->text('Cannot post payment!')); + + $lxdebug->leave_sub(); +} + +sub _post { + + $auth->assert('general_ledger'); + + # inline post + post(1); +} + sub post { $lxdebug->enter_sub(); + $auth->assert('general_ledger'); + + my ($inline) = @_; + + my ($datepaid); + # 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!')); - $closedto = $form->datetonum($form->{closedto}, \%myconfig); - $transdate = $form->datetonum($form->{transdate}, \%myconfig); + my $closedto = $form->datetonum($form->{closedto}, \%myconfig); + my $transdate = $form->datetonum($form->{transdate}, \%myconfig); + $form->error($locale->text('Cannot post transaction for a closed period!')) if ($form->date_closed($form->{"transdate"}, \%myconfig)); - $form->error($locale->text('Cannot post transaction for a closed period!')) - if ($transdate <= $closedto); + $form->error($locale->text('Zero amount posting!')) + unless grep $_*1, map $form->parse_amount(\%myconfig, $form->{"amount_$_"}), 1..$form->{rowcount}; $form->isblank("exchangerate", $locale->text('Exchangerate missing!')) if ($form->{currency} ne $form->{defaultcurrency}); delete($form->{AR}); - for $i (1 .. $form->{paidaccounts}) { - if ($form->{"paid_$i"}) { + for my $i (1 .. $form->{paidaccounts}) { + if ($form->parse_amount(\%myconfig, $form->{"paid_$i"})) { $datepaid = $form->datetonum($form->{"datepaid_$i"}, \%myconfig); $form->isblank("datepaid_$i", $locale->text('Payment date missing!')); $form->error($locale->text('Cannot post payment for a closed period!')) - if ($datepaid <= $closedto); + if ($form->date_closed($form->{"datepaid_$i"}, \%myconfig)); if ($form->{currency} ne $form->{defaultcurrency}) { - $form->{"exchangerate_$i"} = $form->{exchangerate} - if ($transdate == $datepaid); - $form->isblank("exchangerate_$i", - $locale->text('Exchangerate for payment missing!')); + $form->{"exchangerate_$i"} = $form->{exchangerate} if ($transdate == $datepaid); + $form->isblank("exchangerate_$i", $locale->text('Exchangerate for payment missing!')); } } } # if oldcustomer ne customer redo form - ($customer) = split /--/, $form->{customer}; + my ($customer) = split /--/, $form->{customer}; if ($form->{oldcustomer} ne "$customer--$form->{customer_id}") { - &update; + update(); exit; } - ($creditaccno, $credittaxkey) = split /--/, $form->{AR_amountselected}; - ($taxkey, $NULL) = split /--/, $form->{taxchartselected}; - ($receivablesaccno, $payablestaxkey) = split /--/, $form->{ARselected}; - $form->{AR}{amount_1} = $creditaccno; - $form->{AR}{receivables} = $receivablesaccno; - $form->{taxkey} = $taxkey; - - $form->{invnumber} = $form->update_defaults(\%myconfig, "invnumber") - unless $form->{invnumber}; + $form->{AR}{receivables} = $form->{ARselected}; + $form->{storno} = 0; + $lxdebug->message(0, $form->{amount}); $form->{id} = 0 if $form->{postasnew}; + $form->error($locale->text('Cannot post transaction!')) unless AR->post_transaction(\%myconfig, \%$form); - $form->redirect($locale->text('Transaction posted!')) - if (AR->post_transaction(\%myconfig, \%$form)); - $form->error($locale->text('Cannot post transaction!')); + # saving the history + if(!exists $form->{addition} && $form->{id} ne "") { + $form->{snumbers} = "invnumber_$form->{invnumber}"; + $form->{addition} = "POSTED"; + $form->save_history($form->dbconnect(\%myconfig)); + } + # /saving the history + remove_draft() if $form->{remove_draft}; + + $form->redirect($locale->text('Transaction posted!')) unless $inline; $lxdebug->leave_sub(); } @@ -987,15 +1119,40 @@ sub post { sub post_as_new { $lxdebug->enter_sub(); + $auth->assert('general_ledger'); + $form->{postasnew} = 1; + # saving the history + if(!exists $form->{addition} && $form->{id} ne "") { + $form->{snumbers} = qq|invnumber_| . $form->{invnumber}; + $form->{addition} = "POSTED AS NEW"; + $form->save_history($form->dbconnect(\%myconfig)); + } + # /saving the history &post; $lxdebug->leave_sub(); } +sub use_as_template { + $lxdebug->enter_sub(); + + $auth->assert('general_ledger'); + + map { delete $form->{$_} } qw(printed emailed queued invnumber invdate deliverydate id datepaid_1 source_1 memo_1 paid_1 exchangerate_1 AP_paid_1 storno); + $form->{paidaccounts} = 1; + $form->{rowcount}--; + $form->{invdate} = $form->current_date(\%myconfig); + &update; + + $lxdebug->leave_sub(); +} + sub delete { $lxdebug->enter_sub(); + $auth->assert('general_ledger'); + $form->{title} = $locale->text('Confirm!'); $form->header; @@ -1008,7 +1165,8 @@ sub delete { {script}> |; - foreach $key (keys %$form) { + foreach my $key (keys %$form) { + next if (($key eq 'login') || ($key eq 'password') || ('' ne ref $form->{$key})); $form->{$key} =~ s/\"/"/g; print qq|\n|; } @@ -1034,8 +1192,18 @@ sub delete { sub yes { $lxdebug->enter_sub(); - $form->redirect($locale->text('Transaction deleted!')) - if (AR->delete_transaction(\%myconfig, \%$form, $spool)); + $auth->assert('general_ledger'); + + if (AR->delete_transaction(\%myconfig, \%$form)) { + # saving the history + if(!exists $form->{addition}) { + $form->{snumbers} = qq|invnumber_| . $form->{invnumber}; + $form->{addition} = "DELETED"; + $form->save_history($form->dbconnect(\%myconfig)); + } + # /saving the history + $form->redirect($locale->text('Transaction deleted!')); + } $form->error($locale->text('Cannot delete transaction!')); $lxdebug->leave_sub(); @@ -1044,6 +1212,11 @@ sub yes { sub search { $lxdebug->enter_sub(); + $auth->assert('general_ledger | invoice_edit'); + + my ($customer, $department); + my ($jsscript, $button1, $button2, $onload); + # setup customer selection $form->all_vc(\%myconfig, "customer", "AR"); @@ -1074,23 +1247,23 @@ sub search { $form->{title} = $locale->text('AR Transactions'); + $form->{javascript} .= qq||; + # use JavaScript Calendar or not - $form->{jsscript} = $jscalendar; + $form->{jsscript} = 1; $jsscript = ""; if ($form->{jsscript}) { # with JavaScript Calendar $button1 = qq| - + text('button') - . qq|> + . $locale->text('button') . qq|> |; $button2 = qq| - + text('button') - . qq|> + . $locale->text('button') . qq|> |; #write Trigger @@ -1101,16 +1274,31 @@ sub search { # without JavaScript Calendar $button1 = qq| - |; + |; $button2 = qq| - |; + |; } + $form->get_lists("projects" => { "key" => "ALL_PROJECTS", + "all" => 1 }); + + my %labels = (); + my @values = (""); + foreach my $item (@{ $form->{"ALL_PROJECTS"} }) { + push(@values, $item->{"id"}); + $labels{$item->{"id"}} = $item->{"projectnumber"}; + } + my $projectnumber = + NTI($cgi->popup_menu('-name' => 'project_id', '-values' => \@values, + '-labels' => \%labels)); + $form->{fokus} = "search.customer"; $form->header; - + $onload = qq|focus()|; + $onload .= qq|;setupDateFormat('|. $myconfig{dateformat} .qq|', '|. $locale->text("Falsches Datumsformat!") .qq|')|; + $onload .= qq|;setupPoints('|. $myconfig{numberformat} .qq|', '|. $locale->text("wrongformat") .qq|')|; print qq| - + {script}> @@ -1133,10 +1321,18 @@ sub search { | . $locale->text('Order Number') . qq| + + | . $locale->text('Transaction description') . qq| + + | . $locale->text('Notes') . qq| + + | . $locale->text("Project Number") . qq| + $projectnumber + | . $locale->text('From') . qq| $button1 @@ -1193,17 +1389,49 @@ sub search { | . $locale->text('Notes') . qq| - + | . $locale->text('Salesperson') . qq| | . $locale->text('Shipping Point') . qq| | . $locale->text('Ship via') . qq| + + + | . $locale->text('Ertrag') . qq| + + | . $locale->text('Ertrag prozentual') . qq| + + | . $locale->text('Employee') . qq| + | . $locale->text('Subtotal') . qq| + + | . $locale->text('Project Number') . qq| + + | . $locale->text('Transaction description') . qq| + + | . $locale->text('Customer') . qq| + + + + | . $locale->text('Customer Number') . qq| + + | . $locale->text('Country') . qq| + + | . $locale->text('USt-IdNr.') . qq| + + | . $locale->text('Steuersatz') . qq| + + + + | . $locale->text('Payment Terms') . qq| + + | . $locale->text('Buchungskonto') . qq| + + @@ -1217,10 +1445,6 @@ sub search { {nextsub}> -{path}> -{login}> -{password}> - @@ -1237,360 +1461,231 @@ $jsscript $lxdebug->leave_sub(); } +sub create_subtotal_row { + $lxdebug->enter_sub(); + + my ($totals, $columns, $column_alignment, $subtotal_columns, $class) = @_; + + my $row = { map { $_ => { 'data' => '', 'class' => $class, 'align' => $column_alignment->{$_}, } } @{ $columns } }; + + map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, 2) } @{ $subtotal_columns }; + + $row->{tax}->{data} = $form->format_amount(\%myconfig, $totals->{amount} - $totals->{netamount}, 2); + + map { $totals->{$_} = 0 } @{ $subtotal_columns }; + + $lxdebug->leave_sub(); + + return $row; +} + sub ar_transactions { $lxdebug->enter_sub(); + $auth->assert('general_ledger | invoice_edit'); + + my ($callback, $href, @columns); + $form->{customer} = $form->unescape($form->{customer}); ($form->{customer}, $form->{customer_id}) = split(/--/, $form->{customer}); + report_generator_set_default_sort('transdate', 1); + AR->ar_transactions(\%myconfig, \%$form); - $callback = - "$form->{script}?action=ar_transactions&path=$form->{path}&login=$form->{login}&password=$form->{password}"; - $href = $callback; + $form->{title} = $locale->text('AR Transactions'); + + my $report = SL::ReportGenerator->new(\%myconfig, $form); + + @columns = + qw(transdate id type invnumber ordnumber name netamount tax amount paid + datepaid due duedate transaction_description notes salesman employee shippingpoint shipvia + marge_total marge_percent globalprojectnumber customernumber country ustid taxzone payment_terms charts); + + my @hidden_variables = map { "l_${_}" } @columns; + push @hidden_variables, "l_subtotal", qw(open closed customer invnumber ordnumber transaction_description notes project_id transdatefrom transdateto); + + $href = build_std_url('action=ar_transactions', grep { $form->{$_} } @hidden_variables); + + my %column_defs = ( + 'transdate' => { 'text' => $locale->text('Date'), }, + 'id' => { 'text' => $locale->text('ID'), }, + 'type' => { 'text' => $locale->text('Type'), }, + 'invnumber' => { 'text' => $locale->text('Invoice'), }, + 'ordnumber' => { 'text' => $locale->text('Order'), }, + 'name' => { 'text' => $locale->text('Customer'), }, + 'netamount' => { 'text' => $locale->text('Amount'), }, + 'tax' => { 'text' => $locale->text('Tax'), }, + 'amount' => { 'text' => $locale->text('Total'), }, + 'paid' => { 'text' => $locale->text('Paid'), }, + 'datepaid' => { 'text' => $locale->text('Date Paid'), }, + 'due' => { 'text' => $locale->text('Amount Due'), }, + 'duedate' => { 'text' => $locale->text('Due Date'), }, + 'transaction_description' => { 'text' => $locale->text('Transaction description'), }, + 'notes' => { 'text' => $locale->text('Notes'), }, + 'salesman' => { 'text' => $locale->text('Salesperson'), }, + 'employee' => { 'text' => $locale->text('Employee'), }, + 'shippingpoint' => { 'text' => $locale->text('Shipping Point'), }, + 'shipvia' => { 'text' => $locale->text('Ship via'), }, + 'globalprojectnumber' => { 'text' => $locale->text('Project Number'), }, + 'marge_total' => { 'text' => $locale->text('Ertrag'), }, + 'marge_percent' => { 'text' => $locale->text('Ertrag prozentual'), }, + 'customernumber' => { 'text' => $locale->text('Customer Number'), }, + 'country' => { 'text' => $locale->text('Country'), }, + 'ustid' => { 'text' => $locale->text('USt-IdNr.'), }, + 'taxzone' => { 'text' => $locale->text('Steuersatz'), }, + 'payment_terms' => { 'text' => $locale->text('Payment Terms'), }, + 'charts' => { 'text' => $locale->text('Buchungskonto'), }, + ); + + foreach my $name (qw(id transdate duedate invnumber ordnumber name datepaid employee shippingpoint shipvia transaction_description)) { + my $sortdir = $form->{sort} eq $name ? 1 - $form->{sortdir} : $form->{sortdir}; + $column_defs{$name}->{link} = $href . "&sort=$name&sortdir=$sortdir"; + } + + my %column_alignment = map { $_ => 'right' } qw(netamount tax amount paid due); + $form->{"l_type"} = "Y"; + map { $column_defs{$_}->{visible} = $form->{"l_${_}"} ? 1 : 0 } @columns; + + $report->set_columns(%column_defs); + $report->set_column_order(@columns); + + $report->set_export_options('ar_transactions', @hidden_variables, qw(sort sortdir)); + + $report->set_sort_indicator($form->{sort}, $form->{sortdir}); + + my @options; if ($form->{customer}) { - $callback .= "&customer=" . $form->escape($form->{customer}, 1); - $href .= "&customer=" . $form->escape($form->{customer}); - $option = $locale->text('Customer') . " : $form->{customer}"; + push @options, $locale->text('Customer') . " : $form->{customer}"; } if ($form->{department}) { - $callback .= "&department=" . $form->escape($form->{department}, 1); - $href .= "&department=" . $form->escape($form->{department}); - ($department) = split /--/, $form->{department}; - $option .= "\n" if ($option); - $option .= $locale->text('Department') . " : $department"; + my ($department) = split /--/, $form->{department}; + push @options, $locale->text('Department') . " : $department"; } if ($form->{invnumber}) { - $callback .= "&invnumber=" . $form->escape($form->{invnumber}, 1); - $href .= "&invnumber=" . $form->escape($form->{invnumber}); - $option .= "\n" if ($option); - $option .= $locale->text('Invoice Number') . " : $form->{invnumber}"; + push @options, $locale->text('Invoice Number') . " : $form->{invnumber}"; } if ($form->{ordnumber}) { - $callback .= "&ordnumber=" . $form->escape($form->{ordnumber}, 1); - $href .= "&ordnumber=" . $form->escape($form->{ordnumber}); - $option .= "\n" if ($option); - $option .= $locale->text('Order Number') . " : $form->{ordnumber}"; + push @options, $locale->text('Order Number') . " : $form->{ordnumber}"; } if ($form->{notes}) { - $callback .= "¬es=" . $form->escape($form->{notes}, 1); - $href .= "¬es=" . $form->escape($form->{notes}); - $option .= "\n" if $option; - $option .= $locale->text('Notes') . " : $form->{notes}"; + push @options, $locale->text('Notes') . " : $form->{notes}"; + } + if ($form->{transaction_description}) { + push @options, $locale->text('Transaction description') . " : $form->{transaction_description}"; } - if ($form->{transdatefrom}) { - $callback .= "&transdatefrom=$form->{transdatefrom}"; - $href .= "&transdatefrom=$form->{transdatefrom}"; - $option .= "\n" if ($option); - $option .= - $locale->text('From') . " " - . $locale->date(\%myconfig, $form->{transdatefrom}, 1); + push @options, $locale->text('From') . " " . $locale->date(\%myconfig, $form->{transdatefrom}, 1); } if ($form->{transdateto}) { - $callback .= "&transdateto=$form->{transdateto}"; - $href .= "&transdateto=$form->{transdateto}"; - $option .= "\n" if ($option); - $option .= - $locale->text('Bis') . " " - . $locale->date(\%myconfig, $form->{transdateto}, 1); + push @options, $locale->text('Bis') . " " . $locale->date(\%myconfig, $form->{transdateto}, 1); } if ($form->{open}) { - $callback .= "&open=$form->{open}"; - $href .= "&open=$form->{open}"; - $option .= "\n" if ($option); - $option .= $locale->text('Open'); + push @options, $locale->text('Open'); } if ($form->{closed}) { - $callback .= "&closed=$form->{closed}"; - $href .= "&closed=$form->{closed}"; - $option .= "\n" if ($option); - $option .= $locale->text('Closed'); + push @options, $locale->text('Closed'); } - @columns = - $form->sort_columns( - qw(transdate id invnumber ordnumber name netamount tax amount paid datepaid due duedate notes employee shippingpoint shipvia) + $report->set_options('top_info_text' => join("\n", @options), + 'raw_bottom_info_text' => $form->parse_html_template('ar/ar_transactions_bottom'), + 'output_format' => 'HTML', + 'title' => $form->{title}, + 'attachment_basename' => $locale->text('invoice_list') . strftime('_%Y%m%d', localtime time), ); - - foreach $item (@columns) { - if ($form->{"l_$item"} eq "Y") { - push @column_index, $item; - - # add column to href and callback - $callback .= "&l_$item=Y"; - $href .= "&l_$item=Y"; - } - } - - if ($form->{l_subtotal} eq 'Y') { - $callback .= "&l_subtotal=Y"; - $href .= "&l_subtotal=Y"; - } - - $column_header{id} = - "" - . $locale->text('ID') - . ""; - $column_header{transdate} = - "" - . $locale->text('Date') - . ""; - $column_header{duedate} = - "" - . $locale->text('Due Date') - . ""; - $column_header{invnumber} = - "" - . $locale->text('Invoice') - . ""; - $column_header{ordnumber} = - "" - . $locale->text('Order') - . ""; - $column_header{name} = - "" - . $locale->text('Customer') - . ""; - $column_header{netamount} = - "" . $locale->text('Amount') . ""; - $column_header{tax} = - "" . $locale->text('Tax') . ""; - $column_header{amount} = - "" . $locale->text('Total') . ""; - $column_header{paid} = - "" . $locale->text('Paid') . ""; - $column_header{datepaid} = - "" - . $locale->text('Date Paid') - . ""; - $column_header{due} = - "" . $locale->text('Amount Due') . ""; - $column_header{notes} = - "" . $locale->text('Notes') . ""; - $column_header{employee} = - "" - . $locale->text('Salesperson') . ""; - - $column_header{shippingpoint} = - "" - . $locale->text('Shipping Point') - . ""; - $column_header{shipvia} = - "" - . $locale->text('Ship via') - . ""; - - $form->{title} = $locale->text('AR Transactions'); - - $form->header; - - print qq| - - - - - $form->{title} - - - - $option - - - - - -|; - - map { print "\n$column_header{$_}" } @column_index; - - print qq| - -|; + $report->set_options_from_form(); # add sort and escape callback, this one we use for the add sub - $form->{callback} = $callback .= "&sort=$form->{sort}"; + $form->{callback} = $href .= "&sort=$form->{sort}"; # escape callback for href - $callback = $form->escape($callback); + $callback = $form->escape($href); - if (@{ $form->{AR} }) { - $sameitem = $form->{AR}->[0]->{ $form->{sort} }; - } + my @subtotal_columns = qw(netamount amount paid due marge_total marge_percent); - # sums and tax on reports by Antonio Gallardo - # - foreach $ar (@{ $form->{AR} }) { + my %totals = map { $_ => 0 } @subtotal_columns; + my %subtotals = map { $_ => 0 } @subtotal_columns; - if ($form->{l_subtotal} eq 'Y') { - if ($sameitem ne $ar->{ $form->{sort} }) { - &ar_subtotal; - } - } + my $idx = 0; - $column_data{netamount} = - "" - . $form->format_amount(\%myconfig, $ar->{netamount}, 2, " ") - . ""; - $column_data{tax} = "" - . $form->format_amount(\%myconfig, $ar->{amount} - $ar->{netamount}, - 2, " ") - . ""; - $column_data{amount} = - "" - . $form->format_amount(\%myconfig, $ar->{amount}, 2, " ") . ""; - $column_data{paid} = - "" - . $form->format_amount(\%myconfig, $ar->{paid}, 2, " ") . ""; - $column_data{due} = "" - . $form->format_amount(\%myconfig, $ar->{amount} - $ar->{paid}, - 2, " ") - . ""; - - $subtotalnetamount += $ar->{netamount}; - $subtotalamount += $ar->{amount}; - $subtotalpaid += $ar->{paid}; - $subtotaldue += $ar->{amount} - $ar->{paid}; - - $totalnetamount += $ar->{netamount}; - $totalamount += $ar->{amount}; - $totalpaid += $ar->{paid}; - $totaldue += ($ar->{amount} - $ar->{paid}); - - $column_data{transdate} = "$ar->{transdate} "; - $column_data{id} = "$ar->{id}"; - $column_data{datepaid} = "$ar->{datepaid} "; - $column_data{duedate} = "$ar->{duedate} "; - - $module = ($ar->{invoice}) ? "is.pl" : $form->{script}; - - $column_data{invnumber} = - "{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ar->{invnumber}"; - $column_data{ordnumber} = "$ar->{ordnumber} "; - $column_data{name} = "$ar->{name}"; - $ar->{notes} =~ s/\r\n//g; - $column_data{notes} = "$ar->{notes} "; - $column_data{shippingpoint} = "$ar->{shippingpoint} "; - $column_data{shipvia} = "$ar->{shipvia} "; - $column_data{employee} = "$ar->{employee} "; - - $i++; - $i %= 2; - print " - -"; + foreach my $ar (@{ $form->{AR} }) { + $ar->{tax} = $ar->{amount} - $ar->{netamount}; + $ar->{due} = $ar->{amount} - $ar->{paid}; - map { print "\n$column_data{$_}" } @column_index; + map { $subtotals{$_} += $ar->{$_}; + $totals{$_} += $ar->{$_} } @subtotal_columns; - print qq| - -|; + $subtotals{marge_percent} = $subtotals{netamount} ? ($subtotals{marge_total} * 100 / $subtotals{netamount}) : 0; + $totals{marge_percent} = $totals{netamount} ? ($totals{marge_total} * 100 / $totals{netamount} ) : 0; - } + map { $ar->{$_} = $form->format_amount(\%myconfig, $ar->{$_}, 2) } qw(netamount tax amount paid due marge_total marge_percent); - if ($form->{l_subtotal} eq 'Y') { - &ar_subtotal; - } + my $is_storno = $ar->{storno} && $ar->{storno_id}; + my $has_storno = $ar->{storno} && !$ar->{storno_id}; - # print totals - print qq| - -|; + $ar->{type} = + $has_storno ? $locale->text("Invoice with Storno (abbreviation)") : + $is_storno ? $locale->text("Storno (one letter abbreviation)") : + $ar->{amount} < 0 ? $locale->text("Credit note (one letter abbreviation)") : + $ar->{invoice} ? $locale->text("Invoice (one letter abbreviation)") : + $locale->text("AR Transaction (abbreviation)"); - map { $column_data{$_} = " " } @column_index; - - $column_data{netamount} = - "" - . $form->format_amount(\%myconfig, $totalnetamount, 2, " ") . ""; - $column_data{tax} = "" - . $form->format_amount(\%myconfig, $totalamount - $totalnetamount, - 2, " ") - . ""; - $column_data{amount} = - "" - . $form->format_amount(\%myconfig, $totalamount, 2, " ") . ""; - $column_data{paid} = - "" - . $form->format_amount(\%myconfig, $totalpaid, 2, " ") . ""; - $column_data{due} = - "" - . $form->format_amount(\%myconfig, $totaldue, 2, " ") . ""; - - map { print "\n$column_data{$_}" } @column_index; + my $row = { }; - print qq| - - - - - - - - + foreach my $column (@columns) { + $row->{$column} = { + 'data' => $ar->{$column}, + 'align' => $column_alignment{$column}, + }; + } - -{script}> + $row->{invnumber}->{link} = build_std_url("script=" . ($ar->{invoice} ? 'is.pl' : 'ar.pl'), 'action=edit') + . "&id=" . E($ar->{id}) . "&callback=${callback}"; - + my $row_set = [ $row ]; -{path}> -{login}> -{password}> + if (($form->{l_subtotal} eq 'Y') + && (($idx == (scalar @{ $form->{AR} } - 1)) + || ($ar->{ $form->{sort} } ne $form->{AR}->[$idx + 1]->{ $form->{sort} }))) { + push @{ $row_set }, create_subtotal_row(\%subtotals, \@columns, \%column_alignment, \@subtotal_columns, 'listsubtotal'); + } - -|; + $report->add_data($row_set); - if ($form->{menubar}) { - require "$form->{path}/menu.pl"; - &menubar; + $idx++; } - print qq| - + $report->add_separator(); + $report->add_data(create_subtotal_row(\%totals, \@columns, \%column_alignment, \@subtotal_columns, 'listtotal')); - - -|; + $report->generate_with_headers(); $lxdebug->leave_sub(); } -sub ar_subtotal { +sub storno { $lxdebug->enter_sub(); - map { $column_data{$_} = " " } @column_index; - - $column_data{tax} = "" - . $form->format_amount(\%myconfig, $subtotalamount - $subtotalnetamount, - 2, " ") - . ""; - $column_data{amount} = - "" - . $form->format_amount(\%myconfig, $subtotalamount, 2, " ") . ""; - $column_data{paid} = - "" - . $form->format_amount(\%myconfig, $subtotalpaid, 2, " ") . ""; - $column_data{due} = - "" - . $form->format_amount(\%myconfig, $subtotaldue, 2, " ") . ""; - - $subtotalnetamount = 0; - $subtotalamount = 0; - $subtotalpaid = 0; - $subtotaldue = 0; + $auth->assert('general_ledger'); - $sameitem = $ar->{ $form->{sort} }; + # don't cancel cancelled transactions + if (IS->has_storno(\%myconfig, $form, 'ar')) { + $form->{title} = $locale->text("Cancel Accounts Receivables Transaction"); + $form->error($locale->text("Transaction has already been cancelled!")); + } - print ""; + AR->storno($form, \%myconfig, $form->{id}); - map { print "\n$column_data{$_}" } @column_index; + # saving the history + if(!exists $form->{addition} && $form->{id} ne "") { + $form->{snumbers} = "ordnumber_$form->{ordnumber}"; + $form->{addition} = "STORNO"; + $form->save_history($form->dbconnect(\%myconfig)); + } + # /saving the history - print " - -"; + $form->redirect(sprintf $locale->text("Transaction %d cancelled."), $form->{storno_id}); $lxdebug->leave_sub(); }
$form->{saved_message}
| . $locale->text("There are #1 unfinished follow-ups of which #2 are due.", scalar @{ $follow_ups }, $num_due) . qq|