Files
cbsnexora-backend/CUSTOM_FIELDS_IMPLEMENTATION_SUMMARY.md
T

5.2 KiB

SavingsProduct Custom Fields - Implementation Summary

✅ Completed Changes

1. Validator Updates

File: fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductDataValidator.java

Changes:

  • Added balanceFrequency to SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS whitelist
  • Added accountClosedZeroBalanceInDayClosing to SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS whitelist

2. API Constants

File: fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java

Changes:

public static final String balanceFrequencyParamName = "balanceFrequency";
public static final String accountClosedZeroBalanceInDayClosingParamName = "accountClosedZeroBalanceInDayClosing";

3. Entity (Domain Model)

File: fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsProduct.java

Changes:

  • Added field: @Column(name = "balance_frequency", length = 50) private String balanceFrequency;
  • Added field: @Column(name = "account_closed_zero_balance_in_day_closing") private Boolean accountClosedZeroBalanceInDayClosing = false;
  • Added getters: getBalanceFrequency(), getAccountClosedZeroBalanceInDayClosing()
  • Added setters: setBalanceFrequency(), setAccountClosedZeroBalanceInDayClosing()
  • Added update logic in update() method to handle changes to these fields

4. Assembler

File: fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsProductAssembler.java

Changes:

if (command.parameterExists("balanceFrequency")) {
    product.setBalanceFrequency(command.stringValueOfParameterNamed("balanceFrequency"));
}
if (command.parameterExists("accountClosedZeroBalanceInDayClosing")) {
    product.setAccountClosedZeroBalanceInDayClosing(command.booleanObjectValueOfParameterNamed("accountClosedZeroBalanceInDayClosing"));
}

5. DTO (Data Transfer Object)

File: fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductData.java

Changes:

@Getter @Setter private String balanceFrequency;
@Getter @Setter private Boolean accountClosedZeroBalanceInDayClosing;

6. Read Platform Service

File: fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsProductReadPlatformServiceImpl.java

Changes:

  • SQL Query: Added sp.balance_frequency as balanceFrequency
  • SQL Query: Added sp.account_closed_zero_balance_in_day_closing as accountClosedZeroBalanceInDayClosing
  • ResultSet mapping: Added extraction of both fields

7. Database Migration

File: database_migration_add_custom_fields.sql

ALTER TABLE m_savings_product 
ADD COLUMN balance_frequency VARCHAR(50) DEFAULT NULL,
ADD COLUMN account_closed_zero_balance_in_day_closing BOOLEAN DEFAULT FALSE;

📋 What These Fields Do

balanceFrequency (String)

  • Purpose: Defines how often balance is calculated/checked
  • Example Values: "Daily", "Monthly", "Quarterly", "Yearly"
  • Database Column: m_savings_product.balance_frequency
  • Type: VARCHAR(50)

accountClosedZeroBalanceInDayClosing (Boolean)

  • Purpose: Flag to automatically close accounts when balance reaches zero at day end
  • Example Values: true or false
  • Default: false
  • Database Column: m_savings_product.account_closed_zero_balance_in_day_closing
  • Type: BOOLEAN

🎯 API Usage

POST /v1/savingsproducts (Create)

{
  "name": "Saving Product",
  "shortName": "SD22",
  // ... other fields ...
  "balanceFrequency": "Monthly",
  "accountClosedZeroBalanceInDayClosing": true,
  // ... rest of fields ...
}

GET /v1/savingsproducts/{productId} (Read)

Response will include:

{
  "id": 1,
  "name": "Saving Product",
  // ... other fields ...
  "balanceFrequency": "Monthly",
  "accountClosedZeroBalanceInDayClosing": true,
  // ... rest of fields ...
}

PUT /v1/savingsproducts/{productId} (Update)

{
  "balanceFrequency": "Quarterly",
  "accountClosedZeroBalanceInDayClosing": false
}

🗄️ Database Migration Steps

Run this SQL script to add the columns:

mysql -u root -p your_database < database_migration_add_custom_fields.sql

Or manually execute:

ALTER TABLE m_savings_product 
ADD COLUMN balance_frequency VARCHAR(50) DEFAULT NULL,
ADD COLUMN account_closed_zero_balance_in_day_closing BOOLEAN DEFAULT FALSE;

✅ Validation

The fields are now:

  • ✅ Accepted in CREATE request (POST)
  • ✅ Saved to database
  • ✅ Returned in GET response
  • ✅ Updatable via PUT request
  • ✅ Validated (no longer rejected as unsupported)

🚀 Next Steps

  1. Run Database Migration: Execute the SQL script
  2. Rebuild Application: ./gradlew clean build
  3. Restart Server: Apply the changes
  4. Test API: Use your payload to create a savings product

📝 Notes

  • Both fields are optional (nullable)
  • balanceFrequency accepts any string value (you can add validation later if needed)
  • accountClosedZeroBalanceInDayClosing defaults to false if not provided
  • Both fields support partial updates (you can update just one of them)