You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org> on 2025/07/31 12:02:28 UTC
[PR] FINERACT-2311: Add buydown fees documentation [fineract]
oleksii-novikov-onix opened a new pull request, #4913:
URL: https://github.com/apache/fineract/pull/4913
## Description
Describe the changes made and why they were made.
Ignore if these details are present on the associated [Apache Fineract JIRA ticket](https://github.com/apache/fineract/pull/1284).
## Checklist
Please make sure these boxes are checked before submitting your pull request - thanks!
- [ ] Write the commit message as per https://github.com/apache/fineract/#pull-requests
- [ ] Acknowledge that we will not review PRs that are not passing the build _("green")_ - it is your responsibility to get a proposed PR to pass the build, not primarily the project's maintainers.
- [ ] Create/update unit or integration tests for verifying the changes made.
- [ ] Follow coding conventions at https://cwiki.apache.org/confluence/display/FINERACT/Coding+Conventions.
- [ ] Add required Swagger annotation and update API documentation at fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm with details of any API changes
- [ ] Submission is not a "code dump". (Large changes can be made "in repository" via a branch. Ask on the developer mailing list for guidance, if required.)
FYI our guidelines for code reviews are at https://cwiki.apache.org/confluence/display/FINERACT/Code+Review+Guide.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245263796
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
Review Comment:
Irrelevant
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org>.
oleksii-novikov-onix commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245874250
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
Review Comment:
Fixed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248126443
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
Review Comment:
`deferredIncomeLiabilityAccountId` is missing here
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248194646
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
+- Supports all four endpoint variants (internal/external ID combinations)
+
+=== Retrieve Buy Down Fee Amortization Details
+
+**Endpoint**: `GET /loans/{loanId}/buydown-fees`
+
+**Alternative**: `GET /loans/external-id/{loanExternalId}/buydown-fees`
+
+**Purpose**: Retrieves detailed amortization information for all Buy Down Fee transactions associated with a loan.
+
+**Request Parameters**: None (path parameters only)
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoint)
+|===
+
+_* Required only for external ID endpoint_
+
+**Response Structure**:
+[source,json]
+----
+[
+ {
+ "id": 1,
+ "loanId": 123,
+ "transactionId": 456,
+ "buyDownFeeDate": "2024-01-01",
+ "buyDownFeeAmount": 500.00,
+ "amortizedAmount": 125.00,
+ "notYetAmortizedAmount": 375.00,
+ "adjustedAmount": 0.00,
+ "chargedOffAmount": 0.00
+ }
+]
+----
+
+**Response Fields**:
+[cols="2,1,3", options="header"]
+|===
+|Field |Type |Description
+
+|`id`
+|Long
+|Buy Down Fee balance record identifier
+
+|`loanId`
+|Long
+|Internal loan identifier
+
+|`transactionId`
+|Long
+|Buy Down Fee transaction identifier
+
+|`buyDownFeeDate`
+|LocalDate
+|Date when Buy Down Fee was created
+
+|`buyDownFeeAmount`
+|BigDecimal
+|Original Buy Down Fee amount
+
+|`amortizedAmount`
+|BigDecimal
+|Amount already amortized to income
+
+|`notYetAmortizedAmount`
+|BigDecimal
+|Amount still to be amortized
+
+|`adjustedAmount`
+|BigDecimal
+|Total adjustment amount (if any)
+
+|`chargedOffAmount`
+|BigDecimal
+|Amount charged off (if loan was charged off)
+|===
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has read permission for LOAN resources
+2. **Loan Resolution**: For external ID endpoint, resolves loan ID using `ExternalIdFactory` and `LoanReadPlatformService`
+3. **Data Retrieval**: Calls `BuyDownFeeReadPlatformService.retrieveLoanBuyDownFeeAmortizationDetails()`
+4. **Response Assembly**: Returns array of `BuyDownFeeAmortizationDetails` objects
+5. **Security**: Ensures authenticated user context through `PlatformSecurityContext`
+
+=== Validation Rules
+
+**Common Validations**:
+
+- Buy Down Fee must be enabled for the loan product
+- Loan must be in active status
+- Client/Group must be active
+- Transaction date cannot be in the future
+- Transaction amount must be positive
+
+**Create Transaction Validations**:
+
+- Transaction date cannot be before first disbursement date
+- Loan must be disbursed
+- Only one Buy Down Fee transaction per loan (unless adjusted)
+
+**Adjustment Validations**:
+
+- Original Buy Down Fee transaction must exist
+- Adjustment amount cannot exceed remaining balance
+- Adjustment date cannot be before original transaction date
+- Cannot adjust if there are unreversed related transactions
+
+=== Error Responses
+
+**Common Error Codes**:
+
+- `buy.down.fee.not.enabled`: Buy Down Fee not enabled for loan product
+- `cannot.be.before.first.disbursement.date`: Invalid transaction date
+- `cannot.be.more.than.remaining.amount`: Adjustment exceeds balance
+- `loan.transaction.not.found`: Referenced transaction not found
+
+**Error Response Example**:
+[source,json]
+----
+{
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "httpStatusCode": "400",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "errors": [
+ {
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "parameterName": null
+ }
+ ]
+}
+----
+
+== Business Logic
+
+=== Amortization Process
+
+Buy Down Fee amortization follows the Equal Amortization strategy:
+
+1. **Initial Recording**: Buy down fee is recorded as a liability (Deferred Capitalized Income)
+2. **Daily Amortization**: Fee is amortized daily over the loan term
+3. **Income Recognition**: Amortized portions are recognized as income (Fee or Interest based on configuration)
+4. **COB Processing**: Close of Business processes handle automatic amortization
+5. **Balance Tracking**: System maintains current deferred fee balance at loan level
+6. **Customer Invisibility**: Amortization process is not visible to customers
+
+=== Special Scenarios
+
+==== Early Payoff Acceleration
+When a loan is paid off early, the system accelerates the remaining balance of the deferred income to ensure proper revenue recognition.
+
+==== Charge-off Handling
+When a loan balance is charged off, any remaining balance in deferred income is also charged off to maintain accounting accuracy.
+
+==== Deferred Fee Balance Management
+The system maintains a current deferred fee balance at the loan level, tracking:
+* Original fee amount
+* Amortized amount to date
+* Remaining balance to be amortized
+* Any adjustments or charge-offs
+
+=== Journal Entries
+
+==== Buy Down Fee Transaction
+```
+Dr. Buy Down Expense Account [Fee Amount]
+ Cr. Deferred Capitalized Income [Fee Amount]
+```
+
+==== Daily Amortization
+```
+Dr. Deferred Capitalized Income [Daily Amortization]
+ Cr. Fee/Interest Income Account [Daily Amortization]
+```
+
+==== Buy Down Fee Adjustment
+```
+Dr. Deferred Income Liability [Adjustment Amount]
+ Cr. Buy Down Expense Account [Adjustment Amount]
+```
+
+==== Buy Down Fee Amortization Adjustment
+```
+Dr. Deferred Income Liability [Amortization Adjustment]
+ Cr. Income from Buy Down Account [Amortization Adjustment]
+```
+
+==== Charge-off Handling
+```
+Dr. Losses Written Off Account [Remaining Unamortized Amount]
+ Cr. Deferred Income Liability [Remaining Unamortized Amount]
+```
+
+=== Available Disbursement Calculation
+
+Buy Down Fee affects the available disbursement amount calculation:
+
+```
+Available Disbursement = Approved Loan Amount
+ - Total Disbursed Amount
+ - Total Capitalized Income
+ - Total Buy Down Fee
+```
+
+== Limitations and Considerations
+
+* **Progressive Loans Only**: Buy Down Fee is exclusively available for Progressive Loan products
+* **Single Strategy**: Currently supports only Equal Amortization strategy (Formula-based amortization planned for future)
+* **Flat Calculation**: Only flat fee calculation is currently supported
+* **Customer Invisibility**: Fee amortization is intentionally hidden from customer view
+* **0% Interest Context**: Primarily designed for 0% interest loan products with merchant fees
+* **Accounting Setup**: requires proper chart of accounts configuration
+* **COB Dependency**: Amortization relies on Close of Business processing
+* **Early Payoff Impact**: Requires special handling for early loan payoffs
+* **Charge-off Integration**: Must be properly integrated with loan charge-off processes
+
+== Related Features
+
+* **Capitalized Income**: Works alongside capitalized income for comprehensive loan management
+* **Progressive Loans**: Core dependency for advanced loan features
+* **Delinquency Management**: Integrates with delinquency calculations
+* **Loan Scheduling**: Affects loan payment schedules and calculations
Review Comment:
Buy down fees do not affect repayment schedule
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248146628
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
Review Comment:
The original transaction is not reversed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248129900
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
Review Comment:
Deferred income liability account is missing here
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245278453
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account (if payment involved)
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Income Liability Account
+ - Credit: Income from Buy Down Account
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
Review Comment:
What does "adjustment" mean? ( i mean i know what it means, but the documentation not yet explained!)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2247940493
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
Review Comment:
Credits the income gl account configured by `incomeFromBuyDownAccountId`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245277191
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account (if payment involved)
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Income Liability Account
+ - Credit: Income from Buy Down Account
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
Review Comment:
Deferred income mapping missing
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245268083
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
Review Comment:
"Required GL accounts must be configured" is enought... no need to the rest.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org>.
oleksii-novikov-onix commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245877378
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account (if payment involved)
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Income Liability Account
+ - Credit: Income from Buy Down Account
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
Review Comment:
Added description
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org>.
oleksii-novikov-onix commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245873745
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
Review Comment:
Removed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2247923549
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
Review Comment:
Buy down fee creation credits deferred income liability
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248171101
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
+- Supports all four endpoint variants (internal/external ID combinations)
+
+=== Retrieve Buy Down Fee Amortization Details
+
+**Endpoint**: `GET /loans/{loanId}/buydown-fees`
+
+**Alternative**: `GET /loans/external-id/{loanExternalId}/buydown-fees`
+
+**Purpose**: Retrieves detailed amortization information for all Buy Down Fee transactions associated with a loan.
+
+**Request Parameters**: None (path parameters only)
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoint)
+|===
+
+_* Required only for external ID endpoint_
+
+**Response Structure**:
+[source,json]
+----
+[
+ {
+ "id": 1,
+ "loanId": 123,
+ "transactionId": 456,
+ "buyDownFeeDate": "2024-01-01",
+ "buyDownFeeAmount": 500.00,
+ "amortizedAmount": 125.00,
+ "notYetAmortizedAmount": 375.00,
+ "adjustedAmount": 0.00,
+ "chargedOffAmount": 0.00
+ }
+]
+----
+
+**Response Fields**:
+[cols="2,1,3", options="header"]
+|===
+|Field |Type |Description
+
+|`id`
+|Long
+|Buy Down Fee balance record identifier
+
+|`loanId`
+|Long
+|Internal loan identifier
+
+|`transactionId`
+|Long
+|Buy Down Fee transaction identifier
+
+|`buyDownFeeDate`
+|LocalDate
+|Date when Buy Down Fee was created
+
+|`buyDownFeeAmount`
+|BigDecimal
+|Original Buy Down Fee amount
+
+|`amortizedAmount`
+|BigDecimal
+|Amount already amortized to income
+
+|`notYetAmortizedAmount`
+|BigDecimal
+|Amount still to be amortized
+
+|`adjustedAmount`
+|BigDecimal
+|Total adjustment amount (if any)
+
+|`chargedOffAmount`
+|BigDecimal
+|Amount charged off (if loan was charged off)
+|===
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has read permission for LOAN resources
+2. **Loan Resolution**: For external ID endpoint, resolves loan ID using `ExternalIdFactory` and `LoanReadPlatformService`
+3. **Data Retrieval**: Calls `BuyDownFeeReadPlatformService.retrieveLoanBuyDownFeeAmortizationDetails()`
+4. **Response Assembly**: Returns array of `BuyDownFeeAmortizationDetails` objects
+5. **Security**: Ensures authenticated user context through `PlatformSecurityContext`
+
+=== Validation Rules
+
+**Common Validations**:
+
+- Buy Down Fee must be enabled for the loan product
+- Loan must be in active status
+- Client/Group must be active
+- Transaction date cannot be in the future
+- Transaction amount must be positive
+
+**Create Transaction Validations**:
+
+- Transaction date cannot be before first disbursement date
+- Loan must be disbursed
+- Only one Buy Down Fee transaction per loan (unless adjusted)
+
+**Adjustment Validations**:
+
+- Original Buy Down Fee transaction must exist
+- Adjustment amount cannot exceed remaining balance
+- Adjustment date cannot be before original transaction date
+- Cannot adjust if there are unreversed related transactions
+
+=== Error Responses
+
+**Common Error Codes**:
+
+- `buy.down.fee.not.enabled`: Buy Down Fee not enabled for loan product
+- `cannot.be.before.first.disbursement.date`: Invalid transaction date
+- `cannot.be.more.than.remaining.amount`: Adjustment exceeds balance
+- `loan.transaction.not.found`: Referenced transaction not found
+
+**Error Response Example**:
+[source,json]
+----
+{
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "httpStatusCode": "400",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "errors": [
+ {
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "parameterName": null
+ }
+ ]
+}
+----
+
+== Business Logic
+
+=== Amortization Process
+
+Buy Down Fee amortization follows the Equal Amortization strategy:
+
+1. **Initial Recording**: Buy down fee is recorded as a liability (Deferred Capitalized Income)
+2. **Daily Amortization**: Fee is amortized daily over the loan term
+3. **Income Recognition**: Amortized portions are recognized as income (Fee or Interest based on configuration)
+4. **COB Processing**: Close of Business processes handle automatic amortization
+5. **Balance Tracking**: System maintains current deferred fee balance at loan level
+6. **Customer Invisibility**: Amortization process is not visible to customers
+
+=== Special Scenarios
+
+==== Early Payoff Acceleration
+When a loan is paid off early, the system accelerates the remaining balance of the deferred income to ensure proper revenue recognition.
+
+==== Charge-off Handling
+When a loan balance is charged off, any remaining balance in deferred income is also charged off to maintain accounting accuracy.
+
+==== Deferred Fee Balance Management
+The system maintains a current deferred fee balance at the loan level, tracking:
+* Original fee amount
+* Amortized amount to date
+* Remaining balance to be amortized
+* Any adjustments or charge-offs
+
+=== Journal Entries
+
+==== Buy Down Fee Transaction
+```
+Dr. Buy Down Expense Account [Fee Amount]
+ Cr. Deferred Capitalized Income [Fee Amount]
+```
+
+==== Daily Amortization
+```
+Dr. Deferred Capitalized Income [Daily Amortization]
+ Cr. Fee/Interest Income Account [Daily Amortization]
+```
+
+==== Buy Down Fee Adjustment
+```
+Dr. Deferred Income Liability [Adjustment Amount]
+ Cr. Buy Down Expense Account [Adjustment Amount]
+```
+
+==== Buy Down Fee Amortization Adjustment
+```
+Dr. Deferred Income Liability [Amortization Adjustment]
+ Cr. Income from Buy Down Account [Amortization Adjustment]
Review Comment:
This should be the mirror of Daily Amortization
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245266778
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
Review Comment:
Totally irrelevant. Please remove entirely!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245272552
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
Review Comment:
Duplicate? line 71
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "bharathcgowda (via GitHub)" <gi...@apache.org>.
bharathcgowda commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2251275670
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
+- Supports all four endpoint variants (internal/external ID combinations)
+
+=== Retrieve Buy Down Fee Amortization Details
+
+**Endpoint**: `GET /loans/{loanId}/buydown-fees`
+
+**Alternative**: `GET /loans/external-id/{loanExternalId}/buydown-fees`
+
+**Purpose**: Retrieves detailed amortization information for all Buy Down Fee transactions associated with a loan.
+
+**Request Parameters**: None (path parameters only)
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoint)
+|===
+
+_* Required only for external ID endpoint_
+
+**Response Structure**:
+[source,json]
+----
+[
+ {
+ "id": 1,
+ "loanId": 123,
+ "transactionId": 456,
+ "buyDownFeeDate": "2024-01-01",
+ "buyDownFeeAmount": 500.00,
+ "amortizedAmount": 125.00,
+ "notYetAmortizedAmount": 375.00,
+ "adjustedAmount": 0.00,
+ "chargedOffAmount": 0.00
+ }
+]
+----
+
+**Response Fields**:
+[cols="2,1,3", options="header"]
+|===
+|Field |Type |Description
+
+|`id`
+|Long
+|Buy Down Fee balance record identifier
+
+|`loanId`
+|Long
+|Internal loan identifier
+
+|`transactionId`
+|Long
+|Buy Down Fee transaction identifier
+
+|`buyDownFeeDate`
+|LocalDate
+|Date when Buy Down Fee was created
+
+|`buyDownFeeAmount`
+|BigDecimal
+|Original Buy Down Fee amount
+
+|`amortizedAmount`
+|BigDecimal
+|Amount already amortized to income
+
+|`notYetAmortizedAmount`
+|BigDecimal
+|Amount still to be amortized
+
+|`adjustedAmount`
+|BigDecimal
+|Total adjustment amount (if any)
+
+|`chargedOffAmount`
+|BigDecimal
+|Amount charged off (if loan was charged off)
+|===
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has read permission for LOAN resources
+2. **Loan Resolution**: For external ID endpoint, resolves loan ID using `ExternalIdFactory` and `LoanReadPlatformService`
+3. **Data Retrieval**: Calls `BuyDownFeeReadPlatformService.retrieveLoanBuyDownFeeAmortizationDetails()`
+4. **Response Assembly**: Returns array of `BuyDownFeeAmortizationDetails` objects
+5. **Security**: Ensures authenticated user context through `PlatformSecurityContext`
+
+=== Validation Rules
+
+**Common Validations**:
+
+- Buy Down Fee must be enabled for the loan product
+- Loan must be in active status
+- Client/Group must be active
+- Transaction date cannot be in the future
+- Transaction amount must be positive
+
+**Create Transaction Validations**:
+
+- Transaction date cannot be before first disbursement date
+- Loan must be disbursed
+- Only one Buy Down Fee transaction per loan (unless adjusted)
+
+**Adjustment Validations**:
+
+- Original Buy Down Fee transaction must exist
+- Adjustment amount cannot exceed remaining balance
+- Adjustment date cannot be before original transaction date
+- Cannot adjust if there are unreversed related transactions
+
+=== Error Responses
+
+**Common Error Codes**:
+
+- `buy.down.fee.not.enabled`: Buy Down Fee not enabled for loan product
+- `cannot.be.before.first.disbursement.date`: Invalid transaction date
+- `cannot.be.more.than.remaining.amount`: Adjustment exceeds balance
+- `loan.transaction.not.found`: Referenced transaction not found
+
+**Error Response Example**:
+[source,json]
+----
+{
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "httpStatusCode": "400",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "errors": [
+ {
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "parameterName": null
+ }
+ ]
+}
+----
+
+== Business Logic
+
+=== Amortization Process
+
+Buy Down Fee amortization follows the Equal Amortization strategy:
+
+1. **Initial Recording**: Buy down fee is recorded as a liability (Deferred Capitalized Income)
+2. **Daily Amortization**: Fee is amortized daily over the loan term
+3. **Income Recognition**: Amortized portions are recognized as income (Fee or Interest based on configuration)
+4. **COB Processing**: Close of Business processes handle automatic amortization
+5. **Balance Tracking**: System maintains current deferred fee balance at loan level
+6. **Customer Invisibility**: Amortization process is not visible to customers
+
+=== Special Scenarios
+
+==== Early Payoff Acceleration
+When a loan is paid off early, the system accelerates the remaining balance of the deferred income to ensure proper revenue recognition.
+
+==== Charge-off Handling
+When a loan balance is charged off, any remaining balance in deferred income is also charged off to maintain accounting accuracy.
+
+==== Deferred Fee Balance Management
+The system maintains a current deferred fee balance at the loan level, tracking:
+* Original fee amount
+* Amortized amount to date
+* Remaining balance to be amortized
+* Any adjustments or charge-offs
+
+=== Journal Entries
+
+==== Buy Down Fee Transaction
+```
+Dr. Buy Down Expense Account [Fee Amount]
+ Cr. Deferred Capitalized Income [Fee Amount]
+```
+
+==== Daily Amortization
+```
+Dr. Deferred Capitalized Income [Daily Amortization]
+ Cr. Fee/Interest Income Account [Daily Amortization]
+```
+
+==== Buy Down Fee Adjustment
+```
+Dr. Deferred Income Liability [Adjustment Amount]
+ Cr. Buy Down Expense Account [Adjustment Amount]
+```
+
+==== Buy Down Fee Amortization Adjustment
+```
+Dr. Deferred Income Liability [Amortization Adjustment]
+ Cr. Income from Buy Down Account [Amortization Adjustment]
+```
+
+==== Charge-off Handling
+```
+Dr. Losses Written Off Account [Remaining Unamortized Amount]
+ Cr. Deferred Income Liability [Remaining Unamortized Amount]
+```
+
+=== Available Disbursement Calculation
+
+Buy Down Fee affects the available disbursement amount calculation:
+
+```
+Available Disbursement = Approved Loan Amount
+ - Total Disbursed Amount
+ - Total Capitalized Income
+ - Total Buy Down Fee
Review Comment:
@oleksii-novikov-onix
Total Buydownfee should be removed from this formula
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245265679
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
Review Comment:
Irrelevant
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245275721
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account (if payment involved)
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Income Liability Account
+ - Credit: Income from Buy Down Account
+
Review Comment:
Buy down fee adjustment and buy down fee amortization adjustment is missing.
Account in case of charge-off missing.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on PR #4913:
URL: https://github.com/apache/fineract/pull/4913#issuecomment-3139828658
@bharathc27 Please review!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248057384
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
Review Comment:
It was not yet implemented, so i was wondering whether we should just add them afterwards? @bharathcgowda what do you think?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248160665
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
+- Supports all four endpoint variants (internal/external ID combinations)
+
+=== Retrieve Buy Down Fee Amortization Details
+
+**Endpoint**: `GET /loans/{loanId}/buydown-fees`
+
+**Alternative**: `GET /loans/external-id/{loanExternalId}/buydown-fees`
+
+**Purpose**: Retrieves detailed amortization information for all Buy Down Fee transactions associated with a loan.
+
+**Request Parameters**: None (path parameters only)
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoint)
+|===
+
+_* Required only for external ID endpoint_
+
+**Response Structure**:
+[source,json]
+----
+[
+ {
+ "id": 1,
+ "loanId": 123,
+ "transactionId": 456,
+ "buyDownFeeDate": "2024-01-01",
+ "buyDownFeeAmount": 500.00,
+ "amortizedAmount": 125.00,
+ "notYetAmortizedAmount": 375.00,
+ "adjustedAmount": 0.00,
+ "chargedOffAmount": 0.00
+ }
+]
+----
+
+**Response Fields**:
+[cols="2,1,3", options="header"]
+|===
+|Field |Type |Description
+
+|`id`
+|Long
+|Buy Down Fee balance record identifier
+
+|`loanId`
+|Long
+|Internal loan identifier
+
+|`transactionId`
+|Long
+|Buy Down Fee transaction identifier
+
+|`buyDownFeeDate`
+|LocalDate
+|Date when Buy Down Fee was created
+
+|`buyDownFeeAmount`
+|BigDecimal
+|Original Buy Down Fee amount
+
+|`amortizedAmount`
+|BigDecimal
+|Amount already amortized to income
+
+|`notYetAmortizedAmount`
+|BigDecimal
+|Amount still to be amortized
+
+|`adjustedAmount`
+|BigDecimal
+|Total adjustment amount (if any)
+
+|`chargedOffAmount`
+|BigDecimal
+|Amount charged off (if loan was charged off)
+|===
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has read permission for LOAN resources
+2. **Loan Resolution**: For external ID endpoint, resolves loan ID using `ExternalIdFactory` and `LoanReadPlatformService`
+3. **Data Retrieval**: Calls `BuyDownFeeReadPlatformService.retrieveLoanBuyDownFeeAmortizationDetails()`
+4. **Response Assembly**: Returns array of `BuyDownFeeAmortizationDetails` objects
+5. **Security**: Ensures authenticated user context through `PlatformSecurityContext`
+
+=== Validation Rules
+
+**Common Validations**:
+
+- Buy Down Fee must be enabled for the loan product
+- Loan must be in active status
+- Client/Group must be active
+- Transaction date cannot be in the future
+- Transaction amount must be positive
+
+**Create Transaction Validations**:
+
+- Transaction date cannot be before first disbursement date
+- Loan must be disbursed
+- Only one Buy Down Fee transaction per loan (unless adjusted)
Review Comment:
We can have more than one buy down fee per loan
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2256982061
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,544 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+== Purpose
+
+This functionality enables financial institutions to:
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Supported Loan Type
+
+[IMPORTANT]
+====
+Buy Down Fee is only supported for loans that have **all** of the following:
+
+* **Advanced Payment Allocation Strategy** (transaction processing strategy)
+* **Progressive Loan Schedule** (loan schedule type)
+
+Other transaction processing strategies or loan schedule types are not supported.
+====
+
+== Configuration at Loan Product Level
+
+Buy Down Fee must be configured on the loan product.
+
+The configuration options include:
+
+* *Enable Buy Down Fee*: Boolean toggle (`enableBuyDownFee`) (default: disabled)
+* *Calculation Mode*: Only "Flat" is currently supported (`buyDownFeeCalculationType`)
+* *Amortization Strategy*: Only "EQUAL_AMORTIZATION" is supported (`buyDownFeeStrategy`)
+** Daily equal portions are recognized over the life of the loan
+* *Income Type*: Specifies allocation rule (`buyDownFeeIncomeType`)
+
+Options:
+* FEE
+* INTEREST
+
+=== GL Mapping
+
+Required GL Account mappings when Buy Down Fee is enabled:
+
+* *Buy Down Expense Account*: `buyDownExpenseAccountId` - mandatory when enabled
+* *Deferred Income Liability Account*: `deferredIncomeLiabilityAccountId` - mandatory when enabled
+* *Income from Buy Down Account*: `incomeFromBuyDownAccountId` - mandatory when enabled
+
+[IMPORTANT]
+====
+All GL accounts become mandatory when `enableBuyDownFee` is set to `true`.
+====
+
+=== Configuration Dependencies
+
+When `enableBuyDownFee` is set to `true`, all following parameters become mandatory:
+
+* `buyDownFeeCalculationType` - must be "FLAT"
+* `buyDownFeeStrategy` - must be "EQUAL_AMORTIZATION"
+* `buyDownFeeIncomeType` - must be "FEE" or "INTEREST"
+* `buyDownExpenseAccountId` - must reference a valid GL account
+* `deferredIncomeLiabilityAccountId` - must reference a valid GL account
+* `incomeFromBuyDownAccountId` - must reference a valid GL account
+
+== Validation Rules
+
+=== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+=== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+* Transaction date cannot be in the future
+* Client/Group must be active
+* Loan must be disbursed
+* Multiple Buy Down Fee transactions per loan are supported
+
+=== Adjustment Validations
+
+* Original Buy Down Fee transaction must exist
+* Adjustment amount cannot exceed remaining balance
+* Adjustment date cannot be before original transaction date
+* Cannot adjust if there are unreversed related transactions
Review Comment:
Buy down fee adjustments are related to the buy down fee transaction (they have relation with type `ADJUSTMENT` between them), and there can be more than one adjustment to the same buy down fee transaction.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "bharathcgowda (via GitHub)" <gi...@apache.org>.
bharathcgowda commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248013911
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
Review Comment:
This doesn't contain the non-merchant and merchant configuration and its differences.
will that come in later?
@adamsaghy cc
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248138550
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
Review Comment:
Loan balance does not change with buy down fees, LoanBalanceChangedBusinessEvent is not fired here
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248174409
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
+- Supports all four endpoint variants (internal/external ID combinations)
+
+=== Retrieve Buy Down Fee Amortization Details
+
+**Endpoint**: `GET /loans/{loanId}/buydown-fees`
+
+**Alternative**: `GET /loans/external-id/{loanExternalId}/buydown-fees`
+
+**Purpose**: Retrieves detailed amortization information for all Buy Down Fee transactions associated with a loan.
+
+**Request Parameters**: None (path parameters only)
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoint)
+|===
+
+_* Required only for external ID endpoint_
+
+**Response Structure**:
+[source,json]
+----
+[
+ {
+ "id": 1,
+ "loanId": 123,
+ "transactionId": 456,
+ "buyDownFeeDate": "2024-01-01",
+ "buyDownFeeAmount": 500.00,
+ "amortizedAmount": 125.00,
+ "notYetAmortizedAmount": 375.00,
+ "adjustedAmount": 0.00,
+ "chargedOffAmount": 0.00
+ }
+]
+----
+
+**Response Fields**:
+[cols="2,1,3", options="header"]
+|===
+|Field |Type |Description
+
+|`id`
+|Long
+|Buy Down Fee balance record identifier
+
+|`loanId`
+|Long
+|Internal loan identifier
+
+|`transactionId`
+|Long
+|Buy Down Fee transaction identifier
+
+|`buyDownFeeDate`
+|LocalDate
+|Date when Buy Down Fee was created
+
+|`buyDownFeeAmount`
+|BigDecimal
+|Original Buy Down Fee amount
+
+|`amortizedAmount`
+|BigDecimal
+|Amount already amortized to income
+
+|`notYetAmortizedAmount`
+|BigDecimal
+|Amount still to be amortized
+
+|`adjustedAmount`
+|BigDecimal
+|Total adjustment amount (if any)
+
+|`chargedOffAmount`
+|BigDecimal
+|Amount charged off (if loan was charged off)
+|===
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has read permission for LOAN resources
+2. **Loan Resolution**: For external ID endpoint, resolves loan ID using `ExternalIdFactory` and `LoanReadPlatformService`
+3. **Data Retrieval**: Calls `BuyDownFeeReadPlatformService.retrieveLoanBuyDownFeeAmortizationDetails()`
+4. **Response Assembly**: Returns array of `BuyDownFeeAmortizationDetails` objects
+5. **Security**: Ensures authenticated user context through `PlatformSecurityContext`
+
+=== Validation Rules
+
+**Common Validations**:
+
+- Buy Down Fee must be enabled for the loan product
+- Loan must be in active status
+- Client/Group must be active
+- Transaction date cannot be in the future
+- Transaction amount must be positive
+
+**Create Transaction Validations**:
+
+- Transaction date cannot be before first disbursement date
+- Loan must be disbursed
+- Only one Buy Down Fee transaction per loan (unless adjusted)
+
+**Adjustment Validations**:
+
+- Original Buy Down Fee transaction must exist
+- Adjustment amount cannot exceed remaining balance
+- Adjustment date cannot be before original transaction date
+- Cannot adjust if there are unreversed related transactions
+
+=== Error Responses
+
+**Common Error Codes**:
+
+- `buy.down.fee.not.enabled`: Buy Down Fee not enabled for loan product
+- `cannot.be.before.first.disbursement.date`: Invalid transaction date
+- `cannot.be.more.than.remaining.amount`: Adjustment exceeds balance
+- `loan.transaction.not.found`: Referenced transaction not found
+
+**Error Response Example**:
+[source,json]
+----
+{
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "httpStatusCode": "400",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "errors": [
+ {
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "parameterName": null
+ }
+ ]
+}
+----
+
+== Business Logic
+
+=== Amortization Process
+
+Buy Down Fee amortization follows the Equal Amortization strategy:
+
+1. **Initial Recording**: Buy down fee is recorded as a liability (Deferred Capitalized Income)
+2. **Daily Amortization**: Fee is amortized daily over the loan term
+3. **Income Recognition**: Amortized portions are recognized as income (Fee or Interest based on configuration)
+4. **COB Processing**: Close of Business processes handle automatic amortization
+5. **Balance Tracking**: System maintains current deferred fee balance at loan level
+6. **Customer Invisibility**: Amortization process is not visible to customers
+
+=== Special Scenarios
+
+==== Early Payoff Acceleration
+When a loan is paid off early, the system accelerates the remaining balance of the deferred income to ensure proper revenue recognition.
+
+==== Charge-off Handling
+When a loan balance is charged off, any remaining balance in deferred income is also charged off to maintain accounting accuracy.
+
+==== Deferred Fee Balance Management
+The system maintains a current deferred fee balance at the loan level, tracking:
+* Original fee amount
+* Amortized amount to date
+* Remaining balance to be amortized
+* Any adjustments or charge-offs
+
+=== Journal Entries
+
+==== Buy Down Fee Transaction
+```
+Dr. Buy Down Expense Account [Fee Amount]
+ Cr. Deferred Capitalized Income [Fee Amount]
+```
+
+==== Daily Amortization
+```
+Dr. Deferred Capitalized Income [Daily Amortization]
+ Cr. Fee/Interest Income Account [Daily Amortization]
+```
+
+==== Buy Down Fee Adjustment
+```
+Dr. Deferred Income Liability [Adjustment Amount]
+ Cr. Buy Down Expense Account [Adjustment Amount]
+```
+
+==== Buy Down Fee Amortization Adjustment
+```
+Dr. Deferred Income Liability [Amortization Adjustment]
+ Cr. Income from Buy Down Account [Amortization Adjustment]
+```
+
+==== Charge-off Handling
+```
+Dr. Losses Written Off Account [Remaining Unamortized Amount]
+ Cr. Deferred Income Liability [Remaining Unamortized Amount]
Review Comment:
Debits Deferred income, and credits `ChargeOff Expense` or `Charge Off Fraud Expense` if the loan was marked as fraud
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248174409
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
+- Supports all four endpoint variants (internal/external ID combinations)
+
+=== Retrieve Buy Down Fee Amortization Details
+
+**Endpoint**: `GET /loans/{loanId}/buydown-fees`
+
+**Alternative**: `GET /loans/external-id/{loanExternalId}/buydown-fees`
+
+**Purpose**: Retrieves detailed amortization information for all Buy Down Fee transactions associated with a loan.
+
+**Request Parameters**: None (path parameters only)
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoint)
+|===
+
+_* Required only for external ID endpoint_
+
+**Response Structure**:
+[source,json]
+----
+[
+ {
+ "id": 1,
+ "loanId": 123,
+ "transactionId": 456,
+ "buyDownFeeDate": "2024-01-01",
+ "buyDownFeeAmount": 500.00,
+ "amortizedAmount": 125.00,
+ "notYetAmortizedAmount": 375.00,
+ "adjustedAmount": 0.00,
+ "chargedOffAmount": 0.00
+ }
+]
+----
+
+**Response Fields**:
+[cols="2,1,3", options="header"]
+|===
+|Field |Type |Description
+
+|`id`
+|Long
+|Buy Down Fee balance record identifier
+
+|`loanId`
+|Long
+|Internal loan identifier
+
+|`transactionId`
+|Long
+|Buy Down Fee transaction identifier
+
+|`buyDownFeeDate`
+|LocalDate
+|Date when Buy Down Fee was created
+
+|`buyDownFeeAmount`
+|BigDecimal
+|Original Buy Down Fee amount
+
+|`amortizedAmount`
+|BigDecimal
+|Amount already amortized to income
+
+|`notYetAmortizedAmount`
+|BigDecimal
+|Amount still to be amortized
+
+|`adjustedAmount`
+|BigDecimal
+|Total adjustment amount (if any)
+
+|`chargedOffAmount`
+|BigDecimal
+|Amount charged off (if loan was charged off)
+|===
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has read permission for LOAN resources
+2. **Loan Resolution**: For external ID endpoint, resolves loan ID using `ExternalIdFactory` and `LoanReadPlatformService`
+3. **Data Retrieval**: Calls `BuyDownFeeReadPlatformService.retrieveLoanBuyDownFeeAmortizationDetails()`
+4. **Response Assembly**: Returns array of `BuyDownFeeAmortizationDetails` objects
+5. **Security**: Ensures authenticated user context through `PlatformSecurityContext`
+
+=== Validation Rules
+
+**Common Validations**:
+
+- Buy Down Fee must be enabled for the loan product
+- Loan must be in active status
+- Client/Group must be active
+- Transaction date cannot be in the future
+- Transaction amount must be positive
+
+**Create Transaction Validations**:
+
+- Transaction date cannot be before first disbursement date
+- Loan must be disbursed
+- Only one Buy Down Fee transaction per loan (unless adjusted)
+
+**Adjustment Validations**:
+
+- Original Buy Down Fee transaction must exist
+- Adjustment amount cannot exceed remaining balance
+- Adjustment date cannot be before original transaction date
+- Cannot adjust if there are unreversed related transactions
+
+=== Error Responses
+
+**Common Error Codes**:
+
+- `buy.down.fee.not.enabled`: Buy Down Fee not enabled for loan product
+- `cannot.be.before.first.disbursement.date`: Invalid transaction date
+- `cannot.be.more.than.remaining.amount`: Adjustment exceeds balance
+- `loan.transaction.not.found`: Referenced transaction not found
+
+**Error Response Example**:
+[source,json]
+----
+{
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "httpStatusCode": "400",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "errors": [
+ {
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "parameterName": null
+ }
+ ]
+}
+----
+
+== Business Logic
+
+=== Amortization Process
+
+Buy Down Fee amortization follows the Equal Amortization strategy:
+
+1. **Initial Recording**: Buy down fee is recorded as a liability (Deferred Capitalized Income)
+2. **Daily Amortization**: Fee is amortized daily over the loan term
+3. **Income Recognition**: Amortized portions are recognized as income (Fee or Interest based on configuration)
+4. **COB Processing**: Close of Business processes handle automatic amortization
+5. **Balance Tracking**: System maintains current deferred fee balance at loan level
+6. **Customer Invisibility**: Amortization process is not visible to customers
+
+=== Special Scenarios
+
+==== Early Payoff Acceleration
+When a loan is paid off early, the system accelerates the remaining balance of the deferred income to ensure proper revenue recognition.
+
+==== Charge-off Handling
+When a loan balance is charged off, any remaining balance in deferred income is also charged off to maintain accounting accuracy.
+
+==== Deferred Fee Balance Management
+The system maintains a current deferred fee balance at the loan level, tracking:
+* Original fee amount
+* Amortized amount to date
+* Remaining balance to be amortized
+* Any adjustments or charge-offs
+
+=== Journal Entries
+
+==== Buy Down Fee Transaction
+```
+Dr. Buy Down Expense Account [Fee Amount]
+ Cr. Deferred Capitalized Income [Fee Amount]
+```
+
+==== Daily Amortization
+```
+Dr. Deferred Capitalized Income [Daily Amortization]
+ Cr. Fee/Interest Income Account [Daily Amortization]
+```
+
+==== Buy Down Fee Adjustment
+```
+Dr. Deferred Income Liability [Adjustment Amount]
+ Cr. Buy Down Expense Account [Adjustment Amount]
+```
+
+==== Buy Down Fee Amortization Adjustment
+```
+Dr. Deferred Income Liability [Amortization Adjustment]
+ Cr. Income from Buy Down Account [Amortization Adjustment]
+```
+
+==== Charge-off Handling
+```
+Dr. Losses Written Off Account [Remaining Unamortized Amount]
+ Cr. Deferred Income Liability [Remaining Unamortized Amount]
Review Comment:
Debits Deferred income, and credits ChargeOff Expense or Charge Off Fraud Expense if the loan was marked as fraud
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248191343
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
+- Supports all four endpoint variants (internal/external ID combinations)
+
+=== Retrieve Buy Down Fee Amortization Details
+
+**Endpoint**: `GET /loans/{loanId}/buydown-fees`
+
+**Alternative**: `GET /loans/external-id/{loanExternalId}/buydown-fees`
+
+**Purpose**: Retrieves detailed amortization information for all Buy Down Fee transactions associated with a loan.
+
+**Request Parameters**: None (path parameters only)
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoint)
+|===
+
+_* Required only for external ID endpoint_
+
+**Response Structure**:
+[source,json]
+----
+[
+ {
+ "id": 1,
+ "loanId": 123,
+ "transactionId": 456,
+ "buyDownFeeDate": "2024-01-01",
+ "buyDownFeeAmount": 500.00,
+ "amortizedAmount": 125.00,
+ "notYetAmortizedAmount": 375.00,
+ "adjustedAmount": 0.00,
+ "chargedOffAmount": 0.00
+ }
+]
+----
+
+**Response Fields**:
+[cols="2,1,3", options="header"]
+|===
+|Field |Type |Description
+
+|`id`
+|Long
+|Buy Down Fee balance record identifier
+
+|`loanId`
+|Long
+|Internal loan identifier
+
+|`transactionId`
+|Long
+|Buy Down Fee transaction identifier
+
+|`buyDownFeeDate`
+|LocalDate
+|Date when Buy Down Fee was created
+
+|`buyDownFeeAmount`
+|BigDecimal
+|Original Buy Down Fee amount
+
+|`amortizedAmount`
+|BigDecimal
+|Amount already amortized to income
+
+|`notYetAmortizedAmount`
+|BigDecimal
+|Amount still to be amortized
+
+|`adjustedAmount`
+|BigDecimal
+|Total adjustment amount (if any)
+
+|`chargedOffAmount`
+|BigDecimal
+|Amount charged off (if loan was charged off)
+|===
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has read permission for LOAN resources
+2. **Loan Resolution**: For external ID endpoint, resolves loan ID using `ExternalIdFactory` and `LoanReadPlatformService`
+3. **Data Retrieval**: Calls `BuyDownFeeReadPlatformService.retrieveLoanBuyDownFeeAmortizationDetails()`
+4. **Response Assembly**: Returns array of `BuyDownFeeAmortizationDetails` objects
+5. **Security**: Ensures authenticated user context through `PlatformSecurityContext`
+
+=== Validation Rules
+
+**Common Validations**:
+
+- Buy Down Fee must be enabled for the loan product
+- Loan must be in active status
+- Client/Group must be active
+- Transaction date cannot be in the future
+- Transaction amount must be positive
+
+**Create Transaction Validations**:
+
+- Transaction date cannot be before first disbursement date
+- Loan must be disbursed
+- Only one Buy Down Fee transaction per loan (unless adjusted)
+
+**Adjustment Validations**:
+
+- Original Buy Down Fee transaction must exist
+- Adjustment amount cannot exceed remaining balance
+- Adjustment date cannot be before original transaction date
+- Cannot adjust if there are unreversed related transactions
+
+=== Error Responses
+
+**Common Error Codes**:
+
+- `buy.down.fee.not.enabled`: Buy Down Fee not enabled for loan product
+- `cannot.be.before.first.disbursement.date`: Invalid transaction date
+- `cannot.be.more.than.remaining.amount`: Adjustment exceeds balance
+- `loan.transaction.not.found`: Referenced transaction not found
+
+**Error Response Example**:
+[source,json]
+----
+{
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "httpStatusCode": "400",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "errors": [
+ {
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "parameterName": null
+ }
+ ]
+}
+----
+
+== Business Logic
+
+=== Amortization Process
+
+Buy Down Fee amortization follows the Equal Amortization strategy:
+
+1. **Initial Recording**: Buy down fee is recorded as a liability (Deferred Capitalized Income)
+2. **Daily Amortization**: Fee is amortized daily over the loan term
+3. **Income Recognition**: Amortized portions are recognized as income (Fee or Interest based on configuration)
+4. **COB Processing**: Close of Business processes handle automatic amortization
+5. **Balance Tracking**: System maintains current deferred fee balance at loan level
+6. **Customer Invisibility**: Amortization process is not visible to customers
+
+=== Special Scenarios
+
+==== Early Payoff Acceleration
+When a loan is paid off early, the system accelerates the remaining balance of the deferred income to ensure proper revenue recognition.
+
+==== Charge-off Handling
+When a loan balance is charged off, any remaining balance in deferred income is also charged off to maintain accounting accuracy.
+
+==== Deferred Fee Balance Management
+The system maintains a current deferred fee balance at the loan level, tracking:
+* Original fee amount
+* Amortized amount to date
+* Remaining balance to be amortized
+* Any adjustments or charge-offs
+
+=== Journal Entries
+
+==== Buy Down Fee Transaction
+```
+Dr. Buy Down Expense Account [Fee Amount]
+ Cr. Deferred Capitalized Income [Fee Amount]
+```
+
+==== Daily Amortization
+```
+Dr. Deferred Capitalized Income [Daily Amortization]
+ Cr. Fee/Interest Income Account [Daily Amortization]
+```
+
+==== Buy Down Fee Adjustment
+```
+Dr. Deferred Income Liability [Adjustment Amount]
+ Cr. Buy Down Expense Account [Adjustment Amount]
+```
+
+==== Buy Down Fee Amortization Adjustment
+```
+Dr. Deferred Income Liability [Amortization Adjustment]
+ Cr. Income from Buy Down Account [Amortization Adjustment]
+```
+
+==== Charge-off Handling
+```
+Dr. Losses Written Off Account [Remaining Unamortized Amount]
+ Cr. Deferred Income Liability [Remaining Unamortized Amount]
+```
+
+=== Available Disbursement Calculation
+
+Buy Down Fee affects the available disbursement amount calculation:
+
+```
+Available Disbursement = Approved Loan Amount
+ - Total Disbursed Amount
+ - Total Capitalized Income
+ - Total Buy Down Fee
+```
+
+== Limitations and Considerations
+
+* **Progressive Loans Only**: Buy Down Fee is exclusively available for Progressive Loan products
+* **Single Strategy**: Currently supports only Equal Amortization strategy (Formula-based amortization planned for future)
+* **Flat Calculation**: Only flat fee calculation is currently supported
+* **Customer Invisibility**: Fee amortization is intentionally hidden from customer view
+* **0% Interest Context**: Primarily designed for 0% interest loan products with merchant fees
+* **Accounting Setup**: requires proper chart of accounts configuration
+* **COB Dependency**: Amortization relies on Close of Business processing
+* **Early Payoff Impact**: Requires special handling for early loan payoffs
Review Comment:
Not really, early payoff and normal loan closure are handled the same way
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245273484
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account (if payment involved)
Review Comment:
"(if payment involved)" - what does this mean?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248176461
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
+- Supports all four endpoint variants (internal/external ID combinations)
+
+=== Retrieve Buy Down Fee Amortization Details
+
+**Endpoint**: `GET /loans/{loanId}/buydown-fees`
+
+**Alternative**: `GET /loans/external-id/{loanExternalId}/buydown-fees`
+
+**Purpose**: Retrieves detailed amortization information for all Buy Down Fee transactions associated with a loan.
+
+**Request Parameters**: None (path parameters only)
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoint)
+|===
+
+_* Required only for external ID endpoint_
+
+**Response Structure**:
+[source,json]
+----
+[
+ {
+ "id": 1,
+ "loanId": 123,
+ "transactionId": 456,
+ "buyDownFeeDate": "2024-01-01",
+ "buyDownFeeAmount": 500.00,
+ "amortizedAmount": 125.00,
+ "notYetAmortizedAmount": 375.00,
+ "adjustedAmount": 0.00,
+ "chargedOffAmount": 0.00
+ }
+]
+----
+
+**Response Fields**:
+[cols="2,1,3", options="header"]
+|===
+|Field |Type |Description
+
+|`id`
+|Long
+|Buy Down Fee balance record identifier
+
+|`loanId`
+|Long
+|Internal loan identifier
+
+|`transactionId`
+|Long
+|Buy Down Fee transaction identifier
+
+|`buyDownFeeDate`
+|LocalDate
+|Date when Buy Down Fee was created
+
+|`buyDownFeeAmount`
+|BigDecimal
+|Original Buy Down Fee amount
+
+|`amortizedAmount`
+|BigDecimal
+|Amount already amortized to income
+
+|`notYetAmortizedAmount`
+|BigDecimal
+|Amount still to be amortized
+
+|`adjustedAmount`
+|BigDecimal
+|Total adjustment amount (if any)
+
+|`chargedOffAmount`
+|BigDecimal
+|Amount charged off (if loan was charged off)
+|===
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has read permission for LOAN resources
+2. **Loan Resolution**: For external ID endpoint, resolves loan ID using `ExternalIdFactory` and `LoanReadPlatformService`
+3. **Data Retrieval**: Calls `BuyDownFeeReadPlatformService.retrieveLoanBuyDownFeeAmortizationDetails()`
+4. **Response Assembly**: Returns array of `BuyDownFeeAmortizationDetails` objects
+5. **Security**: Ensures authenticated user context through `PlatformSecurityContext`
+
+=== Validation Rules
+
+**Common Validations**:
+
+- Buy Down Fee must be enabled for the loan product
+- Loan must be in active status
+- Client/Group must be active
+- Transaction date cannot be in the future
+- Transaction amount must be positive
+
+**Create Transaction Validations**:
+
+- Transaction date cannot be before first disbursement date
+- Loan must be disbursed
+- Only one Buy Down Fee transaction per loan (unless adjusted)
+
+**Adjustment Validations**:
+
+- Original Buy Down Fee transaction must exist
+- Adjustment amount cannot exceed remaining balance
+- Adjustment date cannot be before original transaction date
+- Cannot adjust if there are unreversed related transactions
+
+=== Error Responses
+
+**Common Error Codes**:
+
+- `buy.down.fee.not.enabled`: Buy Down Fee not enabled for loan product
+- `cannot.be.before.first.disbursement.date`: Invalid transaction date
+- `cannot.be.more.than.remaining.amount`: Adjustment exceeds balance
+- `loan.transaction.not.found`: Referenced transaction not found
+
+**Error Response Example**:
+[source,json]
+----
+{
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "httpStatusCode": "400",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "errors": [
+ {
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "parameterName": null
+ }
+ ]
+}
+----
+
+== Business Logic
+
+=== Amortization Process
+
+Buy Down Fee amortization follows the Equal Amortization strategy:
+
+1. **Initial Recording**: Buy down fee is recorded as a liability (Deferred Capitalized Income)
+2. **Daily Amortization**: Fee is amortized daily over the loan term
+3. **Income Recognition**: Amortized portions are recognized as income (Fee or Interest based on configuration)
+4. **COB Processing**: Close of Business processes handle automatic amortization
+5. **Balance Tracking**: System maintains current deferred fee balance at loan level
+6. **Customer Invisibility**: Amortization process is not visible to customers
+
+=== Special Scenarios
+
+==== Early Payoff Acceleration
+When a loan is paid off early, the system accelerates the remaining balance of the deferred income to ensure proper revenue recognition.
+
+==== Charge-off Handling
+When a loan balance is charged off, any remaining balance in deferred income is also charged off to maintain accounting accuracy.
+
+==== Deferred Fee Balance Management
+The system maintains a current deferred fee balance at the loan level, tracking:
+* Original fee amount
+* Amortized amount to date
+* Remaining balance to be amortized
+* Any adjustments or charge-offs
+
+=== Journal Entries
+
+==== Buy Down Fee Transaction
+```
+Dr. Buy Down Expense Account [Fee Amount]
+ Cr. Deferred Capitalized Income [Fee Amount]
+```
+
+==== Daily Amortization
+```
+Dr. Deferred Capitalized Income [Daily Amortization]
+ Cr. Fee/Interest Income Account [Daily Amortization]
+```
+
+==== Buy Down Fee Adjustment
+```
+Dr. Deferred Income Liability [Adjustment Amount]
+ Cr. Buy Down Expense Account [Adjustment Amount]
+```
+
+==== Buy Down Fee Amortization Adjustment
+```
+Dr. Deferred Income Liability [Amortization Adjustment]
+ Cr. Income from Buy Down Account [Amortization Adjustment]
+```
+
+==== Charge-off Handling
+```
+Dr. Losses Written Off Account [Remaining Unamortized Amount]
+ Cr. Deferred Income Liability [Remaining Unamortized Amount]
+```
+
+=== Available Disbursement Calculation
+
+Buy Down Fee affects the available disbursement amount calculation:
Review Comment:
It shouldn't affect available disbursement amount
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248115720
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
Review Comment:
Debits Deferred income, and credits `ChargeOff Expense` or `Charge Off Fraud Expense` if the loan was marked as fraud
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "bharathcgowda (via GitHub)" <gi...@apache.org>.
bharathcgowda commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248009409
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
+- Supports all four endpoint variants (internal/external ID combinations)
+
+=== Retrieve Buy Down Fee Amortization Details
+
+**Endpoint**: `GET /loans/{loanId}/buydown-fees`
+
+**Alternative**: `GET /loans/external-id/{loanExternalId}/buydown-fees`
+
+**Purpose**: Retrieves detailed amortization information for all Buy Down Fee transactions associated with a loan.
+
+**Request Parameters**: None (path parameters only)
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoint)
+|===
+
+_* Required only for external ID endpoint_
+
+**Response Structure**:
+[source,json]
+----
+[
+ {
+ "id": 1,
+ "loanId": 123,
+ "transactionId": 456,
+ "buyDownFeeDate": "2024-01-01",
+ "buyDownFeeAmount": 500.00,
+ "amortizedAmount": 125.00,
+ "notYetAmortizedAmount": 375.00,
+ "adjustedAmount": 0.00,
+ "chargedOffAmount": 0.00
+ }
+]
+----
+
+**Response Fields**:
+[cols="2,1,3", options="header"]
+|===
+|Field |Type |Description
+
+|`id`
+|Long
+|Buy Down Fee balance record identifier
+
+|`loanId`
+|Long
+|Internal loan identifier
+
+|`transactionId`
+|Long
+|Buy Down Fee transaction identifier
+
+|`buyDownFeeDate`
+|LocalDate
+|Date when Buy Down Fee was created
+
+|`buyDownFeeAmount`
+|BigDecimal
+|Original Buy Down Fee amount
+
+|`amortizedAmount`
+|BigDecimal
+|Amount already amortized to income
+
+|`notYetAmortizedAmount`
+|BigDecimal
+|Amount still to be amortized
+
+|`adjustedAmount`
+|BigDecimal
+|Total adjustment amount (if any)
+
+|`chargedOffAmount`
+|BigDecimal
+|Amount charged off (if loan was charged off)
+|===
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has read permission for LOAN resources
+2. **Loan Resolution**: For external ID endpoint, resolves loan ID using `ExternalIdFactory` and `LoanReadPlatformService`
+3. **Data Retrieval**: Calls `BuyDownFeeReadPlatformService.retrieveLoanBuyDownFeeAmortizationDetails()`
+4. **Response Assembly**: Returns array of `BuyDownFeeAmortizationDetails` objects
+5. **Security**: Ensures authenticated user context through `PlatformSecurityContext`
+
+=== Validation Rules
+
+**Common Validations**:
+
+- Buy Down Fee must be enabled for the loan product
+- Loan must be in active status
+- Client/Group must be active
+- Transaction date cannot be in the future
+- Transaction amount must be positive
+
+**Create Transaction Validations**:
+
+- Transaction date cannot be before first disbursement date
+- Loan must be disbursed
+- Only one Buy Down Fee transaction per loan (unless adjusted)
+
+**Adjustment Validations**:
+
+- Original Buy Down Fee transaction must exist
+- Adjustment amount cannot exceed remaining balance
+- Adjustment date cannot be before original transaction date
+- Cannot adjust if there are unreversed related transactions
+
+=== Error Responses
+
+**Common Error Codes**:
+
+- `buy.down.fee.not.enabled`: Buy Down Fee not enabled for loan product
+- `cannot.be.before.first.disbursement.date`: Invalid transaction date
+- `cannot.be.more.than.remaining.amount`: Adjustment exceeds balance
+- `loan.transaction.not.found`: Referenced transaction not found
+
+**Error Response Example**:
+[source,json]
+----
+{
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "httpStatusCode": "400",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "errors": [
+ {
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "parameterName": null
+ }
+ ]
+}
+----
+
+== Business Logic
+
+=== Amortization Process
+
+Buy Down Fee amortization follows the Equal Amortization strategy:
+
+1. **Initial Recording**: Buy down fee is recorded as a liability (Deferred Capitalized Income)
+2. **Daily Amortization**: Fee is amortized daily over the loan term
+3. **Income Recognition**: Amortized portions are recognized as income (Fee or Interest based on configuration)
+4. **COB Processing**: Close of Business processes handle automatic amortization
+5. **Balance Tracking**: System maintains current deferred fee balance at loan level
+6. **Customer Invisibility**: Amortization process is not visible to customers
+
+=== Special Scenarios
+
+==== Early Payoff Acceleration
+When a loan is paid off early, the system accelerates the remaining balance of the deferred income to ensure proper revenue recognition.
+
+==== Charge-off Handling
+When a loan balance is charged off, any remaining balance in deferred income is also charged off to maintain accounting accuracy.
+
+==== Deferred Fee Balance Management
+The system maintains a current deferred fee balance at the loan level, tracking:
+* Original fee amount
+* Amortized amount to date
+* Remaining balance to be amortized
+* Any adjustments or charge-offs
+
+=== Journal Entries
+
+==== Buy Down Fee Transaction
+```
+Dr. Buy Down Expense Account [Fee Amount]
+ Cr. Deferred Capitalized Income [Fee Amount]
+```
+
+==== Daily Amortization
+```
+Dr. Deferred Capitalized Income [Daily Amortization]
+ Cr. Fee/Interest Income Account [Daily Amortization]
+```
+
+==== Buy Down Fee Adjustment
+```
+Dr. Deferred Income Liability [Adjustment Amount]
+ Cr. Buy Down Expense Account [Adjustment Amount]
+```
+
+==== Buy Down Fee Amortization Adjustment
+```
+Dr. Deferred Income Liability [Amortization Adjustment]
+ Cr. Income from Buy Down Account [Amortization Adjustment]
+```
+
+==== Charge-off Handling
+```
+Dr. Losses Written Off Account [Remaining Unamortized Amount]
+ Cr. Deferred Income Liability [Remaining Unamortized Amount]
+```
+
+=== Available Disbursement Calculation
+
+Buy Down Fee affects the available disbursement amount calculation:
+
+```
+Available Disbursement = Approved Loan Amount
+ - Total Disbursed Amount
+ - Total Capitalized Income
+ - Total Buy Down Fee
Review Comment:
We discussed to remove Total buydown fees from this calculation
@adamsaghy cc
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "bharathcgowda (via GitHub)" <gi...@apache.org>.
bharathcgowda commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248010973
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
+- Supports all four endpoint variants (internal/external ID combinations)
+
+=== Retrieve Buy Down Fee Amortization Details
+
+**Endpoint**: `GET /loans/{loanId}/buydown-fees`
+
+**Alternative**: `GET /loans/external-id/{loanExternalId}/buydown-fees`
+
+**Purpose**: Retrieves detailed amortization information for all Buy Down Fee transactions associated with a loan.
+
+**Request Parameters**: None (path parameters only)
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoint)
+|===
+
+_* Required only for external ID endpoint_
+
+**Response Structure**:
+[source,json]
+----
+[
+ {
+ "id": 1,
+ "loanId": 123,
+ "transactionId": 456,
+ "buyDownFeeDate": "2024-01-01",
+ "buyDownFeeAmount": 500.00,
+ "amortizedAmount": 125.00,
+ "notYetAmortizedAmount": 375.00,
+ "adjustedAmount": 0.00,
+ "chargedOffAmount": 0.00
+ }
+]
+----
+
+**Response Fields**:
+[cols="2,1,3", options="header"]
+|===
+|Field |Type |Description
+
+|`id`
+|Long
+|Buy Down Fee balance record identifier
+
+|`loanId`
+|Long
+|Internal loan identifier
+
+|`transactionId`
+|Long
+|Buy Down Fee transaction identifier
+
+|`buyDownFeeDate`
+|LocalDate
+|Date when Buy Down Fee was created
+
+|`buyDownFeeAmount`
+|BigDecimal
+|Original Buy Down Fee amount
+
+|`amortizedAmount`
+|BigDecimal
+|Amount already amortized to income
+
+|`notYetAmortizedAmount`
+|BigDecimal
+|Amount still to be amortized
+
+|`adjustedAmount`
+|BigDecimal
+|Total adjustment amount (if any)
+
+|`chargedOffAmount`
+|BigDecimal
+|Amount charged off (if loan was charged off)
+|===
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has read permission for LOAN resources
+2. **Loan Resolution**: For external ID endpoint, resolves loan ID using `ExternalIdFactory` and `LoanReadPlatformService`
+3. **Data Retrieval**: Calls `BuyDownFeeReadPlatformService.retrieveLoanBuyDownFeeAmortizationDetails()`
+4. **Response Assembly**: Returns array of `BuyDownFeeAmortizationDetails` objects
+5. **Security**: Ensures authenticated user context through `PlatformSecurityContext`
+
+=== Validation Rules
+
+**Common Validations**:
+
+- Buy Down Fee must be enabled for the loan product
+- Loan must be in active status
+- Client/Group must be active
+- Transaction date cannot be in the future
+- Transaction amount must be positive
+
+**Create Transaction Validations**:
+
+- Transaction date cannot be before first disbursement date
+- Loan must be disbursed
+- Only one Buy Down Fee transaction per loan (unless adjusted)
+
+**Adjustment Validations**:
+
+- Original Buy Down Fee transaction must exist
+- Adjustment amount cannot exceed remaining balance
+- Adjustment date cannot be before original transaction date
+- Cannot adjust if there are unreversed related transactions
+
+=== Error Responses
+
+**Common Error Codes**:
+
+- `buy.down.fee.not.enabled`: Buy Down Fee not enabled for loan product
+- `cannot.be.before.first.disbursement.date`: Invalid transaction date
+- `cannot.be.more.than.remaining.amount`: Adjustment exceeds balance
+- `loan.transaction.not.found`: Referenced transaction not found
+
+**Error Response Example**:
+[source,json]
+----
+{
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "httpStatusCode": "400",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "errors": [
+ {
+ "developerMessage": "Buy down fee is not enabled for this loan product",
+ "defaultUserMessage": "Buy down fee is not enabled for this loan product",
+ "userMessageGlobalisationCode": "buy.down.fee.not.enabled",
+ "parameterName": null
+ }
+ ]
+}
+----
+
+== Business Logic
+
+=== Amortization Process
+
+Buy Down Fee amortization follows the Equal Amortization strategy:
+
+1. **Initial Recording**: Buy down fee is recorded as a liability (Deferred Capitalized Income)
+2. **Daily Amortization**: Fee is amortized daily over the loan term
+3. **Income Recognition**: Amortized portions are recognized as income (Fee or Interest based on configuration)
+4. **COB Processing**: Close of Business processes handle automatic amortization
+5. **Balance Tracking**: System maintains current deferred fee balance at loan level
+6. **Customer Invisibility**: Amortization process is not visible to customers
+
+=== Special Scenarios
+
+==== Early Payoff Acceleration
+When a loan is paid off early, the system accelerates the remaining balance of the deferred income to ensure proper revenue recognition.
+
+==== Charge-off Handling
+When a loan balance is charged off, any remaining balance in deferred income is also charged off to maintain accounting accuracy.
+
+==== Deferred Fee Balance Management
+The system maintains a current deferred fee balance at the loan level, tracking:
+* Original fee amount
+* Amortized amount to date
+* Remaining balance to be amortized
+* Any adjustments or charge-offs
+
+=== Journal Entries
+
+==== Buy Down Fee Transaction
+```
+Dr. Buy Down Expense Account [Fee Amount]
+ Cr. Deferred Capitalized Income [Fee Amount]
+```
+
+==== Daily Amortization
+```
+Dr. Deferred Capitalized Income [Daily Amortization]
+ Cr. Fee/Interest Income Account [Daily Amortization]
+```
+
+==== Buy Down Fee Adjustment
+```
+Dr. Deferred Income Liability [Adjustment Amount]
+ Cr. Buy Down Expense Account [Adjustment Amount]
+```
+
+==== Buy Down Fee Amortization Adjustment
+```
+Dr. Deferred Income Liability [Amortization Adjustment]
+ Cr. Income from Buy Down Account [Amortization Adjustment]
+```
+
+==== Charge-off Handling
+```
+Dr. Losses Written Off Account [Remaining Unamortized Amount]
Review Comment:
this should affect the charge-off parameter "charge-off expense/charge-off expense- bad dept" parameter
@adamsaghy cc
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org>.
oleksii-novikov-onix commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245875619
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account (if payment involved)
Review Comment:
Removed part `(if payment involved)`
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account (if payment involved)
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Income Liability Account
+ - Credit: Income from Buy Down Account
+
Review Comment:
Added
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org>.
oleksii-novikov-onix commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245873074
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
Review Comment:
Removed
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
Review Comment:
Removed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245270442
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
Review Comment:
`Deferred income` gl mapping is missing.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "bharathcgowda (via GitHub)" <gi...@apache.org>.
bharathcgowda commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248002198
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
Review Comment:
charge off should debit - charge-off expense/charge-off expense- account no?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248094819
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
Review Comment:
This should be the mirror of daily amortization
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy merged PR #4913:
URL: https://github.com/apache/fineract/pull/4913
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org>.
oleksii-novikov-onix commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245874629
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
Review Comment:
Added
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org>.
oleksii-novikov-onix commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245872391
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
Review Comment:
Fixed
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
Review Comment:
Fixed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org>.
oleksii-novikov-onix commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245876292
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account (if payment involved)
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Income Liability Account
+ - Credit: Income from Buy Down Account
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
Review Comment:
Added
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "bharathcgowda (via GitHub)" <gi...@apache.org>.
bharathcgowda commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248002198
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
Review Comment:
charge off should debit - charge-off expense/charge-off expense- account no?
@adamsaghy cc
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248151331
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
Review Comment:
It does use `buyDownFeeAdjustment` command
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "bharathcgowda (via GitHub)" <gi...@apache.org>.
bharathcgowda commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2251272485
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
Review Comment:
we can add them afterwords
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org>.
oleksii-novikov-onix commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2250988777
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
Review Comment:
Fixed
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
Review Comment:
Fixed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org>.
oleksii-novikov-onix commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2250990492
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
Review Comment:
Changed this part to:
- Debit: Deferred Income Liability Account
- Credit: Charge-off Expense Account
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248141688
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
Review Comment:
The original transaction is not reversed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248163275
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
+7. **Balance Update**: Updates LoanBuyDownFeeBalance with new amount
+8. **Journal Entries**: Posts appropriate accounting entries for the adjustment
+9. **Business Events**: Triggers adjustment-related business events
+
+**Implementation Details**:
+
+- Uses standard loan transaction adjustment mechanism from `LoanTransactionsApiResource`
+- Leverages `CommandWrapperBuilder` for command processing
+- Integrates with `PortfolioCommandSourceWritePlatformService` for transaction handling
+- No special command parameter required (unlike creation which uses `?command=buyDownFee`)
+- Supports all four endpoint variants (internal/external ID combinations)
+
+=== Retrieve Buy Down Fee Amortization Details
+
+**Endpoint**: `GET /loans/{loanId}/buydown-fees`
+
+**Alternative**: `GET /loans/external-id/{loanExternalId}/buydown-fees`
+
+**Purpose**: Retrieves detailed amortization information for all Buy Down Fee transactions associated with a loan.
+
+**Request Parameters**: None (path parameters only)
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoint)
+|===
+
+_* Required only for external ID endpoint_
+
+**Response Structure**:
+[source,json]
+----
+[
+ {
+ "id": 1,
+ "loanId": 123,
+ "transactionId": 456,
+ "buyDownFeeDate": "2024-01-01",
+ "buyDownFeeAmount": 500.00,
+ "amortizedAmount": 125.00,
+ "notYetAmortizedAmount": 375.00,
+ "adjustedAmount": 0.00,
+ "chargedOffAmount": 0.00
+ }
+]
+----
+
+**Response Fields**:
+[cols="2,1,3", options="header"]
+|===
+|Field |Type |Description
+
+|`id`
+|Long
+|Buy Down Fee balance record identifier
+
+|`loanId`
+|Long
+|Internal loan identifier
+
+|`transactionId`
+|Long
+|Buy Down Fee transaction identifier
+
+|`buyDownFeeDate`
+|LocalDate
+|Date when Buy Down Fee was created
+
+|`buyDownFeeAmount`
+|BigDecimal
+|Original Buy Down Fee amount
+
+|`amortizedAmount`
+|BigDecimal
+|Amount already amortized to income
+
+|`notYetAmortizedAmount`
+|BigDecimal
+|Amount still to be amortized
+
+|`adjustedAmount`
+|BigDecimal
+|Total adjustment amount (if any)
+
+|`chargedOffAmount`
+|BigDecimal
+|Amount charged off (if loan was charged off)
+|===
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has read permission for LOAN resources
+2. **Loan Resolution**: For external ID endpoint, resolves loan ID using `ExternalIdFactory` and `LoanReadPlatformService`
+3. **Data Retrieval**: Calls `BuyDownFeeReadPlatformService.retrieveLoanBuyDownFeeAmortizationDetails()`
+4. **Response Assembly**: Returns array of `BuyDownFeeAmortizationDetails` objects
+5. **Security**: Ensures authenticated user context through `PlatformSecurityContext`
+
+=== Validation Rules
+
+**Common Validations**:
+
+- Buy Down Fee must be enabled for the loan product
+- Loan must be in active status
+- Client/Group must be active
+- Transaction date cannot be in the future
+- Transaction amount must be positive
+
+**Create Transaction Validations**:
+
+- Transaction date cannot be before first disbursement date
+- Loan must be disbursed
+- Only one Buy Down Fee transaction per loan (unless adjusted)
+
+**Adjustment Validations**:
+
+- Original Buy Down Fee transaction must exist
+- Adjustment amount cannot exceed remaining balance
+- Adjustment date cannot be before original transaction date
+- Cannot adjust if there are unreversed related transactions
Review Comment:
We can have multiple adjustments to the same buy down fee transaction
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "magyari-adam (via GitHub)" <gi...@apache.org>.
magyari-adam commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2248148724
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,637 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest/fee income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** and **NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+
+|`deferredIncomeLiabilityAccountId`
+|Yes*
+|GL Account ID for Deferred Income Liability Account used during amortization
+
+|`loanScheduleType`
+|Yes
+|Loan schedule type, must be set to "PROGRESSIVE" for Buy Down Fee
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
+ - Account Type: EXPENSE
+ - Purpose: Records the initial Buy Down Fee expense when transaction is created
+ - Journal Entry: Debit when Buy Down Fee is added
+
+* **Income from Buy Down Account** (`incomeFromBuyDownAccountId`)
+ - Account Type: INCOME
+ - Purpose: Records income recognition during daily amortization process
+ - Journal Entry: Credit during COB amortization
+
+==== Journal Entry Flow
+
+1. **Buy Down Fee Creation**:
+ - Debit: Buy Down Expense Account
+ - Credit: Cash/Bank Account
+
+2. **Daily Amortization** (via COB):
+ - Debit: Deferred Capitalized Income
+ - Credit: Fee/Interest Income Account
+
+3. **Buy Down Fee Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Buy Down Expense Account
+
+4. **Buy Down Fee Amortization Adjustment**:
+- Debit: Deferred Income Liability
+- Credit: Income from Buy Down Account
+
+5. **Charge-off Handling**:
+- Debit: Losses Written Off Account
+- Credit: Deferred Income Liability
+
+=== Validation Rules
+
+The system enforces the following validation rules:
+
+==== Product Level Validations
+
+* Buy Down Fee can only be enabled for Progressive Loan products
+* When `enableBuyDownFee` is `true`, all related parameters become mandatory
+* Calculation type must be `FLAT` (other types not yet supported)
+* Strategy must be `EQUAL_AMORTIZATION` (other strategies not yet supported)
+* Income type must be either `FEE` or `INTEREST`
+* Both expense and income GL accounts must be provided and valid
+* GL accounts must have correct account types (EXPENSE and INCOME respectively)
+* `deferredIncomeLiabilityAccountId` mapping requirements:
+ - Must be a valid LIABILITY type GL account
+ - Represents temporary holding of not-yet-recognized income
+ - Used to track unamortized Buy Down Fee portion
+ - Cannot be zero or null when Buy Down Fee is enabled
+
+==== Transaction Level Validations
+
+* Buy Down Fee transactions can only be added to active loans
+* Transaction amount must be positive (greater than zero)
+* Transaction date cannot be before the first disbursement date
+* Loan must have Buy Down Fee enabled in its product configuration
+
+==== Adjustment Validations
+
+A Buy Down Fee adjustment is a mechanism to modify an existing Buy Down Fee transaction after its initial creation. It allows financial institutions to:
+
+* Reduce the total Buy Down Fee amount
+* Correct errors in the initial fee calculation
+
+===== Adjustment Validations:
+
+* Adjustment amount cannot exceed the original Buy Down Fee amount
+* Total adjustments cannot exceed the remaining unadjusted amount
+* Adjustments can only be made to existing Buy Down Fee transactions
+* Standard payment details validation applies (payment type, notes, etc.)
+
+=== Configuration Examples
+
+==== Enabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": true,
+ "buyDownFeeCalculationType": "FLAT",
+ "buyDownFeeStrategy": "EQUAL_AMORTIZATION",
+ "buyDownFeeIncomeType": "FEE",
+ "buyDownExpenseAccountId": 123,
+ "incomeFromBuyDownAccountId": 456,
+ // ... other loan product parameters
+}
+----
+
+==== Disabling Buy Down Fee
+
+[source,json]
+----
+{
+ "enableBuyDownFee": false
+ // buyDownFee* parameters are optional when disabled
+}
+----
+
+=== Error Scenarios
+
+Common validation errors and their resolutions:
+
+* **"Buy Down Fee calculation type is required"**: Provide `buyDownFeeCalculationType` when enabling Buy Down Fee
+* **"Buy Down Fee strategy is required"**: Provide `buyDownFeeStrategy` when enabling Buy Down Fee
+* **"Buy Down Fee income type is required"**: Provide `buyDownFeeIncomeType` when enabling Buy Down Fee
+* **"Buy Down expense account is required"**: Provide valid `buyDownExpenseAccountId`
+* **"Income from Buy Down account is required"**: Provide valid `incomeFromBuyDownAccountId`
+* **"Buy Down fees can only be added to active loans"**: Ensure loan status is ACTIVE before adding Buy Down Fee transactions
+
+== API Endpoints
+
+=== Create Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions?command=buyDownFee`
+
+**Alternative**: `POST /loans/external-id/{loanExternalId}/transactions?command=buyDownFee`
+
+**Purpose**: Creates a new Buy Down Fee transaction for a loan, establishing the upfront merchant fee that will be amortized over the loan term.
+
+**Request Parameters**:
+[cols="1,1,1,3"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Transaction date in specified format (e.g., "dd MMMM yyyy")
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|Buy down fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Transaction note/description
+
+|`externalId`
+|String
+|No
+|External transaction identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "01 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 50.0,
+ "note": "Merchant fee for 0% interest loan"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 456,
+ "resourceExternalId": "ext-123",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. Validates that Buy Down Fee is enabled for the loan product
+2. Ensures transaction date is not before first disbursement date
+3. Verifies client/group is active
+4. Creates Buy Down Fee transaction with specified amount
+5. Establishes LoanBuyDownFeeBalance record for amortization tracking
+6. Posts journal entries (Debit: Buy Down Expense, Credit: Deferred Capitalized Income)
+7. Triggers business events for transaction creation and loan balance change
+
+=== Adjust Buy Down Fee Transaction
+
+**Endpoint**: `POST /loans/{loanId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+
+**Alternative Endpoints**:
+
+- `POST /loans/{loanId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/{transactionId}?command=buyDownFeeAdjustment`
+- `POST /loans/external-id/{loanExternalId}/transactions/external-id/{transactionExternalId}?command=buyDownFeeAdjustment`
+
+**Purpose**: Adjusts an existing Buy Down Fee transaction amount. This is effectively a reversal of the original transaction followed by creation of a new transaction with the adjusted amount.
+
+**Path Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`loanId`
+|Long
+|Yes*
+|Internal loan identifier
+
+|`loanExternalId`
+|String
+|Yes*
+|External loan identifier (alternative endpoints)
+
+|`transactionId`
+|Long
+|Yes*
+|Internal transaction identifier
+
+|`externalTransactionId`
+|String
+|Yes*
+|External transaction identifier (alternative endpoints)
+|===
+
+_* Required based on endpoint variant used_
+
+**Request Parameters**:
+[cols="2,1,1,3", options="header"]
+|===
+|Parameter |Type |Required |Description
+
+|`transactionDate`
+|String
+|Yes
+|Adjustment date in specified format
+
+|`dateFormat`
+|String
+|Yes
+|Date format specification (e.g., "dd MMMM yyyy")
+
+|`locale`
+|String
+|Yes
+|Locale for date formatting (e.g., "en")
+
+|`transactionAmount`
+|BigDecimal
+|Yes
+|New Buy Down Fee amount (must be positive)
+
+|`paymentTypeId`
+|Long
+|No
+|Payment type identifier
+
+|`note`
+|String
+|No
+|Adjustment note/description
+
+|`externalId`
+|String
+|No
+|External adjustment identifier
+|===
+
+**Request Example**:
+[source,json]
+----
+{
+ "transactionDate": "15 January 2024",
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en",
+ "transactionAmount": 25.0,
+ "note": "Partial adjustment of buy down fee"
+}
+----
+
+**Response Structure**:
+[source,json]
+----
+{
+ "loanId": 123,
+ "resourceId": 789,
+ "resourceExternalId": "adj-456",
+ "clientId": 789,
+ "officeId": 1
+}
+----
+
+**Business Logic**:
+
+1. **Permission Check**: Validates user has write permission for LOAN resources
+2. **Transaction Validation**: Ensures the referenced transaction exists and is a Buy Down Fee transaction
+3. **Amount Validation**: Validates adjustment amount doesn't exceed remaining buy down fee balance
+4. **Date Validation**: Ensures transaction date is not before original buy down fee transaction
+5. **Transaction Reversal**: Reverses the original Buy Down Fee transaction
+6. **New Transaction Creation**: Creates new Buy Down Fee transaction with adjusted amount
Review Comment:
Creates `Buy Down Fee Adjustment` transaction
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245260536
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
Review Comment:
Either:
"and amortized into interest/fee income over the life of the loan"
"and amortized into interest income over the life of the loan"
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
Review Comment:
The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer and NOT affecting the repayment schedule** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] FINERACT-2311: Add buydown fees documentation [fineract]
Posted by "oleksii-novikov-onix (via GitHub)" <gi...@apache.org>.
oleksii-novikov-onix commented on code in PR #4913:
URL: https://github.com/apache/fineract/pull/4913#discussion_r2245683139
##########
fineract-doc/src/docs/en/chapters/features/buydown-fee.adoc:
##########
@@ -0,0 +1,630 @@
+= Buy Down Fee
+
+== Overview
+
+Buy Down Fee is a specialized fee mechanism in Apache Fineract that allows financial institutions to collect upfront fees from borrowers to reduce their effective interest rate over the loan term. This feature is particularly designed for 0% interest "buy down" loans where a merchant fee is collected and amortized into interest income over the life of the loan.
+
+The key characteristic of Buy Down Fee is that the amortized fee is **NOT visible to the customer** - it operates as a background process for proper revenue recognition while maintaining transparency in customer-facing loan terms.
+
+=== Key Benefits
+
+* **Interest Rate Reduction**: Borrowers can reduce their effective interest rate by paying an upfront fee
+* **Merchant Fee Support**: Enables 0% interest loan products with merchant-paid fees
+* **Cash Flow Management**: Helps borrowers manage their payment obligations over time
+* **Revenue Recognition**: Provides controlled amortization of fee income over the loan term
+* **Customer Transparency**: Fee amortization is invisible to customers, maintaining clean loan presentation
+* **Flexible Loan Products**: Enables creation of diverse loan products to meet different customer needs
+* **Accounting Integration**: Proper journal entries and accounting treatment for fee transactions
+
+== Fee Types Overview
+
+Apache Fineract supports various fee calculation types across different product categories:
+
+=== Loan Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of loan principal
+* **Percent of Amount and Interest**: Percentage of principal plus interest
+* **Percent of Interest**: Percentage of interest amount only
+* **Percent of Disbursement Amount**: Percentage of disbursed amount
+
+=== Savings Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of account balance
+
+=== Client Fees
+* **Flat**: Fixed amount fee only
+
+=== Share Fees
+* **Flat**: Fixed amount fee
+* **Percent of Amount**: Percentage of share value
+
+== Buy Down Fee Configuration
+
+=== Prerequisites
+
+Before enabling Buy Down Fee functionality, ensure the following prerequisites are met:
+
+* **Loan Product Type**: Only Progressive Loan products support Buy Down Fee functionality
+* **Accounting Method**: Accrual accounting must be enabled for proper income recognition and amortization
+* **General Ledger Accounts**: Required GL accounts must be configured for expense and income mappings
+
+=== Required Configuration Parameters
+
+When creating or updating a loan product with Buy Down Fee enabled, the following parameters are mandatory:
+
+[cols="2,1,3", options="header"]
+|===
+|Parameter |Required |Description
+
+|`enableBuyDownFee`
+|Yes
+|Boolean flag to enable/disable Buy Down Fee functionality
+
+|`buyDownFeeCalculationType`
+|Yes*
+|Calculation method for Buy Down Fee. Currently only `FLAT` is supported
+
+|`buyDownFeeStrategy`
+|Yes*
+|Amortization strategy. Currently only `EQUAL_AMORTIZATION` is supported
+
+|`buyDownFeeIncomeType`
+|Yes*
+|Income recognition type: `FEE` or `INTEREST`
+
+|`buyDownExpenseAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee expense recognition
+
+|`incomeFromBuyDownAccountId`
+|Yes*
+|GL Account ID for Buy Down Fee income recognition during amortization
+|===
+
+_* Required only when `enableBuyDownFee` is set to `true`_
+
+=== Accounting Mappings
+
+Buy Down Fee requires specific GL account mappings for proper financial reporting:
+
+==== Required GL Accounts
+
+* **Buy Down Expense Account** (`buyDownExpenseAccountId`)
Review Comment:
It is just a different format of description, earlier in the table, it is described simply as an argument along with others. But here, it is described as GL Accounts, with account type and so on. I can remove this section if you want.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org