[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Can't apply payment to vendor invoice in foreign currency - with proposed fix



Hi,

As I said in a previous mail, we're unable to apply payments to
invoices in foreign currencies. By changing the way
Payment.sql::payment_get_open_invoices() handles the currency rate
(inverting the check from in_account_class = 1 to 'in_account_class <>
1'), we were able to get a bit further.

However, we immediately run into the next problem: "Invalid number
detected during parsing". As it turns out, LedgerSMB::parse_amount()
is being fed the string "N/A" which it can't turn into a number --
logically. The source of the N/A string is in scripts/payment.pl:953.
The block there looks like this (lines 944 to 953):

"""
# LETS SET THE EXCHANGERATE VALUES
   my $due_fx =
$request->{"optional_discount_$array_options[$ref]->{invoice_id}"} ?
$request->round_amount($array_options[$ref]->{due_fx}) :
$request->round_amount($array_options[$ref]->{due_fx}) +
$array_options[$ref]->{discount_fx} ;
   my $topay_fx_value;
   if ("$exchangerate") {
       $topay_fx_value =   $due_fx;
       if (!$request->{"optional_discount_$array_options[$ref]->{invoice_id}"})
{
       $topay_fx_value = $due_fx = $due_fx +
$request->round_amount($array_options[$ref]->{discount}/$array_options[$ref]->{exchangerate});
        }
   } else {
       $topay_fx_value = "N/A";
   }
"""

The problem that I have with the code is that the $exchangerate is the
form's exchange rate to be used for the transaction being entered.
It's not the exchange rate of the actual invoice being presented.
Since the invoice has been entered and is in a non-local currency,
presumably, there's *always* an fx rate available. So, I changed the
block to:


"""
# LETS SET THE EXCHANGERATE VALUES
   my $due_fx =
$request->{"optional_discount_$array_options[$ref]->{invoice_id}"} ?
$request->round_amount($array_options[$ref]->{due_fx}) :
$request->round_amount($array_options[$ref]->{due_fx}) +
$array_options[$ref]->{discount_fx} ;
   my $topay_fx_value;
#   if ("$exchangerate") {
       $topay_fx_value =   $due_fx;
       if (!$request->{"optional_discount_$array_options[$ref]->{invoice_id}"})
{
       $topay_fx_value = $due_fx = $due_fx +
$request->round_amount($array_options[$ref]->{discount}/$array_options[$ref]->{exchangerate});
        }
#   } else {
#       $topay_fx_value = "N/A";
#   }
"""

Which works.

However, since I don't understand why the original code looked like it
did, I don't want to commit this change -- yet.

Can someone explain what the code tries to do and which case it tries
to prevent from occurring? Why would that calculation be invalid if
the $exchangerate isn't defined? It's not even being used!


Bye,


Erik.