Important Instructions before Enabling this Configuration
What must you know before you enable this configuration?
This feature is only applicable for Simple Loans type of loan products and Child loans of the Master Facility that are also of the type Simple Loans.
Before you enable this configuration, it is important that you go through the following instructions:
You must not enable this configuration without the Q2 Loan Servicing product team's knowledge as this may require reimplementation of the code if you have any customizations.
Once you have enabled this configuration, you cannot disable it again.
-
You must make the following changes if you have custom implementations:
Caution:Please consult the Q2 Loan Servicing product team before you go ahead with the following changes.
-
If you have been querying amortization schedules in your custom code until now, then this needs to be replaced by using the following global methods or REST APIs that now access data from both sObject and big object:
-
Global methods:
LoanActionImpl3.getRepaymentSchedules();
RepaymentScheduleDataAccess.queryCurrentActiveSchedules(loanAccountIds)
RepaymentScheduleDataAccess.queryAllActiveSchedules(loanAccountIds)
RepaymentScheduleDataAccess.queryAllActiveSchedules(loanAccountIds, sortInASC)
RepaymentScheduleDataAccess.queryActiveSchedules(loanAccount, externalIds, fromDate, toDate)
RepaymentScheduleDataAccess.queryInactiveSchedules(loanAccount, externalIds)
RepaymentScheduleDataAccess.queryAllSchedules(loanIds)
RepaymentScheduleDataAccess.queryAllSchedules(loanIds, sortInASC)
-
REST APIs:
-
/services/apexrest/peer/v1/loanAccounts/getDetails/{loanId}
Note: For the preceding endpoint, if the storage optimization of amortization schedules is enabled, then on making a request to these endpoints, the repayment schedules will be returned in the response object (of the returned HTTP response) instead of the content object.
/services/apexrest/peer/v1/loanAccounts/amzSchedule/{loanId}
-
For more information on these, see the Q2 Loan Servicing Global Methods Guide and the Q2 Loan Servicing REST APIs Guide.
-
If you are using any third-party tools to fetch the amortization schedule data, you must replace it by using the product’s provided global methods instead.
-
If you are using any of the following fields just for viewing, then you will need to hide them. If you are using any of the following fields for calculations, then you must not use them and use your custom logic for the calculations instead.
This is because the value of these fields are based on the amortization schedules and as some of the amortization schedules are in sObject while rest are in big object, there would be a discrepancy in the actual and the expected values of these fields.
Note:If there are more fields like the following, such as more such custom fields, then do the same for these too.
-
Fields of the Loan Account object that are based on the schedules:
Repayment_Schedule_Count__c: This field gives the sum of schedules that are not archived. It is used in some areas to check whether schedules are generated or not for the respective contract.
Total_Interest_Amortization_Based__c: This field is the sum of the Due_Interest__c field of all un-archived schedules. It is not used anywhere in the code.
Number_Of_Past_Installments__c: This field gives the count of schedules where Schd.Past_Due_Date__c is true. It is not used anywhere in the code.
These fields, if used, will not display the correct value on the contract anymore since only limited number of schedules are stored in the sObject.
-
Fields of the Repayment Schedule object that are based on the Due Fee and Paid Fee:
Total_Paid_Fees__c: This field is the sum of Paid_Fee_Amount__c field that is available on Paid Fee object. This is being queried in the multiple queries but not being used anywhere in the product code.
Total_Due_Fees__c: This field is the sum of Due_Fee_Amount__c field that is available on Due Fee object. This is being used in the VF page printRepaymentSchedule to render the data in the PDF.
These fields, if used, will not display the correct value on the schedule after the enabling of the optimization.
-
Lookup fields of the following objects that lookup to the Repayment Schedule
Charge__c (no usage other than having lookup)
Interest_Posting_Transaction__c (For FAMZ contracts)
Loan_Payment_Collection__c (no usage)
Loan_Payment_Amz_Sched_Junction__c (for AMZ contracts)
These fields are linked to the repayment schedules and so, once the old schedules are deleted from the sObject and moved to big object, they will lose the link since the sObject schedule records would not exist as they would be deleted.
-
-
There may be times when the system has problems and you may need to restore the previous data. To accomplish this, you must first generate a backup of your data. Also, you may have a large amount of data that has to be backed up for safety reasons. Salesforce also backs up the data that is stored in the sObject, but it does not have the capability to back up the data that is stored in the big object.
For this reason, Q2 Loan Servicing has developed a system that allows you to successfully restore the data (amortization schedules) stored in the big object by introducing a field called External Id, which aids in tracing the amortization schedules of a contract. This Id is maintained in both the contract and the amortization schedule, forming a relationship between the two in the database. As a result, once the contract is restored, the system will use this Id to retrieve and restore the corresponding amortization schedules too.
More on the External Id:
All the schedules generated will have External Id generated and updated on the records. This is because during moving objects from big object to sObject and sObject to big object, the Salesforce generated Id will not be useful to map the schedules for the respective OLT, or any other external mapping if needed. So this External Id generated will be unique for a given record, whether it's stored in sObject or big object at any point of its life cycle, giving it a proper identification.
-
What is the fail-safe mechanism and what can you do if this fails?
The big objects database stores billions of records and is a distributed system that favors consistency over availability. The database is designed to ensure low-level consistency. When working with big data and writing batches of records using APIs or Apex, you may experience a partial batch failure where some records are written and others aren’t. Because the database is highly responsive and consistent at scale, this type of behavior is expected. Therefore, we need a fail-safe mechanism to avoid loss of data while inserting to and deleting from big objects. For this, Q2 Loan Servicing provides a fail-self mechanism.
The following steps are performed by the system as part of the fail-safe mechanism:
While inserting or deleting, if the records fail to get inserted or deleted, the system tries for a maximum of 5 times again to insert or delete.
If it fails even after that, the big object records are stored in the JSON format in a new object, Failed BigObject Dml.
-
Then the system marks the field, Repayment ScheduleBO Failure, of the Loan Parameters object, for the respective Loan Accounts, as true.
This makes sure that operations like rescheduling are restricted for the contract till the task of insertion or deletion is completed.
Once the records in the Failed BigObject Dml are fixed, the system runs the job: RetryRepaymentScheduleBOOperationsJob.
-
This job retries the inserts of the failed records, and after the successful insertion or deletion, it marks the Repayment ScheduleBO Failure field as false.
This job is a DAG-enabled job and hence, once added, can be automated to run.
If this job fails, and if you need to perform some action such as a rescheduling on a particular contract, then you can run this job manually for that contract.
How are the various actions going to get impacted if you enable this configuration?
Before you enable this configuration, as this configuration impacts repayment schedules storage, you must know where the schedules are used and how are some functions or values impacted. This is explained in the following table:
Loan Actions | Impact |
---|---|
Contract creation (Non-FIT) | At the time of contract creation, amortization schedules get generated. These schedules will be stored in sObject and big object as per the parameters defined in the org parameter while enabling this optimization. |
Disbursement (FIT) or Principal Adjustment and its reversal |
At the first disbursal or at every disbursal in an FIT loan, the schedules are generated or regenerated respectively. And when these disbursements are reversed, the new schedules are generated and the old schedules that are marked archived are deleted. The system will archive the old schedules and move them to the big object and re-generate the new schedules and store them into the sObject and big object as per the parameters defined in the org parameter while enabling this optimization. In case of FIT loans, all the schedules greater than transaction date are used from the sobject or big obect as they need to be archived. For Disbursal Reversal, in case of FIT, all old schedules are required for deletion of records. |
Payments |
There is no impact on current dated payments as schedules are only used from the transaction date to system date and the next immediate schedule. But in case of back dated payments, schedules in the past are also used from the transaction date of the payment. So if the Store Schedules Before Fixed Period Of field is configured, validation is added to allow back dated payments only till the oldest schedule date present in the sObject. |
Reschedule and Rate Change actions |
When a loan contract is rescheduled, the system generates new schedules and the old are archived. When this rescheduling is reversed, the old archived schedules are made active and the new schedules are archived. The system will archive the old schedules and move them to the big object and re-generate the new schedules and store them into the sObject and big object as per the parameters defined in the org parameter while enabling this optimization. During rescheduling, all the current active schedules after the transaction date will be queried from the sObject and big object, and will be marked archived and stored in big object, and new schedules generated are again stored in sObject and big object based on the parameters defined in the org parameter while enabling this optimization. (Transaction Date is considered here because if Maintain Delinquency is set to true, the past schedules are already billed. It is thus not needed them to be archived. But in case of Maintain Delinquency false, the past unpaid schedules are also archived. These archived schedules are stored in big object.) The External Ids of the schedules being marked archived will be stored in the snapshot of schedules, instead of actual IDs of the records. During reversal, the data from the big object are queried using the External Id values stored in the snapshot and processed for reversal. These records are marked as active, and again stored in the sObject and big objects based on the configuration. The current active records will be deleted. |
Payoff Quote |
The schedules are used in the following areas:
Hence, the impact. |
Floating Rate Revision Job | The system will archive the old schedules and move them to the big object and re-generate the new schedules and store them into the sObject and big object as per the parameters defined in the org parameter while enabling this optimization. |
Billing Job or Interest Posting Job or Investment Order |
The system uses schedules between Previous and Next Installment Date and the next immediate schedule. In case of an Investment Order, it uses schedules between Previous Investment IPT Date till the current system date. Hence, the impact. |
Broker Commission Job | During the broker commission calculation, the schedules are required in between Previous Commission Posting Date till the current system date and the next immediate schedule. |
Fee Accrual |
Calculation of fee accrual will depend on both sObject and big object schedule data, unlike only sObject before the enabling. To create a Fee accrual entries, the system needs schedules from last accrual date to the current system date and for some cases the next immediate schedule. In case of Prepaid fee, to generate the stream and show the list of the accrual entries, the system needs all future schedules to calculate the accrual entries. |
InterestAndBalanceDiagnostic Job |
This job needs transactions or events from the start of the application if it is running for the first time in the system. However, in case of Advance Interest, InterestAndBalanceDiagnostic Job needs schedules from advance interest posting date to the next interest posting date, but if the schedule moves from sObject to big object, then InterestAndBalanceDiagnostic Job will not run from the start of the application date of contract. |
UI Pages |
The pages that are being used to display the repayment schedules will fetch data from both sObject and BigObject. For examples Fee Stream Page, Consolidated schedules Page, Print Repayment Schedule Page PDF, and more. |
Market Place |
Following are the REST APIs where loan Repayment Schedules are being used and will be now queried from the sObject and big object:
|