You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@fineract.apache.org by "Farooq Ayoade (Jira)" <ji...@apache.org> on 2026/02/28 06:02:00 UTC
[jira] [Commented] (FINERACT-2512) Invalid fee_on_month / fee_on_day combination (e.g. day 30 for February) causes HTTP 500 when fetching savings product with template
[ https://issues.apache.org/jira/browse/FINERACT-2512?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18061776#comment-18061776 ]
Farooq Ayoade commented on FINERACT-2512:
-----------------------------------------
PR for the ticket : https://github.com/apache/fineract/pull/5559
> Invalid fee_on_month / fee_on_day combination (e.g. day 30 for February) causes HTTP 500 when fetching savings product with template
> ------------------------------------------------------------------------------------------------------------------------------------
>
> Key: FINERACT-2512
> URL: https://issues.apache.org/jira/browse/FINERACT-2512
> Project: Apache Fineract
> Issue Type: Bug
> Components: Charges, Savings
> Reporter: Farooq Ayoade
> Priority: Major
>
> When fetching a savings product with template data via {{{}GET /fineract-provider/api/v1/savingsproducts/\{productId}?template=true{}}}, the API returns *HTTP 500 Internal Server Error* if any charge linked to that product has an invalid month/day combination stored in the database (e.g. {{{}fee_on_month=2{}}}, {{fee_on_day=30}} — February has no 30th).
> h3. Steps to Reproduce
> # Have a savings product (e.g. id=5) that has at least one charge with an invalid month/day stored in {{m_charge}} (e.g. {{{}fee_on_month=2{}}}, {{{}fee_on_day=30{}}}).
> # Call: {{GET https://localhost:8443/fineract-provider/api/v1/savingsproducts/5?template=true}}
> # Observe: *500 Internal Server Error* with stack trace showing {{{}java.time.DateTimeException: Illegal value for DayOfMonth field, value 30 is not valid for month FEBRUARY{}}}.
> h3. Expected Behavior
> * The API should return *HTTP 200* with the savings product template.
> * Invalid month/day combinations stored in the database (legacy data or “last day of month” semantics) should be handled defensively when building {{MonthDay}} for the response (e.g. clamp day to the last valid day of the month) so that read operations do not fail.
> h3. Actual Behavior
> * *HTTP 500 Internal Server Error* is returned.
> * Server log shows: {{java.time.DateTimeException: Illegal value for DayOfMonth field, value 30 is not valid for month FEBRUARY}}
> * Stack trace points to:
> ** {{ChargeReadPlatformServiceImpl$ChargeMapper.mapRow}} (line 342): {{MonthDay.now(...).withDayOfMonth(feeOnDay).withMonth(feeOnMonth)}}
> ** Called from {{ChargeReadPlatformServiceImpl.retrieveSavingsProductApplicableCharges}} → {{SavingsProductsApiResource.handleTemplateRelatedData}} → {{SavingsProductsApiResource.retrieveOne}}
> h3. Root Cause
> * Charges store *month* and *day* in separate columns: {{{}m_charge.fee_on_month{}}}, {{{}m_charge.fee_on_day{}}}.
> * When mapping a row to {{{}ChargeData{}}}, the code builds a {{MonthDay}} as: {{MonthDay.now(...).withDayOfMonth(feeOnDay).withMonth(feeOnMonth)}} without validating that {{feeOnDay}} is valid for {{feeOnMonth}} (e.g. February allows 1–28/29, not 30/31).
> * Invalid combinations can exist due to:
> ** Legacy or migrated data.
> ** “Last day of month” semantics stored as day 30 or 31 for all months.
> ** Lack of or bypass of validation at charge create/update in some code paths.
> * The same pattern exists in:
> ** *ChargeReadPlatformServiceImpl* (charge template / product-applicable charges).
> ** *SavingsAccountChargeReadPlatformServiceImpl* (savings account charge mapping).
> ** *StandingInstructionReadPlatformServiceImpl* (recurrence month/day mapping).
> So any *read* that maps these columns to {{MonthDay}} can throw {{DateTimeException}} when the stored (month, day) is invalid.
> h3. Affected Code Paths
> * *Primary:* {{org.apache.fineract.portfolio.charge.service.ChargeReadPlatformServiceImpl$ChargeMapper#mapRow}} (line 342).
> * *Same bug pattern:*
> ** {{org.apache.fineract.portfolio.savings.service.SavingsAccountChargeReadPlatformServiceImpl}} (line 122).
> ** {{org.apache.fineract.portfolio.account.service.StandingInstructionReadPlatformServiceImpl}} (lines 443–444).
> h3. Impact
> * Savings product template endpoint is unusable when any linked charge has invalid month/day (e.g. February 30).
> * Similar 500s can occur when reading standing instructions or savings account charges with invalid recurrence/fee month/day.
> * Poor robustness against existing bad or legacy data.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)