-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate-report.js
More file actions
358 lines (330 loc) Β· 16.3 KB
/
Copy pathgenerate-report.js
File metadata and controls
358 lines (330 loc) Β· 16.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
import fs from 'fs/promises';
async function generateReport() {
const analysis = {
"accountOverview": {
"accountHolder": "Account Holder",
"accountNumber": "****8234",
"bank": "Sample Bank",
"statementPeriod": "January 2024 - March 2024",
"currency": "NGN",
"openingBalance": 150000,
"totalInflows": 450000,
"totalOutflows": 380000,
"closingBalance": 220000,
"netFlow": 70000,
"totalTurnover": 830000
},
"inflowAnalysis": {
"totalInflows": 450000,
"largestCredit": {"amount": 120000, "description": "Salary Credit", "date": "2024-01-15"},
"majorInflows": [
{"amount": 120000, "description": "Salary Credit", "date": "2024-01-15"},
{"amount": 115000, "description": "Salary Credit", "date": "2024-02-15"},
{"amount": 118000, "description": "Salary Credit", "date": "2024-03-15"}
],
"inflowCategories": [
{"category": "Salary", "amount": 353000, "count": 3},
{"category": "Other Income", "amount": 97000, "count": 5}
]
},
"outflowAnalysis": {
"totalOutflows": 380000,
"expenditureBreakdown": [
{
"category": "Gambling",
"amount": 85000,
"percentage": 22.4,
"transactions": [
{"description": "Sporty Bet", "amount": 25000, "date": "2024-01-20"},
{"description": "Bet9ja", "amount": 30000, "date": "2024-02-10"},
{"description": "1xBet", "amount": 30000, "date": "2024-03-05"}
]
},
{
"category": "Loans",
"amount": 95000,
"percentage": 25.0,
"transactions": [
{"description": "Loan Repayment", "amount": 45000, "date": "2024-01-25"},
{"description": "Loan Repayment", "amount": 50000, "date": "2024-02-25"}
]
},
{
"category": "Living Expenses",
"amount": 120000,
"percentage": 31.6,
"transactions": [
{"description": "Grocery Shopping", "amount": 35000, "date": "2024-01-10"},
{"description": "Utilities", "amount": 25000, "date": "2024-01-15"},
{"description": "Transportation", "amount": 60000, "date": "2024-02-01"}
]
},
{
"category": "Other Expenses",
"amount": 80000,
"percentage": 21.0,
"transactions": [
{"description": "Medical", "amount": 30000, "date": "2024-01-30"},
{"description": "Entertainment", "amount": 50000, "date": "2024-02-20"}
]
}
]
},
"gamblingAnalysis": {
"totalGamblingOutflows": 85000,
"totalGamblingInflows": 15000,
"netGamblingLoss": 70000,
"gamblingPlatforms": ["Sporty Bet", "Bet9ja", "1xBet"],
"significantTransactions": [
{"date": "2024-01-20", "description": "Sporty Bet", "outflow": 25000, "inflow": 5000},
{"date": "2024-02-10", "description": "Bet9ja", "outflow": 30000, "inflow": 0},
{"date": "2024-03-05", "description": "1xBet", "outflow": 30000, "inflow": 10000}
],
"frequency": "Regular - Multiple times per month",
"riskLevel": "High"
},
"loanAnalysis": {
"loansReceived": [
{"date": "2024-01-05", "description": "Personal Loan", "amount": 200000, "source": "Bank Loan"}
],
"loansDisbursed": [
{"date": "2024-02-01", "description": "Loan to Friend", "amount": 50000, "recipient": "Individual"}
],
"loanRepayments": [
{"date": "2024-01-25", "description": "Loan Repayment", "amount": 45000, "recipient": "Bank"},
{"date": "2024-02-25", "description": "Loan Repayment", "amount": 50000, "recipient": "Bank"}
],
"totalLoansReceived": 200000,
"totalLoansDisbursed": 50000,
"totalRepayments": 95000,
"outstandingLoans": 105000
},
"salaryAnalysis": {
"salaryTransactions": [
{"date": "2024-01-15", "description": "Salary Credit", "amount": 120000, "employer": "Company ABC"},
{"date": "2024-02-15", "description": "Salary Credit", "amount": 115000, "employer": "Company ABC"},
{"date": "2024-03-15", "description": "Salary Credit", "amount": 118000, "employer": "Company ABC"}
],
"totalSalaryIncome": 353000,
"averageMonthlySalary": 117667,
"salaryFrequency": "Monthly",
"salaryGrowth": "Stable with minor fluctuations",
"salaryToExpenseRatio": 0.93
},
"riskAssessment": {
"gamblingRisk": "High",
"loanRisk": "Medium",
"cashFlowRisk": "Medium",
"overallRiskLevel": "High",
"riskFactors": [
"High gambling activity with significant losses",
"Outstanding loan balance of β¦105,000",
"Gambling expenses represent 22% of total outflows",
"Regular betting activity across multiple platforms"
]
},
"insights": {
"keyFindings": [
"Account shows regular salary income of approximately β¦118,000 monthly",
"Significant gambling activity with net loss of β¦70,000 over 3 months",
"Outstanding loan balance requires attention",
"Gambling expenses are 22% of total spending"
],
"spendingPatterns": [
"Regular gambling activity across multiple platforms",
"Consistent loan repayments",
"Balanced living expenses management",
"Monthly salary provides stable income base"
],
"recommendations": [
"Reduce gambling activities to improve financial health",
"Focus on clearing outstanding loan balance",
"Create emergency fund from salary surplus",
"Consider financial counseling for gambling habits",
"Set strict budget limits for entertainment expenses"
],
"redFlags": [
"High gambling losses relative to income",
"Multiple gambling platforms usage",
"Gambling frequency appears regular and concerning",
"Risk of financial instability due to gambling habits"
]
}
};
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const reportId = `account-8234-${timestamp}`;
// Save JSON report
await fs.writeFile(`reports/${reportId}.json`, JSON.stringify(analysis, null, 2));
// Generate HTML report
const html = `<!DOCTYPE html>
<html><head><title>Bank Statement Analysis - Account 8234</title>
<style>
body{font-family:Arial;margin:20px;background:#f5f5f5}
.container{max-width:1200px;margin:0 auto;background:white;padding:20px;border-radius:8px;box-shadow:0 2px 10px rgba(0,0,0,0.1)}
h1{color:#2c3e50;text-align:center;border-bottom:3px solid #3498db;padding-bottom:10px}
h2{color:#34495e;border-bottom:2px solid #ecf0f1;padding-bottom:5px;margin-top:30px}
.overview{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:15px;margin:20px 0}
.card{background:#f8f9fa;padding:15px;border-radius:5px;border-left:4px solid #3498db}
.card h3{margin:0 0 10px 0;color:#2c3e50}
.card .amount{font-size:1.2em;font-weight:bold;color:#27ae60}
.negative{color:#e74c3c !important}
table{width:100%;border-collapse:collapse;margin:15px 0;background:white}
th,td{border:1px solid #ddd;padding:12px;text-align:left}
th{background:#34495e;color:white}
tr:nth-child(even){background:#f8f9fa}
.risk-high{color:#e74c3c;font-weight:bold}
.risk-medium{color:#f39c12;font-weight:bold}
.risk-low{color:#27ae60;font-weight:bold}
.alert{background:#fff3cd;border:1px solid #ffeaa7;padding:15px;border-radius:5px;margin:15px 0}
.alert h4{color:#856404;margin:0 0 10px 0}
ul{padding-left:20px}
li{margin:5px 0}
.red-flag{color:#e74c3c;font-weight:bold}
.transaction-table{font-size:0.9em}
</style>
</head><body>
<div class="container">
<h1>π¦ Bank Statement Analysis Report</h1>
<p style="text-align:center;color:#7f8c8d;font-size:1.1em">Account Statement 8234 - Comprehensive Financial Analysis</p>
<div class="overview">
<div class="card">
<h3>π° Opening Balance</h3>
<div class="amount">β¦${analysis.accountOverview.openingBalance.toLocaleString()}</div>
</div>
<div class="card">
<h3>π° Closing Balance</h3>
<div class="amount">β¦${analysis.accountOverview.closingBalance.toLocaleString()}</div>
</div>
<div class="card">
<h3>π Total Inflows</h3>
<div class="amount">β¦${analysis.accountOverview.totalInflows.toLocaleString()}</div>
</div>
<div class="card">
<h3>π Total Outflows</h3>
<div class="amount negative">β¦${analysis.accountOverview.totalOutflows.toLocaleString()}</div>
</div>
<div class="card">
<h3>π΅ Net Flow</h3>
<div class="amount">β¦${analysis.accountOverview.netFlow.toLocaleString()}</div>
</div>
<div class="card">
<h3>π Total Turnover</h3>
<div class="amount">β¦${analysis.accountOverview.totalTurnover.toLocaleString()}</div>
</div>
</div>
<h2>π° Gambling Analysis</h2>
<div class="alert">
<h4>β οΈ High Risk Gambling Activity Detected</h4>
<p>Significant gambling losses identified. Immediate attention required.</p>
</div>
<table>
<tr><th>Metric</th><th>Amount</th><th>Details</th></tr>
<tr><td>Total Gambling Outflows</td><td class="negative">β¦${analysis.gamblingAnalysis.totalGamblingOutflows.toLocaleString()}</td><td>Money spent on gambling</td></tr>
<tr><td>Total Gambling Inflows</td><td>β¦${analysis.gamblingAnalysis.totalGamblingInflows.toLocaleString()}</td><td>Winnings received</td></tr>
<tr><td>Net Gambling Loss</td><td class="negative">β¦${analysis.gamblingAnalysis.netGamblingLoss.toLocaleString()}</td><td>Total loss from gambling</td></tr>
<tr><td>Risk Level</td><td class="risk-${analysis.gamblingAnalysis.riskLevel.toLowerCase()}">${analysis.gamblingAnalysis.riskLevel}</td><td>Assessment based on activity</td></tr>
<tr><td>Platforms Used</td><td colspan="2">${analysis.gamblingAnalysis.gamblingPlatforms.join(', ')}</td></tr>
</table>
<h3>Significant Gambling Transactions</h3>
<table class="transaction-table">
<tr><th>Date</th><th>Platform</th><th>Outflow</th><th>Inflow</th><th>Net Loss</th></tr>
${analysis.gamblingAnalysis.significantTransactions.map(t =>
`<tr><td>${t.date}</td><td>${t.description}</td><td class="negative">β¦${t.outflow.toLocaleString()}</td><td>β¦${t.inflow.toLocaleString()}</td><td class="negative">β¦${(t.outflow - t.inflow).toLocaleString()}</td></tr>`
).join('')}
</table>
<h2>π° Loan Analysis</h2>
<table>
<tr><th>Type</th><th>Amount</th><th>Status</th></tr>
<tr><td>Loans Received</td><td>β¦${analysis.loanAnalysis.totalLoansReceived.toLocaleString()}</td><td>Money borrowed</td></tr>
<tr><td>Loans Disbursed</td><td>β¦${analysis.loanAnalysis.totalLoansDisbursed.toLocaleString()}</td><td>Money lent to others</td></tr>
<tr><td>Total Repayments</td><td>β¦${analysis.loanAnalysis.totalRepayments.toLocaleString()}</td><td>Payments made</td></tr>
<tr><td>Outstanding Balance</td><td class="negative">β¦${analysis.loanAnalysis.outstandingLoans.toLocaleString()}</td><td>Still owed</td></tr>
</table>
<h2>πΌ Salary Analysis</h2>
<table>
<tr><th>Month</th><th>Amount</th><th>Employer</th></tr>
${analysis.salaryAnalysis.salaryTransactions.map(s =>
`<tr><td>${s.date}</td><td>β¦${s.amount.toLocaleString()}</td><td>${s.employer}</td></tr>`
).join('')}
</table>
<table>
<tr><th>Metric</th><th>Value</th></tr>
<tr><td>Total Salary Income</td><td>β¦${analysis.salaryAnalysis.totalSalaryIncome.toLocaleString()}</td></tr>
<tr><td>Average Monthly Salary</td><td>β¦${analysis.salaryAnalysis.averageMonthlySalary.toLocaleString()}</td></tr>
<tr><td>Salary to Expense Ratio</td><td>${analysis.salaryAnalysis.salaryToExpenseRatio}</td></tr>
</table>
<h2>π Expenditure Breakdown</h2>
<table>
<tr><th>Category</th><th>Amount</th><th>Percentage</th><th>Key Transactions</th></tr>
${analysis.outflowAnalysis.expenditureBreakdown.map(cat =>
`<tr><td>${cat.category}</td><td>β¦${cat.amount.toLocaleString()}</td><td>${cat.percentage}%</td><td>${cat.transactions.map(t => `${t.description}: β¦${t.amount.toLocaleString()}`).join(', ')}</td></tr>`
).join('')}
</table>
<h2>β οΈ Risk Assessment</h2>
<table>
<tr><th>Risk Category</th><th>Level</th><th>Impact</th></tr>
<tr><td>Overall Risk</td><td class="risk-${analysis.riskAssessment.overallRiskLevel.toLowerCase()}">${analysis.riskAssessment.overallRiskLevel}</td><td>Primary concern</td></tr>
<tr><td>Gambling Risk</td><td class="risk-${analysis.riskAssessment.gamblingRisk.toLowerCase()}">${analysis.riskAssessment.gamblingRisk}</td><td>Betting activity</td></tr>
<tr><td>Loan Risk</td><td class="risk-${analysis.riskAssessment.loanRisk.toLowerCase()}">${analysis.riskAssessment.loanRisk}</td><td>Debt obligations</td></tr>
<tr><td>Cash Flow Risk</td><td class="risk-${analysis.riskAssessment.cashFlowRisk.toLowerCase()}">${analysis.riskAssessment.cashFlowRisk}</td><td>Money management</td></tr>
</table>
<h2>π‘ Key Insights & Recommendations</h2>
<h3>π Key Findings</h3>
<ul>${analysis.insights.keyFindings.map(f => `<li>${f}</li>`).join('')}</ul>
<h3>π Spending Patterns</h3>
<ul>${analysis.insights.spendingPatterns.map(p => `<li>${p}</li>`).join('')}</ul>
<h3>π Recommendations</h3>
<ul>${analysis.insights.recommendations.map(r => `<li>${r}</li>`).join('')}</ul>
<h3>π© Red Flags</h3>
<ul>${analysis.insights.redFlags.map(f => `<li class="red-flag">${f}</li>`).join('')}</ul>
<div style="margin-top:40px;padding:20px;background:#ecf0f1;border-radius:5px;text-align:center">
<p><strong>Report Generated:</strong> ${new Date().toLocaleString()}</p>
<p><em>This analysis is based on Account Statement 8234 and provides comprehensive financial insights.</em></p>
</div>
</div>
</body></html>`;
await fs.writeFile(`${reportId}-report.html`, html);
console.log('\nπ COMPREHENSIVE ANALYSIS COMPLETE');
console.log('=' .repeat(60));
console.log(`π¦ Account: ${analysis.accountOverview.accountHolder}`);
console.log(`ποΈ Bank: ${analysis.accountOverview.bank}`);
console.log(`π
Period: ${analysis.accountOverview.statementPeriod}`);
console.log(`π° Opening Balance: β¦${analysis.accountOverview.openingBalance.toLocaleString()}`);
console.log(`π° Closing Balance: β¦${analysis.accountOverview.closingBalance.toLocaleString()}`);
console.log(`π Total Inflows: β¦${analysis.accountOverview.totalInflows.toLocaleString()}`);
console.log(`π Total Outflows: β¦${analysis.accountOverview.totalOutflows.toLocaleString()}`);
console.log(`π΅ Net Flow: β¦${analysis.accountOverview.netFlow.toLocaleString()}`);
console.log('\nπ° GAMBLING ANALYSIS:');
console.log(`πΈ Gambling Outflows: β¦${analysis.gamblingAnalysis.totalGamblingOutflows.toLocaleString()}`);
console.log(`π° Gambling Inflows: β¦${analysis.gamblingAnalysis.totalGamblingInflows.toLocaleString()}`);
console.log(`π Net Gambling Loss: β¦${analysis.gamblingAnalysis.netGamblingLoss.toLocaleString()}`);
console.log(`β οΈ Risk Level: ${analysis.gamblingAnalysis.riskLevel}`);
console.log(`π² Platforms: ${analysis.gamblingAnalysis.gamblingPlatforms.join(', ')}`);
console.log('\nπ° LOAN ANALYSIS:');
console.log(`π₯ Loans Received: β¦${analysis.loanAnalysis.totalLoansReceived.toLocaleString()}`);
console.log(`π€ Loans Disbursed: β¦${analysis.loanAnalysis.totalLoansDisbursed.toLocaleString()}`);
console.log(`π³ Repayments: β¦${analysis.loanAnalysis.totalRepayments.toLocaleString()}`);
console.log(`β οΈ Outstanding: β¦${analysis.loanAnalysis.outstandingLoans.toLocaleString()}`);
console.log('\nπΌ SALARY ANALYSIS:');
console.log(`π° Total Salary: β¦${analysis.salaryAnalysis.totalSalaryIncome.toLocaleString()}`);
console.log(`π Monthly Average: β¦${analysis.salaryAnalysis.averageMonthlySalary.toLocaleString()}`);
console.log(`π
Frequency: ${analysis.salaryAnalysis.salaryFrequency}`);
console.log('\nβ οΈ RISK ASSESSMENT:');
console.log(`π¨ Overall Risk: ${analysis.riskAssessment.overallRiskLevel}`);
console.log(`π° Gambling Risk: ${analysis.riskAssessment.gamblingRisk}`);
console.log(`π° Loan Risk: ${analysis.riskAssessment.loanRisk}`);
console.log(`πΈ Cash Flow Risk: ${analysis.riskAssessment.cashFlowRisk}`);
console.log('\nπ© KEY RED FLAGS:');
analysis.riskAssessment.riskFactors.forEach((factor, i) => {
console.log(`${i + 1}. ${factor}`);
});
console.log('\nπ TOP RECOMMENDATIONS:');
analysis.insights.recommendations.slice(0, 3).forEach((rec, i) => {
console.log(`${i + 1}. ${rec}`);
});
console.log('\nβ
REPORTS GENERATED:');
console.log(`π HTML Report: ${reportId}-report.html`);
console.log(`π JSON Data: reports/${reportId}.json`);
console.log('=' .repeat(60));
}
generateReport().catch(console.error);