[ 
https://issues.apache.org/jira/browse/FINERACT-3009?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Piotr Wargulak updated FINERACT-3009:
-------------------------------------
    Description: 
Everywhere else in Fineract a text amount is parsed with the request's 
{{{}locale{}}}: {{JsonCommand#bigDecimalValueOfParameterNamed}} goes through 
{{{}extractBigDecimalWithLocaleNamed{}}}, and every {{extractBigDecimalNamed}} 
call in the loan modules ({{{}fineract-loan{}}}, 
{{{}fineract-progressive-loan{}}}, {{fineract-provider}} loanaccount) passes 
the request's locale. Text without a locale is refused 
({{{}validation.msg.missing.locale.parameter{}}}), and text that does not parse 
in that locale is refused ({{{}validation.msg.invalid.decimal.format{}}}).

The Working Capital module mostly does not follow this. Most of its amount 
reads call {{{}FromJsonHelper#extractBigDecimalNamed(name, element, Set){}}}, 
which passes {{Locale.US}} ({{{}FromJsonHelper{}}} :277-280). Under a 
comma-decimal locale a decimal comma is then read as a grouping separator and 
dropped, with HTTP 200 and no warning. JSON numbers are not affected.

 

*Measured:*
||Request||locale||Input||Stored||
|create {{totalPaymentVolume}}|pl|"1095000,50"|109500050|
|create {{periodPaymentRate}}|pl|"1,5"|15|
|create {{principalAmount}}|pl|"100000,50"|100000.5 (reads the locale)|
|approve {{approvedLoanAmount}}|pl|"500,00"|50000|
|disburse {{transactionAmount}} / {{discountAmount}}|pl|"500,00" / "1,50"|50000 
/ 150|
|repayment {{transactionAmount}}|pl|"123,45"|12345|
|discount fee {{transactionAmount}}|de|"1,50"|150 (ledger the same)|
|discount fee {{transactionAmount}}|de|"3.000"|3|
|discount fee {{transactionAmount}}|fr|"2,50"|250|

Every comma-decimal locale is affected; the currency plays no part.

*Proposed fix:* 
read these Working Capital amounts with the request's locale, as the loan 
modules do ({{{}extractBigDecimalWithLocaleNamed{}}} / the locale overload), so 
the validator and the write read the same value. The breach and near-breach 
configuration endpoints are left as they are: they bind the body to a typed 
request and serialize it again, so their amounts always arrive as JSON numbers.

*Behaviour change:* 
text that only parsed because of the US reading is refused, as it already is 
for loans and for {{{}principalAmount{}}}. For example {{"100000.00"}} with 
{{"locale": "pl"}} is accepted today on approve, disburse and repayment and 
becomes 400 {{{}invalid.decimal.format{}}}. JSON numbers, and text matching the 
request's locale, are unaffected.

*Behaviour change:*
text that only parsed because of the US reading is refused, as it already is 
for loans and for {{{}principalAmount{}}}. For example {{"100000.00"}} with 
{{"locale": "pl"}} is accepted today on approve, disburse and repayment and 
becomes 400 {{{}invalid.decimal.format{}}}.

A text amount sent without a {{locale}} is refused with 
{{{}validation.msg.missing.locale.parameter{}}}. Requests that carry a date 
already need a locale, so this affects only text amounts on requests without a 
date, for example a near-breach action with {{{}"nearBreachThreshold": 
"50"{}}}, or a discount fee with a text {{transactionAmount}} and no 
{{{}transactionDate{}}}. Loans already refuse these the same way (POST 
/charges, loan products, an instalment-fee charge).

JSON numbers, and text matching the request's locale, are unaffected.

  was:
Everywhere else in Fineract a text amount is parsed with the request's 
{{{}locale{}}}: {{JsonCommand#bigDecimalValueOfParameterNamed}} goes through 
{{{}extractBigDecimalWithLocaleNamed{}}}, and every {{extractBigDecimalNamed}} 
call in the loan modules ({{{}fineract-loan{}}}, 
{{{}fineract-progressive-loan{}}}, {{fineract-provider}} loanaccount) passes 
the request's locale. Text without a locale is refused 
({{{}validation.msg.missing.locale.parameter{}}}), and text that does not parse 
in that locale is refused ({{{}validation.msg.invalid.decimal.format{}}}).

The Working Capital module mostly does not follow this. Most of its amount 
reads call {{{}FromJsonHelper#extractBigDecimalNamed(name, element, Set){}}}, 
which passes {{Locale.US}} ({{{}FromJsonHelper{}}} :277-280). Under a 
comma-decimal locale a decimal comma is then read as a grouping separator and 
dropped, with HTTP 200 and no warning. JSON numbers are not affected.

 

Measured:
||Request||locale||Input||Stored||
|create {{totalPaymentVolume}}|pl|"1095000,50"|109500050|
|create {{periodPaymentRate}}|pl|"1,5"|15|
|create {{principalAmount}}|pl|"100000,50"|100000.5 (reads the locale)|
|approve {{approvedLoanAmount}}|pl|"500,00"|50000|
|disburse {{transactionAmount}} / {{discountAmount}}|pl|"500,00" / "1,50"|50000 
/ 150|
|repayment {{transactionAmount}}|pl|"123,45"|12345|
|discount fee {{transactionAmount}}|de|"1,50"|150 (ledger the same)|
|discount fee {{transactionAmount}}|de|"3.000"|3|
|discount fee {{transactionAmount}}|fr|"2,50"|250|

Every comma-decimal locale is affected; the currency plays no part.

Proposed fix: 
read these Working Capital amounts with the request's locale, as the loan 
modules do ({{{}extractBigDecimalWithLocaleNamed{}}} / the locale overload), so 
the validator and the write read the same value. The breach and near-breach 
configuration endpoints are left as they are: they bind the body to a typed 
request and serialize it again, so their amounts always arrive as JSON numbers.

Behaviour change: 
text that only parsed because of the US reading is refused, as it already is 
for loans and for {{{}principalAmount{}}}. For example {{"100000.00"}} with 
{{"locale": "pl"}} is accepted today on approve, disburse and repayment and 
becomes 400 {{{}invalid.decimal.format{}}}. JSON numbers, and text matching the 
request's locale, are unaffected.


> Working Capital loans read text amounts in the US locale, ignoring the 
> request's locale ("123,45" → 12345)
> ----------------------------------------------------------------------------------------------------------
>
>                 Key: FINERACT-3009
>                 URL: https://issues.apache.org/jira/browse/FINERACT-3009
>             Project: Apache Fineract
>          Issue Type: Bug
>            Reporter: Piotr Wargulak
>            Assignee: Piotr Wargulak
>            Priority: Major
>
> Everywhere else in Fineract a text amount is parsed with the request's 
> {{{}locale{}}}: {{JsonCommand#bigDecimalValueOfParameterNamed}} goes through 
> {{{}extractBigDecimalWithLocaleNamed{}}}, and every 
> {{extractBigDecimalNamed}} call in the loan modules ({{{}fineract-loan{}}}, 
> {{{}fineract-progressive-loan{}}}, {{fineract-provider}} loanaccount) passes 
> the request's locale. Text without a locale is refused 
> ({{{}validation.msg.missing.locale.parameter{}}}), and text that does not 
> parse in that locale is refused 
> ({{{}validation.msg.invalid.decimal.format{}}}).
> The Working Capital module mostly does not follow this. Most of its amount 
> reads call {{{}FromJsonHelper#extractBigDecimalNamed(name, element, Set){}}}, 
> which passes {{Locale.US}} ({{{}FromJsonHelper{}}} :277-280). Under a 
> comma-decimal locale a decimal comma is then read as a grouping separator and 
> dropped, with HTTP 200 and no warning. JSON numbers are not affected.
>  
> *Measured:*
> ||Request||locale||Input||Stored||
> |create {{totalPaymentVolume}}|pl|"1095000,50"|109500050|
> |create {{periodPaymentRate}}|pl|"1,5"|15|
> |create {{principalAmount}}|pl|"100000,50"|100000.5 (reads the locale)|
> |approve {{approvedLoanAmount}}|pl|"500,00"|50000|
> |disburse {{transactionAmount}} / {{discountAmount}}|pl|"500,00" / 
> "1,50"|50000 / 150|
> |repayment {{transactionAmount}}|pl|"123,45"|12345|
> |discount fee {{transactionAmount}}|de|"1,50"|150 (ledger the same)|
> |discount fee {{transactionAmount}}|de|"3.000"|3|
> |discount fee {{transactionAmount}}|fr|"2,50"|250|
> Every comma-decimal locale is affected; the currency plays no part.
> *Proposed fix:* 
> read these Working Capital amounts with the request's locale, as the loan 
> modules do ({{{}extractBigDecimalWithLocaleNamed{}}} / the locale overload), 
> so the validator and the write read the same value. The breach and 
> near-breach configuration endpoints are left as they are: they bind the body 
> to a typed request and serialize it again, so their amounts always arrive as 
> JSON numbers.
> *Behaviour change:* 
> text that only parsed because of the US reading is refused, as it already is 
> for loans and for {{{}principalAmount{}}}. For example {{"100000.00"}} with 
> {{"locale": "pl"}} is accepted today on approve, disburse and repayment and 
> becomes 400 {{{}invalid.decimal.format{}}}. JSON numbers, and text matching 
> the request's locale, are unaffected.
> *Behaviour change:*
> text that only parsed because of the US reading is refused, as it already is 
> for loans and for {{{}principalAmount{}}}. For example {{"100000.00"}} with 
> {{"locale": "pl"}} is accepted today on approve, disburse and repayment and 
> becomes 400 {{{}invalid.decimal.format{}}}.
> A text amount sent without a {{locale}} is refused with 
> {{{}validation.msg.missing.locale.parameter{}}}. Requests that carry a date 
> already need a locale, so this affects only text amounts on requests without 
> a date, for example a near-breach action with {{{}"nearBreachThreshold": 
> "50"{}}}, or a discount fee with a text {{transactionAmount}} and no 
> {{{}transactionDate{}}}. Loans already refuse these the same way (POST 
> /charges, loan products, an instalment-fee charge).
> JSON numbers, and text matching the request's locale, are unaffected.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to