X-Git-Url: http://wagnertech.de/gitweb/gitweb.cgi/mfinanz.git/blobdiff_plain/ff159a4d47b9a2d10744dcfc23da2c63605c8a32..eeb5375ee7727c956cc357cc8f90b19d1bfe80b9:/SL/IR.pm diff --git a/SL/IR.pm b/SL/IR.pm index 3d8ee3637..f27f6696a 100644 --- a/SL/IR.pm +++ b/SL/IR.pm @@ -40,16 +40,19 @@ use SL::ARAP; use SL::Common; use SL::CVar; use SL::DATEV qw(:CONSTANTS); +use SL::Util qw(trim); use SL::DBUtils; use SL::DB::Draft; use SL::DO; use SL::GenericTranslations; use SL::HTML::Restrict; use SL::IO; +use SL::Locale::String qw(t8); use SL::MoreCommon; use SL::DB::Default; use SL::DB::TaxZone; use SL::DB::MakeModel; +use SL::DB::ValidityToken; use SL::DB; use SL::Presenter::Part qw(type_abbreviation classification_abbreviation); use List::Util qw(min); @@ -72,6 +75,16 @@ sub post_invoice { sub _post_invoice { my ($self, $myconfig, $form, $provided_dbh, %params) = @_; + my $validity_token; + if (!$form->{id}) { + $validity_token = SL::DB::Manager::ValidityToken->fetch_valid_token( + scope => SL::DB::ValidityToken::SCOPE_PURCHASE_INVOICE_POST(), + token => $form->{form_validity_token}, + ); + + die $::locale->text('The form is not valid anymore.') if !$validity_token; + } + my $payments_only = $params{payments_only}; my $dbh = $provided_dbh || SL::DB->client->dbh; my $restricter = SL::HTML::Restrict->create; @@ -84,14 +97,14 @@ sub _post_invoice { my ($query, $sth, @values, $project_id); my ($allocated, $taxrate, $taxamount, $taxdiff, $item); - my ($amount, $linetotal, $lastinventoryaccno, $lastexpenseaccno); + my ($amount, $linetotal, $last_inventory_accno_tax_id_key, $last_expense_accno_tax_id_key); my ($netamount, $invoicediff, $expensediff) = (0, 0, 0); my $exchangerate = 0; my ($basefactor, $baseqty, @taxaccounts, $totaltax); my $all_units = AM->retrieve_units($myconfig, $form); -#markierung + #markierung if (!$payments_only) { if ($form->{id}) { &reverse_invoice($dbh, $form); @@ -100,16 +113,25 @@ sub _post_invoice { do_query($form, $dbh, qq|INSERT INTO ap (id, invnumber, currency_id, taxzone_id) VALUES (?, '', (SELECT id FROM currencies WHERE name=?), ?)|, $form->{id}, $form->{currency}, $form->{taxzone_id}); } } - if ($form->{currency} eq $defaultcurrency) { $form->{exchangerate} = 1; } else { - $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{invdate}, 'sell'); + $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{invdate}, 'sell'); + $form->{exchangerate} = $form->parse_amount($myconfig, $form->{exchangerate}, 5); + + # if default exchangerate is not defined, define one + unless ($exchangerate) { + $form->update_exchangerate($dbh, $form->{currency}, $form->{invdate}, 0, $form->{exchangerate}); + # delete records exchangerate -> if user sets new invdate for record + $query = qq|UPDATE ap set exchangerate = NULL where id = ?|; + do_query($form, $dbh, $query, $form->{"id"}); + } + # update record exchangerate, if the default is set and differs from current + if ($exchangerate && ($form->{exchangerate} != $exchangerate)) { + $form->update_exchangerate($dbh, $form->{currency}, $form->{invdate}, + 0, $form->{exchangerate}, $form->{id}, 'ap'); + } } - - $form->{exchangerate} = $exchangerate || $form->parse_amount($myconfig, $form->{exchangerate}); - $form->{exchangerate} = 1 unless ($form->{exchangerate} * 1); - my %item_units; my $q_item_unit = qq|SELECT unit FROM parts WHERE id = ?|; my $h_item_unit = prepare_query($form, $dbh, $q_item_unit); @@ -127,7 +149,10 @@ sub _post_invoice { $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"}); $form->{"qty_$i"} *= -1 if $form->{storno}; - if ( $::instance_conf->get_inventory_system eq 'periodic') { + if ( ($form->{"tax_chart_type_$i"} eq 'expense') + || ($form->{"tax_chart_type_$i"} eq '' + && $::instance_conf->get_inventory_system eq 'periodic') + ) { # inventory account number is overwritten with expense account number, so # never book incoming to inventory account but always to expense account $form->{"inventory_accno_$i"} = $form->{"expense_accno_$i"} @@ -155,6 +180,14 @@ sub _post_invoice { $allocated = 0; $taxrate = 0; + # preset tax_id and accno for all taxaccounts + foreach $item (@taxaccounts) { + my $accno = $item; + my $tax_id = $form->{"${item}_tax_id"}; + $form->{amount}{$item . "_" . $tax_id}{tax_id} = $tax_id; + $form->{amount}{$item . "_" . $tax_id}{accno} = $item; + } + $form->{"sellprice_$i"} = $form->parse_amount($myconfig, $form->{"sellprice_$i"}); (my $fxsellprice = $form->{"sellprice_$i"}) =~ /\.(\d+)/; my $dec = length $1; @@ -192,17 +225,18 @@ sub _post_invoice { foreach $item (@taxaccounts) { $taxamount = $form->round_amount($linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"})), 2); - $taxdiff += $taxamount; - $form->{amount}{ $form->{id} }{$item} -= $taxamount; + $taxdiff += $taxamount; + $form->{amount}{$item . "_" . $form->{"${item}_tax_id"}}{amount} -= $taxamount; } - $form->{amount}{ $form->{id} }{ $taxaccounts[0] } += $taxdiff; + my $first_taxaccno = $taxaccounts[0]; + $form->{amount}{ $first_taxaccno . "_" . $form->{"${first_taxaccno}_tax_id"} }{amount} += $taxdiff; } else { - map { $form->{amount}{ $form->{id} }{$_} -= $linetotal * $form->{"${_}_rate"} } @taxaccounts; + map { $form->{amount}{$_ . "_" . $form->{"${_}_tax_id"}}{amount} -= $linetotal * $form->{"${_}_rate"} } @taxaccounts; } } else { - map { $form->{amount}{ $form->{id} }{$_} -= $taxamount * $form->{"${_}_rate"} / $taxrate } @taxaccounts; + map { $form->{amount}{$_ . "_" . $form->{"${_}_tax_id"}}{amount} -= $taxamount * $form->{"${_}_rate"} / $taxrate } @taxaccounts; } # add purchase to inventory, this one is without the tax! @@ -213,19 +247,26 @@ sub _post_invoice { # this is the difference for the inventory $invoicediff += ($amount - $linetotal); - $form->{amount}{ $form->{id} }{ $form->{"inventory_accno_$i"} } -= $linetotal; + my $inventory_key = $form->{"inventory_accno_$i"} . "_" . $form->{"expense_accno_tax_id_$i"}; + $form->{amount}{$inventory_key}{amount} -= $linetotal; + $form->{amount}{$inventory_key}{accno} = $form->{"inventory_accno_$i"}; + $form->{amount}{$inventory_key}{tax_id} = $form->{"expense_accno_tax_id_$i"}; # adjust and round sellprice $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} * $form->{exchangerate}, $decimalplaces); - $lastinventoryaccno = $form->{"inventory_accno_$i"}; + $last_inventory_accno_tax_id_key = $inventory_key; next if $payments_only; - # update parts table by setting lastcost to current price, don't allow negative values by using abs - $query = qq|UPDATE parts SET lastcost = ? WHERE id = ?|; - @values = (abs($fxsellprice * $form->{exchangerate} / $basefactor), conv_i($form->{"id_$i"})); - do_query($form, $dbh, $query, @values); + # change lastcost for part and all assemblies and assortments recursively + my $a = SL::DB::Part->load_cached(conv_i($form->{"id_$i"})); + my $part_price_factor = $a->price_factor_id ? $a->price_factor->factor : 1; + my $new_lastcost = abs($fxsellprice * $form->{exchangerate} / $basefactor / $price_factor * $part_price_factor); + if ( abs($a->lastcost - $new_lastcost) >= 0.009 ) { + $a->update_attributes(lastcost => $new_lastcost); + $a->set_lastcost_assemblies_and_assortiments; + } # check if we sold the item already and # make an entry for the expense and inventory @@ -352,13 +393,13 @@ sub _post_invoice { foreach $item (@taxaccounts) { $taxamount = $linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"})); $totaltax += $taxamount; - $form->{amount}{ $form->{id} }{$item} -= $taxamount; + $form->{amount}{$item . "_" . $form->{"${item}_tax_id"}}{amount} -= $taxamount; } } else { - map { $form->{amount}{ $form->{id} }{$_} -= $linetotal * $form->{"${_}_rate"} } @taxaccounts; + map { $form->{amount}{$_ . "_" . $form->{"${_}_tax_id"}}{amount} -= $linetotal * $form->{"${_}_rate"} } @taxaccounts; } } else { - map { $form->{amount}{ $form->{id} }{$_} -= $taxamount * $form->{"${_}_rate"} / $taxrate } @taxaccounts; + map { $form->{amount}{$_ . "_" . $form->{"${_}_tax_id"}}{amount} -= $taxamount * $form->{"${_}_rate"} / $taxrate } @taxaccounts; } $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * $form->{exchangerate} / $price_factor; @@ -369,18 +410,26 @@ sub _post_invoice { $expensediff += ($amount - $linetotal); # add amount to expense - $form->{amount}{ $form->{id} }{ $form->{"expense_accno_$i"} } -= $linetotal; + my $expense_key = $form->{"expense_accno_$i"} . "_" . $form->{"expense_accno_tax_id_$i"}; + $form->{amount}{$expense_key}{amount} -= $linetotal; + $form->{amount}{$expense_key}{accno} = $form->{"expense_accno_$i"}; + $form->{amount}{$expense_key}{tax_id} = $form->{"expense_accno_tax_id_$i"}; - $lastexpenseaccno = $form->{"expense_accno_$i"}; + $last_expense_accno_tax_id_key = $expense_key; # adjust and round sellprice $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} * $form->{exchangerate}, $decimalplaces); next if $payments_only; - # update lastcost - $query = qq|UPDATE parts SET lastcost = ? WHERE id = ?|; - do_query($form, $dbh, $query, $form->{"sellprice_$i"} / $basefactor, conv_i($form->{"id_$i"})); + # change lastcost for part and all assemblies and assortments recursively + my $a = SL::DB::Part->load_cached(conv_i($form->{"id_$i"})); + my $part_price_factor = $a->price_factor_id ? $a->price_factor->factor : 1; + my $new_lastcost = abs($fxsellprice * $form->{exchangerate} / $basefactor / $price_factor * $part_price_factor); + if ( abs($a->lastcost - $new_lastcost) >= 0.009 ) { + $a->update_attributes(lastcost => $new_lastcost); + $a->set_lastcost_assemblies_and_assortiments; + } } next if $payments_only; @@ -410,6 +459,7 @@ sub _post_invoice { project_id = ?, serialnumber = ?, price_factor_id = ?, price_factor = (SELECT factor FROM price_factors WHERE id = ?), marge_price_factor = ?, active_price_source = ?, active_discount_source = ? + ,expense_chart_id = ?, inventory_chart_id = ?, tax_id = ?, tax_chart_type = ? WHERE id = ? SQL @@ -417,9 +467,10 @@ SQL $form->{"description_$i"}, $restricter->process($form->{"longdescription_$i"}), $form->{"qty_$i"} * -1, $baseqty * -1, $form->{"sellprice_$i"}, $fxsellprice, $form->{"discount_$i"}, $allocated, $form->{"unit_$i"}, conv_date($form->{deliverydate}), - conv_i($form->{"project_id_$i"}), $form->{"serialnumber_$i"}, + conv_i($form->{"project_id_$i"}), trim($form->{"serialnumber_$i"}), conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"marge_price_factor_$i"}), $form->{"active_price_source_$i"}, $form->{"active_discount_source_$i"}, + $form->{"expense_chart_id_$i"}, $form->{"inventory_chart_id_$i"}, $form->{"tax_id_$i"}, $form->{"tax_chart_type_$i"}, conv_i($form->{"invoice_id_$i"})); do_query($form, $dbh, $query, @values); push @processed_invoice_ids, $form->{"invoice_id_$i"}; @@ -477,10 +528,11 @@ SQL $netamount = $amount; foreach $item (split / /, $form->{taxaccounts}) { - $amount = $form->{amount}{ $form->{id} }{$item} * $form->{exchangerate}; - $form->{amount}{ $form->{id} }{$item} = $form->round_amount($amount, 2); + my $key = $item . "_" . $form->{"${item}_tax_id"}; + $amount = $form->{amount}{$key}{amount} * $form->{exchangerate}; + $form->{amount}{$key}{amount} = $form->round_amount($amount, 2); - $amount = $form->{amount}{ $form->{id} }{$item} * -1; + $amount = $form->{amount}{$key}{amount} * -1; $tax += $amount; $netamount -= $amount; } @@ -493,33 +545,33 @@ SQL # in the sales invoice case rounding errors only have to be corrected for # income accounts, it is enough to add the total rounding error to one of # the income accounts, with the one assigned to the last row being used - # (lastinventoryaccno) + # (last_inventory_accno_tax_id_key) # in the purchase invoice case rounding errors may be split between # inventory accounts and expense accounts. After rounding, an error of 1 # cent is introduced if the total rounding error exceeds 0.005. The total # error is made up of $invoicediff and $expensediff, however, so if both # values are below 0.005, but add up to a total >= 0.005, correcting - # lastinventoryaccno and lastexpenseaccno separately has no effect after + # last_inventory_accno_tax_id_key and last_expense_accno_tax_id_key separately has no effect after # rounding. This caused bug 1579. Therefore when the combined total exceeds # 0.005, but neither do individually, the account with the larger value # shall receive the total rounding error, and the next time it is rounded # the 1 cent correction will be introduced. - $form->{amount}{ $form->{id} }{$lastinventoryaccno} -= $invoicediff if $lastinventoryaccno; - $form->{amount}{ $form->{id} }{$lastexpenseaccno} -= $expensediff if $lastexpenseaccno; + $form->{amount}{$last_inventory_accno_tax_id_key}{amount} -= $invoicediff if $last_inventory_accno_tax_id_key; + $form->{amount}{$last_expense_accno_tax_id_key}{amount} -= $expensediff if $last_expense_accno_tax_id_key; if ( (abs($expensediff)+abs($invoicediff)) >= 0.005 and abs($expensediff) < 0.005 and abs($invoicediff) < 0.005 ) { # in total the rounding error adds up to 1 cent effectively, correct the # larger of the two numbers - if ( abs($form->{amount}{ $form->{id} }{$lastinventoryaccno}) > abs($form->{amount}{ $form->{id} }{$lastexpenseaccno}) ) { + if ( abs($form->{amount}{$last_inventory_accno_tax_id_key}{amount}) > abs($form->{amount}{$last_expense_accno_tax_id_key}{amount}) ) { # $invoicediff has already been deducted, now also deduct expensediff - $form->{amount}{ $form->{id} }{$lastinventoryaccno} -= $expensediff; + $form->{amount}{$last_inventory_accno_tax_id_key}{amount} -= $expensediff; } else { # expensediff has already been deducted, now also deduct invoicediff - $form->{amount}{ $form->{id} }{$lastexpenseaccno} -= $invoicediff; + $form->{amount}{$last_expense_accno_tax_id_key}{amount} -= $invoicediff; }; }; @@ -529,57 +581,66 @@ SQL $netamount = $amount; foreach my $item (split / /, $form->{taxaccounts}) { - $form->{amount}{ $form->{id} }{$item} = $form->round_amount($form->{amount}{ $form->{id} }{$item}, 2); - $amount = $form->round_amount( $form->{amount}{ $form->{id} }{$item} * $form->{exchangerate} * -1, 2); - $paiddiff += $amount - $form->{amount}{ $form->{id} }{$item} * $form->{exchangerate} * -1; - $form->{amount}{ $form->{id} }{$item} = $form->round_amount($amount * -1, 2); - $amount = $form->{amount}{ $form->{id} }{$item} * -1; - $tax += $amount; + my $key = $item . "_" . $form->{"${item}_tax_id"}; + $form->{amount}{$key}{amount} = $form->round_amount($form->{amount}{$key}{amount}, 2); + $amount = $form->round_amount( $form->{amount}{$key}{amount} * $form->{exchangerate} * -1, 2); + $paiddiff += $amount - $form->{amount}{$key}{amount} * $form->{exchangerate} * -1; + $form->{amount}{$key}{amount} = $form->round_amount($amount * -1, 2); + $amount = $form->{amount}{$key}{amount} * -1; + $tax += $amount; } } - $form->{amount}{ $form->{id} }{ $form->{AP} } = $netamount + $tax; - - - $form->{paid} = $form->round_amount($form->{paid} * $form->{exchangerate} + $paiddiff, 2) if $form->{paid} != 0; - -# update exchangerate - - $form->update_exchangerate($dbh, $form->{currency}, $form->{invdate}, 0, $form->{exchangerate}) - if ($form->{currency} ne $defaultcurrency) && !$exchangerate; - -# record acc_trans transactions + # record acc_trans transactions my $taxdate = $form->{tax_point} || $form->{deliverydate} || $form->{invdate}; - foreach my $trans_id (keys %{ $form->{amount} }) { - foreach my $accno (keys %{ $form->{amount}{$trans_id} }) { - $form->{amount}{$trans_id}{$accno} = $form->round_amount($form->{amount}{$trans_id}{$accno}, 2); + foreach my $accno_tax_id_key (keys %{ $form->{amount} }) { + $form->{amount}{$accno_tax_id_key}{amount} = $form->round_amount($form->{amount}{$accno_tax_id_key}{amount}, 2); + + + next if $payments_only || !$form->{amount}{$accno_tax_id_key}{amount}; + my $amount = $form->{amount}{$accno_tax_id_key}{amount}; + my $accno = $form->{amount}{$accno_tax_id_key}{accno}; + my $tax_id = $form->{amount}{$accno_tax_id_key}{tax_id}; + + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, taxkey, project_id, tax_id, chart_link) + VALUES (?, (SELECT id FROM chart WHERE accno = ?), ?, ?, + (SELECT taxkey + FROM tax + WHERE id = ?), + ?, + ?, + (SELECT link FROM chart WHERE accno = ?))|; + @values = (conv_i($form->{id}), $accno, $amount, + conv_date($form->{invdate}), $tax_id, $project_id, $tax_id, $accno); + do_query($form, $dbh, $query, @values); + } + my $ap_amount = $netamount + $tax; + my $ap_accno = $form->{AP}; + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, taxkey, project_id, tax_id, chart_link) + VALUES (?, (SELECT id FROM chart WHERE accno = ?), ?, ?, + (SELECT taxkey_id + FROM taxkeys + WHERE chart_id= (SELECT id + FROM chart + WHERE accno = ?) + AND startdate <= ? + ORDER BY startdate DESC LIMIT 1), + ?, + (SELECT tax_id + FROM taxkeys + WHERE chart_id= (SELECT id + FROM chart + WHERE accno = ?) + AND startdate <= ? + ORDER BY startdate DESC LIMIT 1), + (SELECT link FROM chart WHERE accno = ?))|; + @values = (conv_i($form->{id}), $ap_accno, $ap_amount, + conv_date($form->{invdate}), $ap_accno, conv_date($taxdate), $project_id, $ap_accno, conv_date($taxdate), $ap_accno); + do_query($form, $dbh, $query, @values) unless $payments_only; - next if $payments_only || !$form->{amount}{$trans_id}{$accno}; - $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, taxkey, project_id, tax_id, chart_link) - VALUES (?, (SELECT id FROM chart WHERE accno = ?), ?, ?, - (SELECT taxkey_id - FROM taxkeys - WHERE chart_id= (SELECT id - FROM chart - WHERE accno = ?) - AND startdate <= ? - ORDER BY startdate DESC LIMIT 1), - ?, - (SELECT tax_id - FROM taxkeys - WHERE chart_id= (SELECT id - FROM chart - WHERE accno = ?) - AND startdate <= ? - ORDER BY startdate DESC LIMIT 1), - (SELECT link FROM chart WHERE accno = ?))|; - @values = ($trans_id, $accno, $form->{amount}{$trans_id}{$accno}, - conv_date($form->{invdate}), $accno, conv_date($taxdate), $project_id, $accno, conv_date($taxdate), $accno); - do_query($form, $dbh, $query, @values); - } - } + $form->{paid} = $form->round_amount($form->{paid} * $form->{exchangerate} + $paiddiff, 2) if $form->{paid} != 0; # deduct payment differences from paiddiff for my $i (1 .. $form->{paidaccounts}) { @@ -591,7 +652,7 @@ SQL # force AP entry if 0 - $form->{amount}{ $form->{id} }{ $form->{AP} } = $form->{paid} if $form->{amount}{$form->{id}}{$form->{AP}} == 0; + $ap_amount = $form->{paid} if $ap_amount == 0; my %already_cleared = %{ $params{already_cleared} // {} }; @@ -619,7 +680,7 @@ SQL : 'f'; # record AP - if ($form->{amount}{ $form->{id} }{ $form->{AP} } != 0) { + if ($ap_amount != 0) { $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, taxkey, project_id, cleared, tax_id, chart_link) VALUES (?, (SELECT id FROM chart WHERE accno = ?), ?, ?, (SELECT taxkey_id @@ -691,7 +752,8 @@ SQL $paiddiff = 0; - # update exchange rate + # update exchange rate for PAYMENTS + $form->{script} = 'ir.pl'; $form->update_exchangerate($dbh, $form->{currency}, $form->{"datepaid_$i"}, 0, $form->{"exchangerate_$i"}) if ($form->{currency} ne $defaultcurrency) && !$exchangerate; } @@ -779,7 +841,8 @@ SQL $form->add_shipto($dbh, $form->{id}, "AP"); # delete zero entries - do_query($form, $dbh, qq|DELETE FROM acc_trans WHERE amount = 0|); + do_query($form, $dbh, qq|DELETE FROM acc_trans WHERE amount = 0 AND trans_id = ?|, $form->{id}); + Common::webdav_folder($form); @@ -845,6 +908,9 @@ SQL } } + $validity_token->delete if $validity_token; + delete $form->{form_validity_token}; + return 1; } @@ -939,12 +1005,6 @@ sub delete_invoice { my @values = (conv_i($form->{id})); - # delete zero entries - # wtf? use case for this? - $query = qq|DELETE FROM acc_trans WHERE amount = 0|; - do_query($form, $dbh, $query); - - my @queries = ( qq|DELETE FROM invoice WHERE trans_id = ?|, qq|DELETE FROM ap WHERE id = ?|, @@ -1014,7 +1074,7 @@ sub retrieve_invoice { $form->{mtime} = $form->{itime} if !$form->{mtime}; $form->{lastmtime} = $form->{mtime}; - $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{invdate}, "sell"); + ($form->{exchangerate}, $form->{record_forex}) = $form->check_exchangerate($myconfig, $form->{currency}, $form->{invdate}, "sell", conv_i($form->{id}), 'ap'); # get shipto $query = qq|SELECT * FROM shipto WHERE (trans_id = ?) AND (module = 'AP')|; @@ -1039,6 +1099,7 @@ sub retrieve_invoice { i.price_factor_id, i.price_factor, i.marge_price_factor, i.discount, i.active_price_source, i.active_discount_source, p.partnumber, p.part_type, pr.projectnumber, pg.partsgroup ,p.classification_id + ,i.expense_chart_id, i.inventory_chart_id, i.tax_id, i.tax_chart_type FROM invoice i JOIN parts p ON (i.parts_id = p.id) @@ -1072,27 +1133,40 @@ sub retrieve_invoice { } # get tax rates and description - my $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $ref->{expense_accno}; - $query = - qq|SELECT c.accno, t.taxdescription, t.rate, t.id as tax_id, - c.accno as taxnumber -- taxnumber is same as accno, but still accessed as taxnumber in code - FROM tax t - LEFT JOIN chart c ON (c.id = t.chart_id) - WHERE t.id in - (SELECT tk.tax_id FROM taxkeys tk - WHERE tk.chart_id = (SELECT id FROM chart WHERE accno = ?) - AND (startdate <= $transdate) - ORDER BY startdate DESC - LIMIT 1) - ORDER BY c.accno|; - my $stw = prepare_execute_query($form, $dbh, $query, $accno_id); - $ref->{taxaccounts} = ""; + my $get_default_tax = $ref->{tax_id} eq '' ? 1 : 0; + my $stw; + if ($get_default_tax) { + my $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $ref->{expense_accno}; + my $query = + qq|SELECT c.accno, t.taxdescription, t.rate, t.id as tax_id, + c.accno as taxnumber -- taxnumber is same as accno, but still accessed as taxnumber in code + FROM tax t + LEFT JOIN chart c ON (c.id = t.chart_id) + WHERE t.id in + (SELECT tk.tax_id FROM taxkeys tk + WHERE tk.chart_id = (SELECT id FROM chart WHERE accno = ?) + AND (startdate <= $transdate) + ORDER BY startdate DESC + LIMIT 1) + ORDER BY c.accno|; + $stw = prepare_execute_query($form, $dbh, $query, $accno_id); + + } else { # use saved tax_id + my $query = + qq|SELECT c.accno, t.taxdescription, t.rate, t.id as tax_id, + c.accno as taxnumber -- taxnumber is same as accno, but still accessed as taxnumber in code + FROM tax t + LEFT JOIN chart c ON (c.id = t.chart_id) + WHERE t.id = ? + ORDER BY c.accno|; + + $stw = prepare_execute_query($form, $dbh, $query, $ref->{tax_id}); + } - my $i = 0; + $ref->{taxaccounts} = ""; while (my $ptr = $stw->fetchrow_hashref("NAME_lc")) { if (($ptr->{accno} eq "") && ($ptr->{rate} == 0)) { - $i++; - $ptr->{accno} = $i; + $ptr->{accno} = "NO_ACCNO_" . $ptr->{tax_id}; } $ref->{taxaccounts} .= "$ptr->{accno} "; @@ -1132,7 +1206,7 @@ sub get_vendor { $dateformat .= "yy" if $myconfig->{dateformat} !~ /^y/; my $vid = conv_i($params->{vendor_id}); - my $vnr = conv_i($params->{vendornumber}); + my $vnr = $params->{vendornumber}; my $duedate = ($params->{invdate}) @@ -1145,8 +1219,7 @@ sub get_vendor { if ($vid) { $where .= 'AND v.id = ?'; push @values, $vid; - } - if ($vnr) { + } elsif ($vnr) { $where .= 'AND v.vendornumber = ?'; push @values, $vnr; } @@ -1164,6 +1237,8 @@ sub get_vendor { LEFT JOIN currencies cu ON (v.currency_id = cu.id) WHERE 1=1 $where|; my $ref = selectfirst_hashref_query($form, $dbh, $query, @values); + die t8("Cannot find a single vendor. Maybe there is no vendor yet?") unless $ref; + map { $params->{$_} = $ref->{$_} } keys %$ref; # use vendor currency @@ -1181,7 +1256,7 @@ sub get_vendor { WHERE (e.currency_id = o.currency_id) AND (e.transdate = o.transdate)) AS exch FROM oe o - WHERE (o.vendor_id = ?) AND (o.quotation = '0') AND (o.closed = '0')|; + WHERE (o.vendor_id = ?) AND (o.record_type = 'purchase_order') AND (o.closed = '0')|; my $sth = prepare_execute_query($form, $dbh, $query, $vid); while (my ($amount, $exch) = $sth->fetchrow_array()) { $exch = 1 unless $exch;