KLEINUILTIES-WEBAPP/js/seed.js
Slim Uiltjies App 1939bf2ef4 Initial commit: Slim Uiltjies AfterCare invoice system
- Progressive Web App with Express + JSON backend
- PIN-based auth, multi-device sync
- Invoice + Statement PDF generation (branded, Grandstander + Nunito)
- Mobile + Desktop responsive layouts
- n8n backup integration
- Custom logo upload
- Settings for business info, fees, banking
- Bulk invoice generation
- Web Share API integration
2026-08-08 09:25:17 +02:00

219 lines
9 KiB
JavaScript

/* Slim Uiltjies — Sample seed data
Pre-populates the app so it works immediately on first load.
*/
(function () {
'use strict';
async function seed({ force = false } = {}) {
const seeded = await window.SUDB.getMeta('seeded');
if (seeded && !force) return false;
if (force) {
await window.SUDB.clear('parents');
await window.SUDB.clear('children');
await window.SUDB.clear('invoices');
await window.SUDB.clear('payments');
await window.SUDB.clear('business');
}
// Business info — pulled from the original receipt
await window.SUDB.saveBusiness({
name: 'Slim Uiltjies AfterCare',
tagline: 'A safe place to learn, grow and shine!',
address: 'A loving aftercare, a second home.',
phone: '084 770 7077',
email: '',
facebook: 'Slim Uiltjies AfterCare',
currency: 'R',
currencyCode: 'ZAR',
taxNote: '',
bankName: '',
accountHolder: '',
accountNumber: '',
branchCode: '',
referenceNote: 'Use child name as payment reference',
footerNote: "We truly appreciate your timely payments.\nTogether we make a difference in our children's future!",
receiptPrefix: 'SU',
nextReceiptNumber: 1,
defaultFullDayFee: 500,
defaultHalfDayFee: 300,
updatedAt: new Date().toISOString(),
});
// Parents
const parents = [
{ id: 1, name: 'Valentine', phone: '082 123 4567', email: 'valentine@example.com', address: '12 Acacia Street, Pretoria', notes: '', createdAt: new Date().toISOString() },
{ id: 2, name: 'Nomsa Dlamini', phone: '073 555 0102', email: 'nomsa@example.com', address: '4 Violet Lane, Centurion', notes: '', createdAt: new Date().toISOString() },
{ id: 3, name: 'Pieter van Wyk', phone: '083 444 9988', email: 'pieter@example.com', address: '78 Garden Road, Hatfield', notes: '', createdAt: new Date().toISOString() },
];
for (const p of parents) await window.SUDB.put('parents', p);
// Children
const children = [
{ id: 1, parentId: 1, name: 'Tshireletso', plan: 'full', monthlyFee: 500, startDate: '2025-01-01', endDate: '', notes: '', createdAt: new Date().toISOString() },
{ id: 2, parentId: 2, name: 'Lerato', plan: 'full', monthlyFee: 500, startDate: '2025-02-01', endDate: '', notes: '', createdAt: new Date().toISOString() },
{ id: 3, parentId: 2, name: 'Themba', plan: 'half', monthlyFee: 300, startDate: '2025-02-01', endDate: '', notes: '', createdAt: new Date().toISOString() },
{ id: 4, parentId: 3, name: 'Mia', plan: 'full', monthlyFee: 500, startDate: '2025-03-01', endDate: '', notes: '', createdAt: new Date().toISOString() },
];
for (const c of children) await window.SUDB.put('children', c);
// Historical invoices (mirroring the original receipt's proof of payments)
const now = new Date();
const year = now.getFullYear();
const months = [
`${year}-01`, `${year}-02`, `${year}-03`, `${year}-04`, `${year}-05`, `${year}-06`
];
let invId = 1;
let payId = 1;
// Build the same payment pattern as the receipt for Tshireletso
// March is missing on the original receipt — left unpaid (no payment record)
const tsInvoices = [
{ period: `${year}-01`, day: 7, amount: 500, method: 'cash', by: 'Syl-Marie' },
{ period: `${year}-02`, day: 25, amount: 500, method: 'cash', by: 'Syl-Marie' },
{ period: `${year}-03`, day: 0, amount: 0, method: null, by: null },
{ period: `${year}-04`, day: 24, amount: 1000, method: 'cash', by: 'Syl-Marie' },
{ period: `${year}-05`, day: 23, amount: 500, method: 'cash', by: 'Syl-Marie' },
{ period: `${year}-06`, day: 29, amount: 500, method: 'cash', by: 'Syl-Marie' },
];
for (const item of tsInvoices) {
const [yy, mm] = item.period.split('-').map(Number);
const issueDate = `${yy}-${String(mm).padStart(2, '0')}-05`;
const dueDate = `${yy}-${String(mm).padStart(2, '0')}-25`;
const inv = {
id: invId++,
number: `SU-${String(invId - 1).padStart(4, '0')}`,
parentId: 1,
childId: 1,
period: item.period,
issueDate,
dueDate,
items: [{ description: `AfterCare Fees — ${formatPeriod(item.period)}`, quantity: 1, unitPrice: 500, total: 500 }],
subtotal: 500,
total: 500,
paid: item.amount,
balance: Math.max(0, 500 - item.amount),
status: item.amount >= 500 ? 'paid' : (item.amount > 0 ? 'partial' : 'unpaid'),
notes: item.amount === 1000 ? 'March + April combined payment' : '',
createdAt: new Date().toISOString(),
};
await window.SUDB.put('invoices', inv);
if (item.amount > 0) {
const payDate = `${yy}-${String(mm).padStart(2, '0')}-${String(item.day).padStart(2, '0')}`;
await window.SUDB.put('payments', {
id: payId++,
invoiceId: inv.id,
date: payDate,
amount: item.amount,
method: item.method,
receivedBy: item.by,
notes: '',
createdAt: new Date().toISOString(),
});
}
}
// Add an unpaid invoice for Lerato this month
const currentPeriod = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
const [yy2, mm2] = currentPeriod.split('-').map(Number);
const lerInv = {
id: invId++,
number: `SU-${String(invId - 1).padStart(4, '0')}`,
parentId: 2,
childId: 2,
period: currentPeriod,
issueDate: `${yy2}-${String(mm2).padStart(2, '0')}-01`,
dueDate: `${yy2}-${String(mm2).padStart(2, '0')}-25`,
items: [{ description: `AfterCare Fees — ${formatPeriod(currentPeriod)}`, quantity: 1, unitPrice: 500, total: 500 }],
subtotal: 500, total: 500, paid: 0, balance: 500,
status: 'unpaid', notes: '', createdAt: new Date().toISOString(),
};
await window.SUDB.put('invoices', lerInv);
// Paid invoice for Lerato previous month
const prevDate = new Date(now.getFullYear(), now.getMonth() - 1, 1);
const prevPeriod = `${prevDate.getFullYear()}-${String(prevDate.getMonth() + 1).padStart(2, '0')}`;
const lerPrev = {
id: invId++,
number: `SU-${String(invId - 1).padStart(4, '0')}`,
parentId: 2,
childId: 2,
period: prevPeriod,
issueDate: `${prevPeriod}-01`,
dueDate: `${prevPeriod}-25`,
items: [{ description: `AfterCare Fees — ${formatPeriod(prevPeriod)}`, quantity: 1, unitPrice: 500, total: 500 }],
subtotal: 500, total: 500, paid: 500, balance: 0,
status: 'paid', notes: '', createdAt: new Date().toISOString(),
};
await window.SUDB.put('invoices', lerPrev);
await window.SUDB.put('payments', {
id: payId++,
invoiceId: lerPrev.id,
date: `${prevPeriod}-15`,
amount: 500,
method: 'eft',
receivedBy: 'Syl-Marie',
notes: '',
createdAt: new Date().toISOString(),
});
// Mia — paid current month
const miaInv = {
id: invId++,
number: `SU-${String(invId - 1).padStart(4, '0')}`,
parentId: 3,
childId: 4,
period: currentPeriod,
issueDate: `${yy2}-${String(mm2).padStart(2, '0')}-01`,
dueDate: `${yy2}-${String(mm2).padStart(2, '0')}-25`,
items: [{ description: `AfterCare Fees — ${formatPeriod(currentPeriod)}`, quantity: 1, unitPrice: 500, total: 500 }],
subtotal: 500, total: 500, paid: 500, balance: 0,
status: 'paid', notes: '', createdAt: new Date().toISOString(),
};
await window.SUDB.put('invoices', miaInv);
await window.SUDB.put('payments', {
id: payId++,
invoiceId: miaInv.id,
date: `${yy2}-${String(mm2).padStart(2, '0')}-10`,
amount: 500, method: 'cash', receivedBy: 'Syl-Marie',
notes: '', createdAt: new Date().toISOString(),
});
// Themba — paid half-day fees
const thembaInv = {
id: invId++,
number: `SU-${String(invId - 1).padStart(4, '0')}`,
parentId: 2,
childId: 3,
period: currentPeriod,
issueDate: `${yy2}-${String(mm2).padStart(2, '0')}-01`,
dueDate: `${yy2}-${String(mm2).padStart(2, '0')}-25`,
items: [{ description: `AfterCare Fees (Half Day) — ${formatPeriod(currentPeriod)}`, quantity: 1, unitPrice: 300, total: 300 }],
subtotal: 300, total: 300, paid: 300, balance: 0,
status: 'paid', notes: '', createdAt: new Date().toISOString(),
};
await window.SUDB.put('invoices', thembaInv);
await window.SUDB.put('payments', {
id: payId++,
invoiceId: thembaInv.id,
date: `${yy2}-${String(mm2).padStart(2, '0')}-12`,
amount: 300, method: 'eft', receivedBy: 'Syl-Marie',
notes: '', createdAt: new Date().toISOString(),
});
await window.SUDB.setMeta('seeded', true);
await window.SUDB.setMeta('seededAt', new Date().toISOString());
await window.SUDB.setMeta('nextReceipt', invId);
return true;
}
function formatPeriod(p) {
const [y, m] = p.split('-').map(Number);
const months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
return `${months[m - 1]} ${y}`;
}
window.SUSeed = { seed };
})();