USER
function processData() {
const input = document.getElementById('inputText').value.trim();
const yearInput = document.getElementById('yearInput').value.trim();
const outputDiv = document.getElementById('output');
outputDiv.innerHTML = '';
const headers = \['Date', 'Description', 'Debit', 'Credit', 'Balance'];
const rows = \[];
const table = document.createElement('table');
// Copy buttons row
const copyRow = document.createElement('tr');
headers.forEach((\_, index) => {
const th = document.createElement('th');
const div = document.createElement('div');
div.className = 'copy-col';
const btn = document.createElement('button');
btn.textContent = 'Copy';
btn.className = 'copy-btn';
btn.onclick = () => window\.bankUtils.copyColumn(index);
div.appendChild(btn);
th.appendChild(div);
copyRow\.appendChild(th);
});
table.appendChild(copyRow);
// Header row
const headerRow = document.createElement('tr');
headers.forEach(header => {
const th = document.createElement('th');
th.textContent = header;
headerRow\.appendChild(th);
});
table.appendChild(headerRow);
const lines = input.split('\n').map(l => l.trim()).filter(Boolean);
let buffer = \[];
let lastBalance = null;
const flushBuffer = () => {
if (buffer.length === 0) return;
```
const full = buffer.join(' ');
const dateMatch = full.match(/\b(\d{2}\/\d{2}\/\d{4})\b/);
const amounts = [...full.matchAll(/-?\d{1,3}(?:,\d{3})*\.\d{2}/g)].map(m => m[0].replace(/,/g, ''));
if (!dateMatch || amounts.length < 2) {
buffer = [];
return;
}
let date = dateMatch[1];
if (yearInput) {
const parts = date.split('/');
date = `${parts[0]}/${parts[1]}/${yearInput}`;
}
const amount = parseFloat(amounts[amounts.length - 2]);
const balance = parseFloat(amounts[amounts.length - 1]);
let description = full
.replace(dateMatch[0], '')
.replace(/-?\d{1,3}(?:,\d{3})*\.\d{2}/g, '')
.replace(/\s+/g, ' ')
.trim();
let debit = '', credit = '';
if (lastBalance !== null) {
if (balance < lastBalance) {
debit = amount.toFixed(2);
} else {
credit = amount.toFixed(2);
}
} else {
// If no prior balance, default to debit
debit = amount.toFixed(2);
}
lastBalance = balance;
const row = [date, description, debit, credit, balance.toFixed(2)];
rows.push(row);
const tr = document.createElement('tr');
row.forEach(cell => {
const td = document.createElement('td');
td.textContent = cell;
tr.appendChild(td);
});
table.appendChild(tr);
buffer = [];
```
};
lines.forEach(line => {
if (/^\d{2}/\d{2}/\d{4}/.test(line)) {
flushBuffer();
buffer.push(line);
} else {
buffer.push(line);
}
});
flushBuffer(); // Final flush
outputDiv.appendChild(table);
table.dataset.rows = JSON.stringify(rows);
}
window\.processData = processData;
this is scotiaAccount, now create a similar script to recognize and allocate the debit and credit for this data for tdinPerson.js
Jan31,2024 PAPER STMT FEE 3.00 \$243,689.42
Jan 31,2024 ACCT BAL REBATE 19.00 \$243,692.42
Jan31,2024 MONTHLY PLAN FEE 19.00 \$243,673.42
Jan26,2024 MONEY MART #629 299.99 \$243,692.42
Jan 26, 2024 GC 0110-CASH WITHDRA 300.00 \$243,992.41
Jan26,2024 GC0110-TRANSFER 2,000.00 \$244,292.41
Jan26,2024 CREDIT CARD PAYMENT 1,000.00 \$246,292.41
Jan26,2024 GC 0110-DEPOSIT 6,152.86 \$247,292.41
Jan22,2024 64068 MACS CONV 23.38 \$241,139.55
Jan 22,2024 DARRYLL & TRACY 101.12 \$241,162.93
Jan 16,2024 TRANSFER 2,000.00 \$241,264.05
Jan 16,2024 CREDIT CARD PAYMENT 422.51 \$243,264.05
Jan 16,2024 CREDIT CARD PAYMENT 1,000.00 \$243,686.56
Jan 16,2024 DEPOSIT 7,363.84 \$244,686.56
Jan02,2024 NDL GROUP RLS 1,460.42 \$237,322.72
Jan 02,2024 PTS TO: 00536881245 200.00 \$238,783.14
mind the date , sometimes with space sometimes no
it looks like this, it needs to track balances to allocate the debit and credit based on differences similar to the scotia script , give it in full
but bear in mind in this one transactions are always single line like this, so no need for multi line detection like scotia, just keep it simple and make sure the tracking is rocksolid
make sure to make it understand that the first line will always be either:
1. opening balance (a number that goes in balance)
2. a transaction that goes into debit as a default
BE CAREFUL THAT IN THIS BANK, BALANCE IS RAISED BY A DEBIT STATEMENT , AND IT IS LOWERED BY CREDIT TRANSACTIONS SO:
Jan31,2024 PAPER STMT FEE 3.00 $243,689.42
Jan 31,2024 ACCT BAL REBATE 19.00 $243,692.42
Jan31,2024 MONTHLY PLAN FEE 19.00 $243,673.42
Jan26,2024 MONEY MART #629 299.99 $243,692.42
Jan 26, 2024 GC 0110-CASH WITHDRA 300.00 $243,992.41
Jan26,2024 GC0110-TRANSFER 2,000.00 $244,292.41
Jan26,2024 CREDIT CARD PAYMENT 1,000.00 $246,292.41
Jan26,2024 GC 0110-DEPOSIT 6,152.86 $247,292.41
Jan22,2024 64068 MACS CONV 23.38 $241,139.55
Jan 22,2024 DARRYLL & TRACY 101.12 $241,162.93
Jan 16,2024 TRANSFER 2,000.00 $241,264.05
Jan 16,2024 CREDIT CARD PAYMENT 422.51 $243,264.05
Jan 16,2024 CREDIT CARD PAYMENT 1,000.00 $243,686.56
Jan 16,2024 DEPOSIT 7,363.84 $244,686.56
Jan02,2024 NDL GROUP RLS 1,460.42 $237,322.72
Jan 02,2024 PTS TO: 00536881245 200.00 $238,783.14
IN THESE THE 19 IS CREDIT, AND THE 6,152.86 , AND THE 7,363.84 IS CREDIT, WHILE THE REST IS DEBIT, CAN YOU GIVE ME THE FULL JS ACCORDINGLY?? ensure the proper architecture that connects with my main.js and index.html the same way as the sample js given at the beginning please!ASSISTANT
Certainly! Below is a full, self-contained JS script for your `tdinPerson.js`, which processes the given Scotia-style bank statement lines you shared. It closely follows your format and logic requests, maintaining the architecture of your original `processData()` for easy integration with your `main.js` and `index.html`.
---
### How it works:
- Input text contains one transaction per line.
- Date parsing flexible for space or no space after month.
- Amount & balance extracted reliably.
- First line determines whether it’s opening balance or a debit transaction defaulting debit.
- Debit and credit allocation logic **reversed** compared to Scotia:
- **If balance increases, the transaction is debit**.
- **If balance decreases, the transaction is credit**.
- Build table with:
- Copy buttons for each column header
- Rows for each transaction
---
```js
function processData() {
const input = document.getElementById('inputText').value.trim();
const yearInput = document.getElementById('yearInput').value.trim(); // optional
const outputDiv = document.getElementById('output');
outputDiv.innerHTML = '';
const headers = ['Date', 'Description', 'Debit', 'Credit', 'Balance'];
const rows = [];
const table = document.createElement('table');
// Copy buttons row
const copyRow = document.createElement('tr');
headers.forEach((_, index) => {
const th = document.createElement('th');
const div = document.createElement('div');
div.className = 'copy-col';
const btn = document.createElement('button');
btn.textContent = 'Copy';
btn.className = 'copy-btn';
btn.onclick = () => window.bankUtils.copyColumn(index);
div.appendChild(btn);
th.appendChild(div);
copyRow.appendChild(th);
});
table.appendChild(copyRow);
// Header row
const headerRow = document.createElement('tr');
headers.forEach(header => {
const th = document.createElement('th');
th.textContent = header;
headerRow.appendChild(th);
});
table.appendChild(headerRow);
// Helper function to parse date with or without space after month
function normalizeDate(dateStr) {
// Date formats in input like: Jan31,2024 or Jan 31,2024
// We'll unify to MM/DD/YYYY for easy reading
// Parse and convert to MM/DD/YYYY:
// month name => MM number
const monthMap = {
Jan: '01', Feb: '02', Mar: '03', Apr: '04',
May: '05', Jun: '06', Jul: '07', Aug: '08',
Sep: '09', Oct: '10', Nov: '11', Dec: '12'
};
// Remove comma, split by space or no space
// Try to match "Jan31,2024" or "Jan 31,2024"
let m = dateStr.match(/^([A-Za-z]{3})\s?(\d{1,2}),(\d{4})$/);
if (!m) return dateStr; // fallback: return as-is if format unknown
const mm = monthMap[m[1]] || '01';
let dd = m[2].padStart(2, '0');
const yyyy = m[3];
// If yearInput given override yyyy to that
const year = yearInput || yyyy;
return `${mm}/${dd}/${year}`;
}
const lines = input.split('\n').map(l => l.trim()).filter(Boolean);
let lastBalance = null;
lines.forEach((line, idx) => {
// Example line:
// Jan31,2024 PAPER STMT FEE 3.00 $243,689.42
// Jan 26, 2024 GC 0110-CASH WITHDRA 300.00 $243,992.41
// Regex to capture:
// 1) date (Jan31,2024 or Jan 31, 2024)
// 2) description (anything until amount)
// 3) amount (last number before balance)
// 4) balance (last $ number)
// Strategy:
// - Match date at line start (with optional spaces)
// - Then capture everything up to last two numbers (amount and balance)
// - Amount is before balance
// Step1: Extract date using flexible regex for either no space or space after month:
const dateMatch = line.match(/^([A-Za-z]{3}\s?\d{1,2},\s?\d{4})/);
if (!dateMatch) return; // skip malformed line
const rawDate = dateMatch[1];
const date = normalizeDate(rawDate);
// Remove date part from line
let rest = line.slice(rawDate.length).trim();
// Extract balance at the end (format $xxx,xxx.xx)
const balanceMatch = rest.match(/\$[\d,]+\.\d{2}$/);
if (!balanceMatch) return; // skip line if no balance
const balanceStr = balanceMatch[0];
const balanceNum = parseFloat(balanceStr.replace(/[\$,]/g, ''));
// Remove balance from rest
rest = rest.slice(0, rest.lastIndexOf(balanceStr)).trim();
// Extract amount at the end of rest (could have commas, decimal)
// The amount is the last numeric value before balance
// We'll match last number with optional commas and decimal
const amountMatch = rest.match(/-?[\d,]+\.\d{2}$/);
if (!amountMatch) return; // skip if no amount
const amountStr = amountMatch[0];
const amountNum = parseFloat(amountStr.replace(/,/g, ''));
// Remove amount from rest to get description
let description = rest.slice(0, rest.lastIndexOf(amountStr)).trim();
// Logic for debit/credit based on balance change rule:
// First line special case:
// If lastBalance is null:
// - If current balance == amount, consider it opening balance, debit and credit empty
// - Else consider transaction debit = amount by default.
let debit = '';
let credit = '';
if (lastBalance === null) {
// guess if first line is balance or transaction
// If balance equals amount, opening balance
// (however in data the amount is transaction value; balance is separate,
// so assume first line is transaction, debit by default)
// But example:
// Ex: Jan31,2024 PAPER STMT FEE 3.00 $243,689.42
// amount = 3.00, balance = 243,689.42
// so first line generally a transaction and debit by default
debit = amountNum.toFixed(2);
} else {
// According to instruction:
// If balance is raised by debit, lowered by credit:
// if balance > lastBalance => debit transaction
// if balance < lastBalance => credit transaction
if (balanceNum > lastBalance) {
debit = amountNum.toFixed(2);
} else if (balanceNum < lastBalance) {
credit = amountNum.toFixed(2);
} else {
// no change? default to debit
debit = amountNum.toFixed(2);
}
}
lastBalance = balanceNum;
const row = [date, description, debit, credit, balanceNum.toFixed(2)];
rows.push(row);
const tr = document.createElement('tr');
row.forEach(cell => {
const td = document.createElement('td');
td.textContent = cell;
tr.appendChild(td);
});
table.appendChild(tr);
});
outputDiv.appendChild(table);
table.dataset.rows = JSON.stringify(rows);
}
window.processData = processData;
```
---
### Notes:
- This fully functional `processData` function expects HTML elements:
- `#inputText` textarea/input for user data
- `#yearInput` input for optional year override (can be blank)
- `#output` div where table is rendered
- Assumes `window.bankUtils.copyColumn` function is defined as in your original setup.
- Adapt styles and buttons as needed in your HTML/CSS.
---
If you want me to also generate a minimal `index.html` example using this JS, just ask!