@crediblex.io/fineract-api-client 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/fineract-creditlines-api.d.ts +95 -0
- package/dist/api/fineract-creditlines-api.d.ts.map +1 -0
- package/dist/api/fineract-creditlines-api.js +196 -0
- package/dist/api/fineract-creditlines-api.js.map +1 -0
- package/dist/api/fineract-datatable-api.d.ts +64 -0
- package/dist/api/fineract-datatable-api.d.ts.map +1 -0
- package/dist/api/fineract-datatable-api.js +146 -0
- package/dist/api/fineract-datatable-api.js.map +1 -0
- package/dist/api/fineract-holidays-api.d.ts +29 -0
- package/dist/api/fineract-holidays-api.d.ts.map +1 -0
- package/dist/api/fineract-holidays-api.js +57 -0
- package/dist/api/fineract-holidays-api.js.map +1 -0
- package/dist/api/fineract-loanproducts-api.d.ts +57 -0
- package/dist/api/fineract-loanproducts-api.d.ts.map +1 -0
- package/dist/api/fineract-loanproducts-api.js +140 -0
- package/dist/api/fineract-loanproducts-api.js.map +1 -0
- package/dist/api/fineract-loansaccounts-api.d.ts +77 -0
- package/dist/api/fineract-loansaccounts-api.d.ts.map +1 -0
- package/dist/api/fineract-loansaccounts-api.js +209 -0
- package/dist/api/fineract-loansaccounts-api.js.map +1 -0
- package/dist/api/fineract-reports-api.d.ts +33 -0
- package/dist/api/fineract-reports-api.d.ts.map +1 -0
- package/dist/api/fineract-reports-api.js +94 -0
- package/dist/api/fineract-reports-api.js.map +1 -0
- package/dist/api/fineract-savingsaccounts-api.d.ts +59 -0
- package/dist/api/fineract-savingsaccounts-api.d.ts.map +1 -0
- package/dist/api/fineract-savingsaccounts-api.js +141 -0
- package/dist/api/fineract-savingsaccounts-api.js.map +1 -0
- package/dist/api/fineract-savingsproducts-api.d.ts +86 -0
- package/dist/api/fineract-savingsproducts-api.d.ts.map +1 -0
- package/dist/api/fineract-savingsproducts-api.js +184 -0
- package/dist/api/fineract-savingsproducts-api.js.map +1 -0
- package/dist/api/fineract-sme-api.d.ts +39 -0
- package/dist/api/fineract-sme-api.d.ts.map +1 -0
- package/dist/api/fineract-sme-api.js +82 -0
- package/dist/api/fineract-sme-api.js.map +1 -0
- package/dist/api/fineract-workingdays-api.d.ts +28 -0
- package/dist/api/fineract-workingdays-api.d.ts.map +1 -0
- package/dist/api/fineract-workingdays-api.js +84 -0
- package/dist/api/fineract-workingdays-api.js.map +1 -0
- package/dist/examples/run-examples.d.ts +2 -0
- package/dist/examples/run-examples.d.ts.map +1 -0
- package/dist/examples/run-examples.js +868 -0
- package/dist/examples/run-examples.js.map +1 -0
- package/dist/fineract-sdk.d.ts +50 -0
- package/dist/fineract-sdk.d.ts.map +1 -0
- package/dist/fineract-sdk.js +55 -0
- package/dist/fineract-sdk.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/types/creditlines.d.ts +271 -0
- package/dist/types/creditlines.d.ts.map +1 -0
- package/dist/types/creditlines.js +3 -0
- package/dist/types/creditlines.js.map +1 -0
- package/dist/types/datatable.d.ts +36 -0
- package/dist/types/datatable.d.ts.map +1 -0
- package/dist/types/datatable.js +3 -0
- package/dist/types/datatable.js.map +1 -0
- package/dist/types/errors.d.ts +7 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +17 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/holidays.d.ts +32 -0
- package/dist/types/holidays.d.ts.map +1 -0
- package/dist/types/holidays.js +3 -0
- package/dist/types/holidays.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +25 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/loanproducts.d.ts +1 -0
- package/dist/types/loanproducts.d.ts.map +1 -0
- package/dist/types/loanproducts.js +2 -0
- package/dist/types/loanproducts.js.map +1 -0
- package/dist/types/loansaccounts.d.ts +195 -0
- package/dist/types/loansaccounts.d.ts.map +1 -0
- package/dist/types/loansaccounts.js +3 -0
- package/dist/types/loansaccounts.js.map +1 -0
- package/dist/types/reports.d.ts +49 -0
- package/dist/types/reports.d.ts.map +1 -0
- package/dist/types/reports.js +4 -0
- package/dist/types/reports.js.map +1 -0
- package/dist/types/savingsaccounts.d.ts +145 -0
- package/dist/types/savingsaccounts.d.ts.map +1 -0
- package/dist/types/savingsaccounts.js +3 -0
- package/dist/types/savingsaccounts.js.map +1 -0
- package/dist/types/savingsproducts.d.ts +83 -0
- package/dist/types/savingsproducts.d.ts.map +1 -0
- package/dist/types/savingsproducts.js +3 -0
- package/dist/types/savingsproducts.js.map +1 -0
- package/dist/types/sme.d.ts +68 -0
- package/dist/types/sme.d.ts.map +1 -0
- package/dist/types/sme.js +3 -0
- package/dist/types/sme.js.map +1 -0
- package/dist/types/workingdays.d.ts +41 -0
- package/dist/types/workingdays.d.ts.map +1 -0
- package/dist/types/workingdays.js +3 -0
- package/dist/types/workingdays.js.map +1 -0
- package/dist/utils/http-client.d.ts +29 -0
- package/dist/utils/http-client.d.ts.map +1 -0
- package/dist/utils/http-client.js +93 -0
- package/dist/utils/http-client.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,868 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("../index");
|
|
4
|
+
// Configuration for the Fineract SDK
|
|
5
|
+
const sdkConfig = {
|
|
6
|
+
// baseURL: "https://localhost:8443", // Your Fineract base URL
|
|
7
|
+
baseURL: "https://fineract-api.uat.crediblex.io",
|
|
8
|
+
tenantId: "default", // Your Fineract tenant ID
|
|
9
|
+
username: "haider", // Your Fineract username
|
|
10
|
+
password: "bex!BZQ3phw0zyf-caj", // Your Fineract password
|
|
11
|
+
timeout: 60000, // Optional: request timeout in milliseconds
|
|
12
|
+
};
|
|
13
|
+
// Create an instance of the Fineract SDK
|
|
14
|
+
const fineractSDK = (0, index_1.createFineractSDK)(sdkConfig);
|
|
15
|
+
async function createAndFetchSme() {
|
|
16
|
+
console.log("Attempting to create a new sme...");
|
|
17
|
+
const newSmeData = {
|
|
18
|
+
officeId: 1,
|
|
19
|
+
fullname: "Client created by API",
|
|
20
|
+
active: true,
|
|
21
|
+
activationDate: "2024-07-28",
|
|
22
|
+
dateFormat: "yyyy-MM-dd",
|
|
23
|
+
locale: "en",
|
|
24
|
+
legalFormId: 1,
|
|
25
|
+
externalId: "C1",
|
|
26
|
+
};
|
|
27
|
+
let createdSmeId;
|
|
28
|
+
let createdSmeExternalId;
|
|
29
|
+
try {
|
|
30
|
+
const createResponse = await fineractSDK.sme.create(newSmeData);
|
|
31
|
+
console.log("SME created successfully!");
|
|
32
|
+
console.log("Response:", JSON.stringify(createResponse, null, 2));
|
|
33
|
+
createdSmeId = createResponse.clientId;
|
|
34
|
+
createdSmeExternalId = createResponse.resourceExternalId;
|
|
35
|
+
if (!createdSmeId) {
|
|
36
|
+
console.error("Could not determine created sme ID from response:", createResponse);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
console.log(`Created sme ID: ${createdSmeId}`);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
const err = error;
|
|
43
|
+
console.error("Message:", err.message);
|
|
44
|
+
console.error("Details:", JSON.stringify(err.details, null, 2));
|
|
45
|
+
console.error("Status Code:", err.statusCode);
|
|
46
|
+
return; // Stop if sme creation fails
|
|
47
|
+
}
|
|
48
|
+
if (createdSmeId) {
|
|
49
|
+
console.log(`\nAttempting to fetch details for sme ID: ${createdSmeId}...`);
|
|
50
|
+
try {
|
|
51
|
+
const smeDetails1 = await fineractSDK.sme.getDetails(createdSmeId);
|
|
52
|
+
const smeDetails2 = await fineractSDK.sme.getDetailsByExternalId(createdSmeExternalId);
|
|
53
|
+
console.log("SME details retrieved successfully!");
|
|
54
|
+
console.log("Details 1:", JSON.stringify(smeDetails1, null, 2));
|
|
55
|
+
console.log("Details 2:", JSON.stringify(smeDetails2, null, 2));
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
const err = error;
|
|
59
|
+
console.error(`Error fetching sme details for ID ${createdSmeId}:`, err.error);
|
|
60
|
+
console.error("Message:", err.message);
|
|
61
|
+
console.error("Details:", JSON.stringify(err.details, null, 2));
|
|
62
|
+
console.error("Status Code:", err.statusCode);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function fetchDatatable() {
|
|
67
|
+
const datatable = await fineractSDK.datatable.getByName("m_client_extended");
|
|
68
|
+
const datatableEntries = await fineractSDK.datatable.getEntries("m_client_extended", 1);
|
|
69
|
+
console.log("Datatable:", JSON.stringify(datatable, null, 2));
|
|
70
|
+
console.log("Datatable entries:", JSON.stringify(datatableEntries, null, 2));
|
|
71
|
+
}
|
|
72
|
+
async function fetchLoanProducts() {
|
|
73
|
+
const loanProducts = await fineractSDK.loanproducts.getAll();
|
|
74
|
+
console.log("Loan products:", JSON.stringify(loanProducts, null, 2));
|
|
75
|
+
}
|
|
76
|
+
async function fetchSavingsProducts() {
|
|
77
|
+
const savingsProducts = await fineractSDK.savingsproducts.getAll();
|
|
78
|
+
console.log("Savings products:", JSON.stringify(savingsProducts, null, 2));
|
|
79
|
+
}
|
|
80
|
+
async function createSavingsAccount() {
|
|
81
|
+
const savingsProducts = await fineractSDK.savingsproducts.getAll();
|
|
82
|
+
// Create fallback savings account
|
|
83
|
+
const fallbackSavingsProduct = savingsProducts.find((product) => product.shortName === "FBSA");
|
|
84
|
+
console.log("Fallback savings product:", JSON.stringify(fallbackSavingsProduct, null, 2));
|
|
85
|
+
if (!fallbackSavingsProduct) {
|
|
86
|
+
console.error("Fallback savings product not found");
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const savingsAccount = await fineractSDK.savingsaccounts.create({
|
|
90
|
+
clientId: 430, // saved from a response of fineractSDK.sme.create(newSmeData);
|
|
91
|
+
productId: fallbackSavingsProduct.id,
|
|
92
|
+
submittedOnDate: "2024-07-28",
|
|
93
|
+
dateFormat: "yyyy-MM-dd",
|
|
94
|
+
locale: "en",
|
|
95
|
+
});
|
|
96
|
+
console.log("Savings account created:", JSON.stringify(savingsAccount, null, 2));
|
|
97
|
+
// Approve the savings account
|
|
98
|
+
const approvalResponse = await fineractSDK.savingsproducts.approve(savingsAccount.savingsId, {
|
|
99
|
+
approvedOnDate: "2024-06-19",
|
|
100
|
+
dateFormat: "yyyy-MM-dd",
|
|
101
|
+
locale: "en",
|
|
102
|
+
});
|
|
103
|
+
console.log("Savings account approved:", JSON.stringify(approvalResponse, null, 2));
|
|
104
|
+
// Activate the savings account
|
|
105
|
+
const activationResponse = await fineractSDK.savingsproducts.activate(savingsAccount.savingsId, {
|
|
106
|
+
activatedOnDate: "2024-06-19",
|
|
107
|
+
dateFormat: "yyyy-MM-dd",
|
|
108
|
+
locale: "en",
|
|
109
|
+
});
|
|
110
|
+
console.log("Savings account activated:", JSON.stringify(activationResponse, null, 2));
|
|
111
|
+
}
|
|
112
|
+
async function calculateLoanRepaymentSchedule() {
|
|
113
|
+
const loanRepaymentSchedule = await fineractSDK.loansaccounts.getRepaymentSchedule({
|
|
114
|
+
productId: 1,
|
|
115
|
+
// loanOfficerId: "",
|
|
116
|
+
// loanPurposeId: "",
|
|
117
|
+
// fundId: "",
|
|
118
|
+
submittedOnDate: "28 May 2025",
|
|
119
|
+
expectedDisbursementDate: "30 May 2025",
|
|
120
|
+
// externalId: "",
|
|
121
|
+
// linkAccountId: "",
|
|
122
|
+
// createStandingInstructionAtDisbursement: "",
|
|
123
|
+
loanTermFrequency: 3,
|
|
124
|
+
loanTermFrequencyType: 2,
|
|
125
|
+
numberOfRepayments: 3,
|
|
126
|
+
repaymentEvery: 1,
|
|
127
|
+
repaymentFrequencyType: 2,
|
|
128
|
+
// repaymentFrequencyNthDayType: "",
|
|
129
|
+
// repaymentFrequencyDayOfWeekType: "",
|
|
130
|
+
// repaymentsStartingFromDate: null,
|
|
131
|
+
// interestChargedFromDate: null,
|
|
132
|
+
interestType: 0,
|
|
133
|
+
// isEqualAmortization: false,
|
|
134
|
+
amortizationType: 1,
|
|
135
|
+
interestCalculationPeriodType: 1,
|
|
136
|
+
// loanIdToClose: "",
|
|
137
|
+
// isTopup: "",
|
|
138
|
+
transactionProcessingStrategyCode: "creocore-strategy",
|
|
139
|
+
// interestRateFrequencyType: 3,
|
|
140
|
+
interestRatePerPeriod: 1,
|
|
141
|
+
// charges: [],
|
|
142
|
+
// collateral: [],
|
|
143
|
+
dateFormat: "dd MMMM yyyy",
|
|
144
|
+
locale: "en",
|
|
145
|
+
clientId: 1,
|
|
146
|
+
loanType: "individual",
|
|
147
|
+
principal: 100000,
|
|
148
|
+
// allowPartialPeriodInterestCalcualtion: false,
|
|
149
|
+
});
|
|
150
|
+
console.log("Loan repayment schedule created:", JSON.stringify(loanRepaymentSchedule, null, 2));
|
|
151
|
+
}
|
|
152
|
+
// Run the example
|
|
153
|
+
// createAndFetchSme()
|
|
154
|
+
// .then(() => console.log("\nExample finished."))
|
|
155
|
+
// .catch((e) => console.error("Unhandled error in example script:", e));
|
|
156
|
+
// fetchDatatable()
|
|
157
|
+
// .then(() => console.log("\nExample finished."))
|
|
158
|
+
// .catch((e) => console.error("Unhandled error in example script:", e));
|
|
159
|
+
// fetchLoanProducts()
|
|
160
|
+
// .then(() => console.log("\nExample finished."))
|
|
161
|
+
// .catch((e) => console.error("Unhandled error in example script:", e));
|
|
162
|
+
// fetchSavingsProducts()
|
|
163
|
+
// .then(() => console.log("\nExample finished."))
|
|
164
|
+
// .catch((e) => console.error("Unhandled error in example script:", e));
|
|
165
|
+
// createSavingsAccount()
|
|
166
|
+
// .then(() => console.log("\nExample finished."))
|
|
167
|
+
// .catch((e) => console.error("Unhandled error in example script:", e));
|
|
168
|
+
// calculateLoanRepaymentSchedule()
|
|
169
|
+
// .then(() => console.log("\nExample finished."))
|
|
170
|
+
// .catch((e) => console.error("Unhandled error in example script:", e));
|
|
171
|
+
async function completeWorkflowExample() {
|
|
172
|
+
console.log("=== Starting Complete Workflow ===\n");
|
|
173
|
+
try {
|
|
174
|
+
console.log("Step 1: Creating SME Client...");
|
|
175
|
+
const smeResponse = await fineractSDK.sme.create({
|
|
176
|
+
officeId: 1, // Hardcoded to 1 because currently we only have head office
|
|
177
|
+
fullname: "haider 9 july 2025 test-api-client-5",
|
|
178
|
+
active: true, // Hardcoded to always true
|
|
179
|
+
activationDate: "2024-07-28",
|
|
180
|
+
dateFormat: "yyyy-MM-dd",
|
|
181
|
+
locale: "en",
|
|
182
|
+
legalFormId: 2, // Hardcoded to 2 meaning client in fineract language
|
|
183
|
+
externalId: "LOS-EXT-H5",
|
|
184
|
+
});
|
|
185
|
+
const clientId = smeResponse.clientId;
|
|
186
|
+
console.log("✓ SME Client Created with ID:", clientId);
|
|
187
|
+
// console.log("SME Response:", JSON.stringify(smeResponse, null, 2));
|
|
188
|
+
console.log();
|
|
189
|
+
console.log("Skipping virtual account number and remitter details for now");
|
|
190
|
+
// // Step 2: Add Virtual Account Number (Datatables API)
|
|
191
|
+
// console.log("Step 2: Adding Virtual Account Number...");
|
|
192
|
+
// await fineractSDK.datatable.createEntry("dt_client_virtual_account_number",
|
|
193
|
+
// client_id: clientId,
|
|
194
|
+
// virtualAccountNumber: 123456789,
|
|
195
|
+
// );
|
|
196
|
+
// console.log("✓ Virtual Account Number added successfully");
|
|
197
|
+
// console.log();
|
|
198
|
+
// // Step 2.1: Add Remitter Details (for RBF enabled SMEs)
|
|
199
|
+
// console.log("Step 2.1: Adding Remitter Details (RBF)...");
|
|
200
|
+
// await fineractSDK.datatable.addEntry("dt_client_remitter_names", {
|
|
201
|
+
// client_id: clientId,
|
|
202
|
+
// remitterName: "Example Remitter Name", // replace with actual remitter name
|
|
203
|
+
// });
|
|
204
|
+
// console.log("✓ Remitter Details added successfully");
|
|
205
|
+
// console.log();
|
|
206
|
+
// First get all savings products to find fallback product ID
|
|
207
|
+
const savingsProducts = await fineractSDK.savingsproducts.getAll();
|
|
208
|
+
const fallbackProduct = savingsProducts.find((product) => product.shortName === "FBSA");
|
|
209
|
+
const FALLBACK_PRODUCT_ID = fallbackProduct?.id || 1; // fallback to 1 if not found
|
|
210
|
+
console.log("Step 3: Creating Fallback Savings Account with product ID:", FALLBACK_PRODUCT_ID);
|
|
211
|
+
const fallbackAccount = await fineractSDK.savingsaccounts.create({
|
|
212
|
+
clientId: clientId,
|
|
213
|
+
productId: FALLBACK_PRODUCT_ID,
|
|
214
|
+
submittedOnDate: "2024-07-28",
|
|
215
|
+
dateFormat: "yyyy-MM-dd",
|
|
216
|
+
locale: "en",
|
|
217
|
+
});
|
|
218
|
+
const fallbackAccountId = fallbackAccount.resourceId;
|
|
219
|
+
console.log("✓ Fallback Savings Account Created with ID:", fallbackAccountId);
|
|
220
|
+
// Approve fallback account
|
|
221
|
+
await fineractSDK.savingsproducts.approve(fallbackAccountId, {
|
|
222
|
+
approvedOnDate: "2024-07-28",
|
|
223
|
+
dateFormat: "yyyy-MM-dd",
|
|
224
|
+
locale: "en",
|
|
225
|
+
});
|
|
226
|
+
console.log("✓ Fallback Savings Account Approved");
|
|
227
|
+
// Activate fallback account
|
|
228
|
+
await fineractSDK.savingsproducts.activate(fallbackAccountId, {
|
|
229
|
+
activatedOnDate: "2024-07-28",
|
|
230
|
+
dateFormat: "yyyy-MM-dd",
|
|
231
|
+
locale: "en",
|
|
232
|
+
});
|
|
233
|
+
console.log("✓ Fallback Account Activated");
|
|
234
|
+
console.log();
|
|
235
|
+
// Find cash margin product ID
|
|
236
|
+
const cashMarginProduct = savingsProducts.find((product) => product.shortName === "CMSA");
|
|
237
|
+
const CASH_MARGIN_PRODUCT_ID = cashMarginProduct?.id || 2; // fallback to 2 if not found
|
|
238
|
+
console.log("Step 4: Creating Cash Margin Account with product ID:", CASH_MARGIN_PRODUCT_ID);
|
|
239
|
+
// Create cash margin account
|
|
240
|
+
const cashMarginAccount = await fineractSDK.savingsaccounts.create({
|
|
241
|
+
clientId: clientId,
|
|
242
|
+
productId: CASH_MARGIN_PRODUCT_ID,
|
|
243
|
+
submittedOnDate: "2024-07-28",
|
|
244
|
+
dateFormat: "yyyy-MM-dd",
|
|
245
|
+
locale: "en",
|
|
246
|
+
});
|
|
247
|
+
const cashMarginAccountId = cashMarginAccount.resourceId;
|
|
248
|
+
console.log("✓ Cash Margin Account Created with ID:", cashMarginAccountId);
|
|
249
|
+
// Approve cash margin account
|
|
250
|
+
await fineractSDK.savingsproducts.approve(cashMarginAccountId, {
|
|
251
|
+
approvedOnDate: "2024-07-28",
|
|
252
|
+
dateFormat: "yyyy-MM-dd",
|
|
253
|
+
locale: "en",
|
|
254
|
+
});
|
|
255
|
+
console.log("✓ Cash Margin Account Approved");
|
|
256
|
+
// Activate cash margin account
|
|
257
|
+
await fineractSDK.savingsproducts.activate(cashMarginAccountId, {
|
|
258
|
+
activatedOnDate: "2024-07-28",
|
|
259
|
+
dateFormat: "yyyy-MM-dd",
|
|
260
|
+
locale: "en",
|
|
261
|
+
});
|
|
262
|
+
console.log("✓ Cash Margin Account Activated");
|
|
263
|
+
console.log();
|
|
264
|
+
// Find RBF collection product ID
|
|
265
|
+
const rbfProduct = savingsProducts.find((product) => product.shortName === "RBF");
|
|
266
|
+
const RBF_COLLECTION_PRODUCT_ID = rbfProduct?.id || 3; // fallback to 3 if not found
|
|
267
|
+
console.log("Step 5: Creating RBF Collection Account with product ID:", RBF_COLLECTION_PRODUCT_ID);
|
|
268
|
+
// Create RBF collection account
|
|
269
|
+
const rbfCollectionAccount = await fineractSDK.savingsaccounts.create({
|
|
270
|
+
clientId: clientId,
|
|
271
|
+
productId: RBF_COLLECTION_PRODUCT_ID,
|
|
272
|
+
submittedOnDate: "2024-07-28",
|
|
273
|
+
dateFormat: "yyyy-MM-dd",
|
|
274
|
+
locale: "en",
|
|
275
|
+
});
|
|
276
|
+
const rbfCollectionAccountId = rbfCollectionAccount.resourceId;
|
|
277
|
+
console.log("✓ RBF Collection Account Created with ID:", rbfCollectionAccountId);
|
|
278
|
+
// Approve RBF collection account
|
|
279
|
+
await fineractSDK.savingsproducts.approve(rbfCollectionAccountId, {
|
|
280
|
+
approvedOnDate: "2024-07-28",
|
|
281
|
+
dateFormat: "yyyy-MM-dd",
|
|
282
|
+
locale: "en",
|
|
283
|
+
});
|
|
284
|
+
console.log("✓ RBF Collection Account Approved");
|
|
285
|
+
// Activate RBF collection account
|
|
286
|
+
await fineractSDK.savingsproducts.activate(rbfCollectionAccountId, {
|
|
287
|
+
activatedOnDate: "2024-07-28",
|
|
288
|
+
dateFormat: "yyyy-MM-dd",
|
|
289
|
+
locale: "en",
|
|
290
|
+
});
|
|
291
|
+
console.log("✓ RBF Collection Account Activated");
|
|
292
|
+
console.log();
|
|
293
|
+
// Step 6: Create Loan Account
|
|
294
|
+
console.log("Step 6: Creating Loan Account...");
|
|
295
|
+
// Get all loan products to find RBF product
|
|
296
|
+
const loanProducts = await fineractSDK.loanproducts.getAll();
|
|
297
|
+
const rbfLoanProduct = loanProducts.find((product) => product.externalId === "REVENUE_BASED_FINANCING");
|
|
298
|
+
const RBF_LOAN_PRODUCT_ID = rbfLoanProduct?.id || 1; // fallback to 1 if not found
|
|
299
|
+
const newLoan = await fineractSDK.loansaccounts.create({
|
|
300
|
+
productId: RBF_LOAN_PRODUCT_ID,
|
|
301
|
+
linkAccountId: rbfCollectionAccountId.toString(), // Link to the collection account created above
|
|
302
|
+
submittedOnDate: "2025-07-09",
|
|
303
|
+
expectedDisbursementDate: "2025-07-10",
|
|
304
|
+
loanTermFrequency: 3,
|
|
305
|
+
loanTermFrequencyType: 2, // Months
|
|
306
|
+
numberOfRepayments: 3,
|
|
307
|
+
repaymentEvery: 1,
|
|
308
|
+
repaymentFrequencyType: 2, // Months
|
|
309
|
+
interestType: 0, // Flat
|
|
310
|
+
amortizationType: 1, // Equal installments
|
|
311
|
+
interestCalculationPeriodType: 1,
|
|
312
|
+
transactionProcessingStrategyCode: "mifos-standard-strategy",
|
|
313
|
+
interestRatePerPeriod: 1, // 10%
|
|
314
|
+
dateFormat: "yyyy-MM-dd",
|
|
315
|
+
locale: "en",
|
|
316
|
+
clientId: clientId,
|
|
317
|
+
loanType: "individual",
|
|
318
|
+
principal: 100000, // 100,000 principal amount
|
|
319
|
+
datatables: [
|
|
320
|
+
{
|
|
321
|
+
registeredTableName: "dt_loan_remitter_dp_info",
|
|
322
|
+
data: {
|
|
323
|
+
locale: "en",
|
|
324
|
+
remitter_name: "",
|
|
325
|
+
dp_name: "",
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
],
|
|
329
|
+
});
|
|
330
|
+
console.log("✓ Loan Account Created successfully!");
|
|
331
|
+
console.log("Loan Details:", JSON.stringify(newLoan, null, 2));
|
|
332
|
+
console.log();
|
|
333
|
+
console.log("=== Complete SME Workflow Finished Successfully! ===");
|
|
334
|
+
console.log(`Client ID: ${clientId}`);
|
|
335
|
+
console.log(`Fallback Account ID: ${fallbackAccountId}`);
|
|
336
|
+
console.log(`Cash Margin Account ID: ${cashMarginAccountId}`);
|
|
337
|
+
console.log(`RBF Collection Account ID: ${rbfCollectionAccountId}`);
|
|
338
|
+
console.log(`Loan Account ID: ${newLoan.loanId || newLoan.resourceId}`);
|
|
339
|
+
}
|
|
340
|
+
catch (error) {
|
|
341
|
+
console.error("❌ Error in complete workflow:", error);
|
|
342
|
+
// Log detailed error information including validation errors
|
|
343
|
+
if (error instanceof Error && "details" in error) {
|
|
344
|
+
const fineractError = error;
|
|
345
|
+
console.log("=== Detailed Error Information ===");
|
|
346
|
+
console.log("Error Message:", fineractError.message);
|
|
347
|
+
console.log("Status Code:", fineractError.statusCode);
|
|
348
|
+
if (fineractError.details?.errors &&
|
|
349
|
+
Array.isArray(fineractError.details.errors)) {
|
|
350
|
+
console.log("\n=== Validation Errors ===");
|
|
351
|
+
fineractError.details.errors.forEach((validationError, index) => {
|
|
352
|
+
console.log(`Error ${index + 1}:`);
|
|
353
|
+
console.log(` Field: ${validationError.parameterName || "Unknown"}`);
|
|
354
|
+
console.log(` Value: ${validationError.value !== undefined
|
|
355
|
+
? validationError.value
|
|
356
|
+
: "N/A"}`);
|
|
357
|
+
console.log(` Message: ${validationError.defaultUserMessage ||
|
|
358
|
+
validationError.userMessageGlobalisationCode ||
|
|
359
|
+
"No message"}`);
|
|
360
|
+
console.log(` Code: ${validationError.userMessageGlobalisationCode || "No code"}`);
|
|
361
|
+
if (validationError.supportedParameters) {
|
|
362
|
+
console.log(` Supported Parameters: ${JSON.stringify(validationError.supportedParameters)}`);
|
|
363
|
+
}
|
|
364
|
+
console.log("---");
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
if (fineractError.details?.developerMessage) {
|
|
368
|
+
console.log("\nDeveloper Message:", fineractError.details.developerMessage);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
throw error;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
// completeWorkflowExample()
|
|
375
|
+
// .then(() => console.log("\nComplete workflow example finished."))
|
|
376
|
+
// .catch((e) => console.error("Unhandled error in complete workflow:", e));
|
|
377
|
+
// Example function to demonstrate the new deposit transaction endpoint
|
|
378
|
+
async function depositTransactionExample() {
|
|
379
|
+
console.log("=== Deposit Transaction Example ===\n");
|
|
380
|
+
try {
|
|
381
|
+
const accountId = 3873; // Replace with actual account ID
|
|
382
|
+
const depositData = {
|
|
383
|
+
transactionDate: "11 August 2025",
|
|
384
|
+
transactionAmount: 1000,
|
|
385
|
+
paymentTypeId: 1,
|
|
386
|
+
note: "this is 1000 deposit",
|
|
387
|
+
dateFormat: "dd MMMM yyyy",
|
|
388
|
+
locale: "en",
|
|
389
|
+
};
|
|
390
|
+
console.log(`Creating deposit transaction for account ${accountId}...`);
|
|
391
|
+
const depositResponse = await fineractSDK.savingsaccounts.deposit(accountId, depositData);
|
|
392
|
+
console.log("✓ Deposit transaction created successfully!");
|
|
393
|
+
console.log("Response:", JSON.stringify(depositResponse, null, 2));
|
|
394
|
+
}
|
|
395
|
+
catch (error) {
|
|
396
|
+
console.error("❌ Error creating deposit transaction:", error);
|
|
397
|
+
const fineractError = error;
|
|
398
|
+
if (fineractError.details) {
|
|
399
|
+
console.log("Error Details:", JSON.stringify(fineractError.details, null, 2));
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// Uncomment the line below to run the deposit transaction example
|
|
404
|
+
// depositTransactionExample()
|
|
405
|
+
// .then(() => console.log("\nDeposit transaction example finished."))
|
|
406
|
+
// .catch((e) => console.error("Unhandled error in deposit example:", e));
|
|
407
|
+
// Example function to demonstrate the new transaction template endpoint
|
|
408
|
+
async function transactionTemplateExample() {
|
|
409
|
+
console.log("=== Transaction Template Example ===\n");
|
|
410
|
+
try {
|
|
411
|
+
const accountId = 3; // Replace with actual account ID
|
|
412
|
+
console.log(`Getting transaction template for account ${accountId}...`);
|
|
413
|
+
const templateResponse = await fineractSDK.savingsaccounts.getTransactionTemplate(accountId);
|
|
414
|
+
console.log("✓ Transaction template retrieved successfully!");
|
|
415
|
+
console.log("Response:", JSON.stringify(templateResponse, null, 2));
|
|
416
|
+
// Display available payment types
|
|
417
|
+
console.log("\nAvailable Payment Types:");
|
|
418
|
+
templateResponse.paymentTypeOptions.forEach((paymentType) => {
|
|
419
|
+
console.log(`- ID: ${paymentType.id}, Name: ${paymentType.name}, Description: ${paymentType.description}`);
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
catch (error) {
|
|
423
|
+
console.error("❌ Error getting transaction template:", error);
|
|
424
|
+
const fineractError = error;
|
|
425
|
+
if (fineractError.details) {
|
|
426
|
+
console.log("Error Details:", JSON.stringify(fineractError.details, null, 2));
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
// Uncomment the line below to run the transaction template example
|
|
431
|
+
// transactionTemplateExample()
|
|
432
|
+
// .then(() => console.log("\nTransaction template example finished."))
|
|
433
|
+
// .catch((e) => console.error("Unhandled error in template example:", e));
|
|
434
|
+
// Example function to demonstrate the new holidays endpoint
|
|
435
|
+
async function holidaysExample() {
|
|
436
|
+
console.log("=== Holidays Example ===\n");
|
|
437
|
+
try {
|
|
438
|
+
console.log("Getting holidays for office ID 1...");
|
|
439
|
+
const officeHolidays = await fineractSDK.holidays.getHolidaysByOffice(1);
|
|
440
|
+
console.log("✓ Office holidays retrieved successfully!");
|
|
441
|
+
console.log(`Found ${officeHolidays.length} holidays for office 1`);
|
|
442
|
+
console.log("Response:", JSON.stringify(officeHolidays, null, 2));
|
|
443
|
+
// Display holiday summary
|
|
444
|
+
if (officeHolidays.length > 0) {
|
|
445
|
+
console.log("\nHoliday Summary:");
|
|
446
|
+
officeHolidays.forEach((holiday) => {
|
|
447
|
+
const fromDate = `${holiday.fromDate[0]}-${holiday.fromDate[1]
|
|
448
|
+
.toString()
|
|
449
|
+
.padStart(2, "0")}-${holiday.fromDate[2]
|
|
450
|
+
.toString()
|
|
451
|
+
.padStart(2, "0")}`;
|
|
452
|
+
const toDate = `${holiday.toDate[0]}-${holiday.toDate[1]
|
|
453
|
+
.toString()
|
|
454
|
+
.padStart(2, "0")}-${holiday.toDate[2].toString().padStart(2, "0")}`;
|
|
455
|
+
console.log(`- ${holiday.name}: ${fromDate} to ${toDate} (Status: ${holiday.status.value})`);
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
console.error("❌ Error getting holidays:", error);
|
|
461
|
+
const fineractError = error;
|
|
462
|
+
if (fineractError.details) {
|
|
463
|
+
console.log("Error Details:", JSON.stringify(fineractError.details, null, 2));
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
// Uncomment the line below to run the holidays example
|
|
468
|
+
// holidaysExample()
|
|
469
|
+
// .then(() => console.log("\nHolidays example finished."))
|
|
470
|
+
// .catch((e) => console.error("Unhandled error in holidays example:", e));
|
|
471
|
+
// Example function to demonstrate the working days endpoint
|
|
472
|
+
async function workingDaysExample() {
|
|
473
|
+
console.log("=== Working Days Example ===\n");
|
|
474
|
+
try {
|
|
475
|
+
console.log("Getting working days configuration...");
|
|
476
|
+
const workingDays = await fineractSDK.workingdays.getWorkingDays();
|
|
477
|
+
console.log("✓ Working days retrieved successfully!");
|
|
478
|
+
console.log("Response:", JSON.stringify(workingDays, null, 2));
|
|
479
|
+
// Process working days information
|
|
480
|
+
console.log("\nWorking Days Analysis:");
|
|
481
|
+
const workingDayNames = Object.entries(workingDays)
|
|
482
|
+
.filter(([day, isWorking]) => isWorking)
|
|
483
|
+
.map(([day]) => day);
|
|
484
|
+
const nonWorkingDays = Object.entries(workingDays)
|
|
485
|
+
.filter(([day, isWorking]) => !isWorking)
|
|
486
|
+
.map(([day]) => day);
|
|
487
|
+
console.log(`Working days: ${workingDayNames.join(", ")}`);
|
|
488
|
+
console.log(`Non-working days: ${nonWorkingDays.join(", ")}`);
|
|
489
|
+
console.log(`Total working days per week: ${workingDayNames.length}`);
|
|
490
|
+
// Check specific days
|
|
491
|
+
if (workingDays.Saturday || workingDays.Sunday) {
|
|
492
|
+
console.log("Note: Weekend days are included as working days");
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
console.log("Note: Standard Monday-Friday working week");
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
catch (error) {
|
|
499
|
+
console.error("❌ Error getting working days:", error);
|
|
500
|
+
const fineractError = error;
|
|
501
|
+
if (fineractError.details) {
|
|
502
|
+
console.log("Error Details:", JSON.stringify(fineractError.details, null, 2));
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
// Uncomment the line below to run the working days example
|
|
507
|
+
// workingDaysExample()
|
|
508
|
+
// .then(() => console.log("\nWorking days example finished."))
|
|
509
|
+
// .catch((e) => console.error("Unhandled error in working days example:", e));
|
|
510
|
+
// Example function to demonstrate the charges endpoint
|
|
511
|
+
async function chargesExample() {
|
|
512
|
+
console.log("=== Charges Example ===\n");
|
|
513
|
+
try {
|
|
514
|
+
console.log("Getting all available charges...");
|
|
515
|
+
const allCharges = await fineractSDK.creditlines.getCharges();
|
|
516
|
+
console.log("✓ All charges retrieved successfully!");
|
|
517
|
+
console.log(`Found ${allCharges.length} total charges`);
|
|
518
|
+
console.log();
|
|
519
|
+
console.log("Getting charges applicable to credit lines...");
|
|
520
|
+
const creditLineCharges = await fineractSDK.creditlines.getCreditLineCharges();
|
|
521
|
+
console.log("✓ Credit line charges retrieved successfully!");
|
|
522
|
+
console.log(`Found ${creditLineCharges.length} credit line applicable charges`);
|
|
523
|
+
console.log();
|
|
524
|
+
// Display first few charges as example
|
|
525
|
+
console.log("Sample Credit Line Charges:");
|
|
526
|
+
const sampleCharges = creditLineCharges.slice(0, 3);
|
|
527
|
+
for (let index = 0; index < sampleCharges.length; index++) {
|
|
528
|
+
const charge = sampleCharges[index];
|
|
529
|
+
console.log(`${index + 1}. ${charge.name} (ID: ${charge.id})`);
|
|
530
|
+
console.log(` Amount: ${charge.amount} ${charge.currency.code}`);
|
|
531
|
+
console.log(` Type: ${charge.chargeCalculationType.value}`);
|
|
532
|
+
console.log(` Active: ${charge.active ? "Yes" : "No"}`);
|
|
533
|
+
}
|
|
534
|
+
// Filter for specific charge types
|
|
535
|
+
const activationCharges = creditLineCharges.filter((charge) => charge.chargeTimeType.code === "chargeTimeType.lineOfCreditActivation");
|
|
536
|
+
console.log(`\nFound ${activationCharges.length} LOC activation charges`);
|
|
537
|
+
// Prepare charges for credit line creation
|
|
538
|
+
const selectedCharges = creditLineCharges
|
|
539
|
+
.filter((charge) => charge.chargeAppliesTo.code === "chargeAppliesTo.lineOfCredit")
|
|
540
|
+
.slice(0, 2)
|
|
541
|
+
.map((charge) => ({ ...charge, editableAmount: charge.amount }));
|
|
542
|
+
console.log(`\nSelected ${selectedCharges.length} charges for credit line creation`);
|
|
543
|
+
console.log("These charges can be used in CreateCreditLineRequest.charges array");
|
|
544
|
+
}
|
|
545
|
+
catch (error) {
|
|
546
|
+
console.error("❌ Error getting charges:", error);
|
|
547
|
+
const fineractError = error;
|
|
548
|
+
if (fineractError.details) {
|
|
549
|
+
console.log("Error Details:", JSON.stringify(fineractError.details, null, 2));
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
// Uncomment the line below to run the charges example
|
|
554
|
+
// chargesExample()
|
|
555
|
+
// .then(() => console.log("\nCharges example finished."))
|
|
556
|
+
// .catch((e) => console.error("Unhandled error in charges example:", e));
|
|
557
|
+
// Example function to demonstrate the credit lines endpoint
|
|
558
|
+
async function creditLinesExample() {
|
|
559
|
+
console.log("=== Credit Lines Example ===\n");
|
|
560
|
+
try {
|
|
561
|
+
const clientId = 4931; // Replace with actual client ID
|
|
562
|
+
// Step 1: Get template options to select deterministic values
|
|
563
|
+
console.log("Getting credit line template options...");
|
|
564
|
+
const cashMarginTypeOptions = await fineractSDK.creditlines.getCreditLineCashMarginTypeOptions(clientId);
|
|
565
|
+
const productTypeOptions = await fineractSDK.creditlines.getCreditLineProductTypeOptions(clientId);
|
|
566
|
+
const reviewPeriodOptions = await fineractSDK.creditlines.getCreditLineReviewPeriodOptions(clientId);
|
|
567
|
+
const interestChargeTimeOptions = await fineractSDK.creditlines.getCreditLineInterestChargeTimeOptions(clientId);
|
|
568
|
+
const loanOfficers = await fineractSDK.creditlines.getCreditLineLoanOfficers(clientId);
|
|
569
|
+
console.log("✓ Template options retrieved successfully!");
|
|
570
|
+
console.log(`Found ${cashMarginTypeOptions.length} cash margin type options`);
|
|
571
|
+
console.log(`Found ${productTypeOptions.length} product type options`);
|
|
572
|
+
console.log(`Found ${reviewPeriodOptions.length} review period options`);
|
|
573
|
+
console.log(`Found ${interestChargeTimeOptions.length} interest charge time options`);
|
|
574
|
+
console.log(`Found ${loanOfficers.length} loan officers`);
|
|
575
|
+
// Step 2: Get available charges for credit lines
|
|
576
|
+
console.log("\nGetting available charges for credit lines...");
|
|
577
|
+
const availableCharges = await fineractSDK.creditlines.getCreditLineCharges();
|
|
578
|
+
console.log("✓ Credit line charges retrieved successfully!");
|
|
579
|
+
console.log(`Found ${availableCharges.length} applicable charges`);
|
|
580
|
+
// Step 3: Filter and select template values based on business requirements
|
|
581
|
+
console.log("\nSelecting template values for credit line creation...");
|
|
582
|
+
// Select product type - looking for "RECEIVABLE" (ID: 1 in current data)
|
|
583
|
+
const selectedProductType = productTypeOptions.find((option) => option.code === "RECEIVABLE" || option.id === 1) || productTypeOptions[0]; // fallback to first option
|
|
584
|
+
// Select cash margin type - looking for "PERCENTAGE" (ID: 1 in current data)
|
|
585
|
+
const selectedCashMarginType = cashMarginTypeOptions.find((option) => option.code === "PERCENTAGE" || option.id === 1) || cashMarginTypeOptions[0];
|
|
586
|
+
// Select review period - looking for 6 months (ID: 6 in current data)
|
|
587
|
+
const selectedReviewPeriod = reviewPeriodOptions.find((option) => option.code === "locreviewperiod.6months" || option.id === 6) ||
|
|
588
|
+
reviewPeriodOptions.find((option) => option.id === 6) ||
|
|
589
|
+
reviewPeriodOptions[0];
|
|
590
|
+
// Select interest charge time - looking for "UPFRONT" (ID: 1 in current data)
|
|
591
|
+
const selectedInterestChargeTime = interestChargeTimeOptions.find((option) => option.code === "UPFRONT" || option.id === 1) || interestChargeTimeOptions[0];
|
|
592
|
+
// Select active loan officer (ID: 1 in current data)
|
|
593
|
+
const selectedLoanOfficer = loanOfficers.find((officer) => officer.isActive && officer.isLoanOfficer && officer.id === 1) ||
|
|
594
|
+
loanOfficers.find((officer) => officer.isActive && officer.isLoanOfficer) ||
|
|
595
|
+
loanOfficers[0];
|
|
596
|
+
// Select charges for the credit line (activation charges)
|
|
597
|
+
const selectedCharges = availableCharges
|
|
598
|
+
.filter((charge) => charge.active &&
|
|
599
|
+
charge.chargeTimeType.code === "chargeTimeType.lineOfCreditActivation")
|
|
600
|
+
.slice(0, 2) // Take first 2 activation charges
|
|
601
|
+
.map((charge) => ({
|
|
602
|
+
...charge,
|
|
603
|
+
editableAmount: charge.amount, // Use original amount as editable amount
|
|
604
|
+
}));
|
|
605
|
+
console.log("Selected template values:");
|
|
606
|
+
console.log(`- Product Type: ${selectedProductType?.value} (ID: ${selectedProductType?.id})`);
|
|
607
|
+
console.log(`- Cash Margin Type: ${selectedCashMarginType?.value} (ID: ${selectedCashMarginType?.id})`);
|
|
608
|
+
console.log(`- Review Period: ${selectedReviewPeriod?.value} (ID: ${selectedReviewPeriod?.id})`);
|
|
609
|
+
console.log(`- Interest Charge Time: ${selectedInterestChargeTime?.value} (ID: ${selectedInterestChargeTime?.id})`);
|
|
610
|
+
console.log(`- Loan Officer: ${selectedLoanOfficer?.displayName} (ID: ${selectedLoanOfficer?.id})`);
|
|
611
|
+
console.log(`- Selected ${selectedCharges.length} charges for credit line creation`);
|
|
612
|
+
if (selectedCharges.length > 0) {
|
|
613
|
+
console.log("Selected charges:");
|
|
614
|
+
for (const charge of selectedCharges) {
|
|
615
|
+
console.log(` - ${charge.name}: ${charge.amount} ${charge.currency.code}`);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
// Step 4: Create credit line with template-derived values
|
|
619
|
+
const creditLineData = {
|
|
620
|
+
productType: selectedProductType?.id || 1,
|
|
621
|
+
currencyCode: "AED",
|
|
622
|
+
clientCompanyName: "Test Company Ltd",
|
|
623
|
+
clientContactPersonName: "John Doe",
|
|
624
|
+
clientContactPersonPhone: "0501234567",
|
|
625
|
+
clientContactPersonEmail: "john.doe@testcompany.com",
|
|
626
|
+
authorizedSignatoryName: "Jane Smith",
|
|
627
|
+
authorizedSignatoryPhone: "0507654321",
|
|
628
|
+
authorizedSignatoryEmail: "jane.smith@testcompany.com",
|
|
629
|
+
virtualAccount: "VA2000",
|
|
630
|
+
externalId: "CL-TEST-001",
|
|
631
|
+
specialConditions: "Test credit line with standard terms",
|
|
632
|
+
maxCreditLimit: "1000000",
|
|
633
|
+
reviewPeriod: selectedReviewPeriod?.id || 6,
|
|
634
|
+
interimReviewDate: "15 June 2026",
|
|
635
|
+
annualInterestRate: 120, // in percentage
|
|
636
|
+
tenorDays: 365,
|
|
637
|
+
advancePercentage: "85",
|
|
638
|
+
cashMarginType: selectedCashMarginType?.id || 1,
|
|
639
|
+
cashMarginValue: 15,
|
|
640
|
+
interestChargeTime: selectedInterestChargeTime?.id || 1,
|
|
641
|
+
loanOfficerId: selectedLoanOfficer?.id || 1,
|
|
642
|
+
distributionPartner: "Test Distribution Partner",
|
|
643
|
+
approvedBuyers: [
|
|
644
|
+
{ name: "Approved Buyer One" },
|
|
645
|
+
{ name: "Approved Buyer Two" },
|
|
646
|
+
],
|
|
647
|
+
settlementSavingsAccountId: null, // No settlement account
|
|
648
|
+
charges: selectedCharges, // Use template-derived charges
|
|
649
|
+
dateFormat: "dd MMMM yyyy",
|
|
650
|
+
locale: "en",
|
|
651
|
+
};
|
|
652
|
+
console.log(`\nCreating credit line for client ${clientId} with template-derived values...`);
|
|
653
|
+
const response = await fineractSDK.creditlines.createCreditLine(clientId, creditLineData);
|
|
654
|
+
console.log("✓ Credit line created successfully!");
|
|
655
|
+
console.log("Response:", JSON.stringify(response, null, 2));
|
|
656
|
+
// Display key information from response
|
|
657
|
+
console.log(`Credit Line Resource ID: ${response.resourceId}`);
|
|
658
|
+
}
|
|
659
|
+
catch (error) {
|
|
660
|
+
console.error("❌ Error creating credit line:", error);
|
|
661
|
+
const fineractError = error;
|
|
662
|
+
if (fineractError.details) {
|
|
663
|
+
console.log("Error Details:", JSON.stringify(fineractError.details, null, 2));
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
// Uncomment the line below to run the credit lines example
|
|
668
|
+
// creditLinesExample()
|
|
669
|
+
// .then(() => console.log("\nCredit lines example finished."))
|
|
670
|
+
// .catch((e) => console.error("Unhandled error in credit lines example:", e));
|
|
671
|
+
// Example function to demonstrate the credit line template endpoint
|
|
672
|
+
async function creditLineTemplateExample() {
|
|
673
|
+
console.log("=== Credit Line Template Example ===\n");
|
|
674
|
+
try {
|
|
675
|
+
const clientId = 6029; // Replace with actual client ID
|
|
676
|
+
console.log("Getting full credit line template...");
|
|
677
|
+
const template = await fineractSDK.creditlines.getCreditLineTemplate(clientId);
|
|
678
|
+
console.log("✓ Credit line template retrieved successfully!");
|
|
679
|
+
console.log("Template response:", JSON.stringify(template, null, 2));
|
|
680
|
+
console.log("\nGetting specific template options...");
|
|
681
|
+
// Get cash margin type options
|
|
682
|
+
const cashMarginTypeOptions = await fineractSDK.creditlines.getCreditLineCashMarginTypeOptions(clientId);
|
|
683
|
+
console.log("Cash Margin Type Options:");
|
|
684
|
+
for (const option of cashMarginTypeOptions) {
|
|
685
|
+
console.log(`- ID: ${option.id}, Code: ${option.code}, Value: ${option.value}`);
|
|
686
|
+
}
|
|
687
|
+
// Get product type options
|
|
688
|
+
const productTypeOptions = await fineractSDK.creditlines.getCreditLineProductTypeOptions(clientId);
|
|
689
|
+
console.log("\nProduct Type Options:");
|
|
690
|
+
for (const option of productTypeOptions) {
|
|
691
|
+
console.log(`- ID: ${option.id}, Code: ${option.code}, Value: ${option.value}`);
|
|
692
|
+
}
|
|
693
|
+
// Get review period options
|
|
694
|
+
const reviewPeriodOptions = await fineractSDK.creditlines.getCreditLineReviewPeriodOptions(clientId);
|
|
695
|
+
console.log("\nReview Period Options:");
|
|
696
|
+
for (const option of reviewPeriodOptions) {
|
|
697
|
+
console.log(`- ID: ${option.id}, Code: ${option.code}, Value: ${option.value}`);
|
|
698
|
+
}
|
|
699
|
+
// Get interest charge time options
|
|
700
|
+
const interestChargeTimeOptions = await fineractSDK.creditlines.getCreditLineInterestChargeTimeOptions(clientId);
|
|
701
|
+
console.log("\nInterest Charge Time Options:");
|
|
702
|
+
for (const option of interestChargeTimeOptions) {
|
|
703
|
+
console.log(`- ID: ${option.id}, Code: ${option.code}, Value: ${option.value}`);
|
|
704
|
+
}
|
|
705
|
+
// Get loan officers
|
|
706
|
+
const loanOfficers = await fineractSDK.creditlines.getCreditLineLoanOfficers(clientId);
|
|
707
|
+
console.log("\nLoan Officers:");
|
|
708
|
+
for (const officer of loanOfficers) {
|
|
709
|
+
console.log(`- ID: ${officer.id}, Name: ${officer.displayName}, Office: ${officer.officeName}`);
|
|
710
|
+
console.log(` Active: ${officer.isActive}, Loan Officer: ${officer.isLoanOfficer}`);
|
|
711
|
+
}
|
|
712
|
+
// Demonstrate deterministic value selection
|
|
713
|
+
console.log("\nUsing template options for deterministic credit line creation:");
|
|
714
|
+
const selectedCashMarginType = cashMarginTypeOptions.find((option) => option.code === "PERCENTAGE");
|
|
715
|
+
const selectedProductType = productTypeOptions.find((option) => option.code === "RECEIVABLE");
|
|
716
|
+
const selectedReviewPeriod = reviewPeriodOptions.find((option) => option.code === "locreviewperiod.6months");
|
|
717
|
+
console.log(`Selected Cash Margin Type: ${selectedCashMarginType?.value} (ID: ${selectedCashMarginType?.id})`);
|
|
718
|
+
console.log(`Selected Product Type: ${selectedProductType?.value} (ID: ${selectedProductType?.id})`);
|
|
719
|
+
console.log(`Selected Review Period: ${selectedReviewPeriod?.value} (ID: ${selectedReviewPeriod?.id})`);
|
|
720
|
+
console.log("\nThese IDs can now be used in CreateCreditLineRequest with confidence!");
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
console.error("❌ Error getting credit line template:", error);
|
|
724
|
+
const fineractError = error;
|
|
725
|
+
if (fineractError.details) {
|
|
726
|
+
console.log("Error Details:", JSON.stringify(fineractError.details, null, 2));
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
// Uncomment the line below to run the credit line template example
|
|
731
|
+
// creditLineTemplateExample()
|
|
732
|
+
// .then(() => console.log("\nCredit line template example finished."))
|
|
733
|
+
// .catch((e) => console.error("Unhandled error in template example:", e));
|
|
734
|
+
// ===== Reports Example =====
|
|
735
|
+
async function getLoanPaymentsDue() {
|
|
736
|
+
console.log("Loan payments due ===\n");
|
|
737
|
+
const start = Date.now();
|
|
738
|
+
try {
|
|
739
|
+
// Only pass dynamic filters; officeId and loanOfficerId are auto-injected (1, -1)
|
|
740
|
+
const params = {
|
|
741
|
+
fromInstallment: 2,
|
|
742
|
+
toInstallment: 2,
|
|
743
|
+
};
|
|
744
|
+
console.log("[Loan payments due] Sending request...");
|
|
745
|
+
const report = await fineractSDK.reports.getLoanPaymentsDue(params);
|
|
746
|
+
console.log("✓ Loan payments due fetched successfully");
|
|
747
|
+
console.log("First 5 rows:", JSON.stringify(report.data.slice(0, 5), null, 2));
|
|
748
|
+
console.log(`[Loan payments due] Completed in ${Date.now() - start}ms`);
|
|
749
|
+
}
|
|
750
|
+
catch (error) {
|
|
751
|
+
console.error("❌ Error fetching Loan payments due:", error);
|
|
752
|
+
const fineractError = error;
|
|
753
|
+
if (fineractError.details) {
|
|
754
|
+
console.log("Error Details:", JSON.stringify(fineractError.details, null, 2));
|
|
755
|
+
}
|
|
756
|
+
console.log(`[Loan payments due] Failed after ${Date.now() - start}ms`);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
// Uncomment to run the report example
|
|
760
|
+
// getLoanPaymentsDue()
|
|
761
|
+
// .then(() => console.log("\nLoan Payments Due example finished."))
|
|
762
|
+
// .catch((e) => console.error("Unhandled error in Loan Payments Due example:", e));
|
|
763
|
+
async function getLoanPaymentsDueOverdue() {
|
|
764
|
+
console.log("=== Loan payments due (Overdue Loans) ===\n");
|
|
765
|
+
const start = Date.now();
|
|
766
|
+
try {
|
|
767
|
+
// officeId and loanOfficerId auto-injected
|
|
768
|
+
const params = {
|
|
769
|
+
fromInstallment: 1,
|
|
770
|
+
toInstallment: 1,
|
|
771
|
+
overdueFromDays: 1,
|
|
772
|
+
overdueToDays: 30,
|
|
773
|
+
};
|
|
774
|
+
console.log("[Loan payments due (Overdue Loans)] Sending request...");
|
|
775
|
+
const report = await fineractSDK.reports.getLoanPaymentsDueOverdue(params);
|
|
776
|
+
console.log("✓ Loan payments due (Overdue Loans) fetched successfully");
|
|
777
|
+
console.log("First 5 overdue rows:", JSON.stringify(report.data.slice(0, 5), null, 2));
|
|
778
|
+
console.log(`[Loan payments due (Overdue Loans)] Completed in ${Date.now() - start}ms`);
|
|
779
|
+
}
|
|
780
|
+
catch (error) {
|
|
781
|
+
console.error("❌ Error fetching Loan payments due (Overdue Loans):", error);
|
|
782
|
+
const fineractError = error;
|
|
783
|
+
if (fineractError.details) {
|
|
784
|
+
console.log("Error Details:", JSON.stringify(fineractError.details, null, 2));
|
|
785
|
+
}
|
|
786
|
+
console.log(`[Loan payments due (Overdue Loans)] Failed after ${Date.now() - start}ms`);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
// Uncomment to run the overdue report example
|
|
790
|
+
// getLoanPaymentsDueOverdue()
|
|
791
|
+
// .then(() => console.log("\nLoan payments due (Overdue Loans) example finished."))
|
|
792
|
+
// .catch((e) => console.error("Unhandled error in Loan payments due (Overdue Loans) example:", e));
|
|
793
|
+
async function getExpectedPaymentsByDateBasic() {
|
|
794
|
+
console.log("=== Expected Payments By Date - Basic ===\n");
|
|
795
|
+
const start = Date.now();
|
|
796
|
+
try {
|
|
797
|
+
// officeId and loanOfficerId auto-injected
|
|
798
|
+
const params = {
|
|
799
|
+
startDate: "2025-02-04",
|
|
800
|
+
endDate: "2025-10-23",
|
|
801
|
+
locale: "en",
|
|
802
|
+
dateFormat: "yyyy-MM-dd",
|
|
803
|
+
};
|
|
804
|
+
console.log("[Expected Payments By Date - Basic] Sending request...");
|
|
805
|
+
const report = await fineractSDK.reports.getExpectedPaymentsByDateBasic(params);
|
|
806
|
+
console.log("✓ Expected Payments By Date - Basic fetched successfully");
|
|
807
|
+
console.log("First 5 expected payment rows:", JSON.stringify(report.data.slice(0, 5), null, 2));
|
|
808
|
+
console.log(`[Expected Payments By Date - Basic ] Completed in ${Date.now() - start}ms`);
|
|
809
|
+
}
|
|
810
|
+
catch (error) {
|
|
811
|
+
console.error("❌ Error fetching Expected Payments By Date - Basic:", error);
|
|
812
|
+
const fineractError = error;
|
|
813
|
+
if (fineractError.details) {
|
|
814
|
+
console.log("Error Details:", JSON.stringify(fineractError.details, null, 2));
|
|
815
|
+
}
|
|
816
|
+
console.log(`[Expected Payments By Date - Basic] Failed after ${Date.now() - start}ms`);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
/**
|
|
820
|
+
* Get all credit lines for a client
|
|
821
|
+
*/
|
|
822
|
+
async function getCreditLinesForClient() {
|
|
823
|
+
try {
|
|
824
|
+
console.log("\n--- Getting Credit Lines for Client ---");
|
|
825
|
+
const clientId = 6196; // Replace with actual client ID
|
|
826
|
+
console.log(`Fetching credit lines for client ${clientId}...`);
|
|
827
|
+
const creditLines = await fineractSDK.creditlines.getCreditLines(clientId);
|
|
828
|
+
if (creditLines.length === 0) {
|
|
829
|
+
console.log("No credit lines found for this client.");
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
console.log(`Found ${creditLines.length} credit line(s):`);
|
|
833
|
+
for (const [index, creditLineWithLoans] of creditLines.entries()) {
|
|
834
|
+
const creditLine = creditLineWithLoans.lineOfCredit;
|
|
835
|
+
console.log(`\n${index + 1}. Credit Line ID: ${creditLine.id}`);
|
|
836
|
+
console.log(` Account Number: ${creditLine.accountNumber || "N/A"}`);
|
|
837
|
+
console.log(` Maximum Amount: ${creditLine.maximumAmount}`);
|
|
838
|
+
console.log(` Available Balance: ${creditLine.availableBalance}`);
|
|
839
|
+
console.log(` Status: ${creditLine.status?.value || "Unknown"}`);
|
|
840
|
+
if (creditLineWithLoans.loans && creditLineWithLoans.loans.length > 0) {
|
|
841
|
+
console.log(` Associated Loans (${creditLineWithLoans.loans.length}):`);
|
|
842
|
+
for (const [loanIndex, loan] of creditLineWithLoans.loans.entries()) {
|
|
843
|
+
console.log(` ${loanIndex + 1}. Loan #${loan.accountNo} - ${loan.productName || "Unknown Product"}`);
|
|
844
|
+
console.log(` Loan Balance: ${loan.loanBalance || 0}`);
|
|
845
|
+
console.log(` Status: ${loan.status?.value || "Unknown"}`);
|
|
846
|
+
console.log(` In Arrears: ${loan.inArrears ? "Yes" : "No"}`);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
console.log(" No associated loans.");
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
console.log("\nCredit lines retrieval completed successfully!");
|
|
854
|
+
}
|
|
855
|
+
catch (error) {
|
|
856
|
+
console.error("Error getting credit lines:", error);
|
|
857
|
+
throw error;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
// Uncomment to run expected payments by date basic report
|
|
861
|
+
// getExpectedPaymentsByDateBasic()
|
|
862
|
+
// .then(() => console.log("\nExpected Payments By Date - Basic example finished."))
|
|
863
|
+
// .catch((e) => console.error("Unhandled error in Expected Payments By Date - Basic example:", e));
|
|
864
|
+
// Uncomment to run credit lines listing example
|
|
865
|
+
getCreditLinesForClient()
|
|
866
|
+
.then(() => console.log("\nCredit Lines listing example finished."))
|
|
867
|
+
.catch((e) => console.error("Unhandled error in Credit Lines listing example:", e));
|
|
868
|
+
//# sourceMappingURL=run-examples.js.map
|