Add company bank/cards/addresses to financial export ZIP
Validate / validate (push) Successful in 24s

Three new CSVs in the export bundle, with matching README entries:
- company_bank_accounts.csv
- company_cards.csv (last4 only, joined with linked bank account name)
- company_addresses.csv

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-15 10:34:52 +07:00
parent 504fbadec4
commit eceda5f007
+101 -1
View File
@@ -18,7 +18,10 @@ import {
packages, packages,
externalAccounts, externalAccounts,
externalTransactions, externalTransactions,
users users,
companyBankAccounts,
companyCards,
companyAddresses
} from '../db/schema.js'; } from '../db/schema.js';
import { csvBuild } from '$lib/utils/csv.js'; import { csvBuild } from '$lib/utils/csv.js';
import { CARRIER_LABELS } from '../shipping/index.js'; import { CARRIER_LABELS } from '../shipping/index.js';
@@ -68,6 +71,9 @@ export async function buildFinancialExport(
``, ``,
`Files:`, `Files:`,
` company.csv — company record`, ` company.csv — company record`,
` company_bank_accounts.csv — company bank accounts`,
` company_cards.csv — company credit/debit cards (last 4 only)`,
` company_addresses.csv — legal/shipping/billing/other addresses`,
` projects.csv — all projects (active + inactive)`, ` projects.csv — all projects (active + inactive)`,
` parties.csv — all customers/suppliers (incl. archived; see deletedAt)`, ` parties.csv — all customers/suppliers (incl. archived; see deletedAt)`,
` employees.csv — all employees (incl. terminated/archived)`, ` employees.csv — all employees (incl. terminated/archived)`,
@@ -110,6 +116,100 @@ export async function buildFinancialExport(
) )
); );
// ── company_bank_accounts.csv ──────────────────────
{
const bankRows = await db
.select()
.from(companyBankAccounts)
.where(eq(companyBankAccounts.companyId, companyId))
.orderBy(asc(companyBankAccounts.bankName));
const rows: unknown[][] = [
[
'id', 'bankName', 'accountName', 'accountNumber', 'accountType', 'branch',
'swiftBic', 'iban', 'currency', 'isPrimary', 'isActive', 'notes',
'createdAt', 'updatedAt'
]
];
for (const b of bankRows) {
rows.push([
b.id, b.bankName, b.accountName, b.accountNumber, b.accountType ?? '',
b.branch ?? '', b.swiftBic ?? '', b.iban ?? '', b.currency,
b.isPrimary, b.isActive, b.notes ?? '',
b.createdAt.toISOString(), b.updatedAt.toISOString()
]);
}
zip.file('company_bank_accounts.csv', withBom(csvBuild(rows)));
}
// ── company_cards.csv ──────────────────────────────
{
const cardRows = await db
.select({
id: companyCards.id,
brand: companyCards.brand,
last4: companyCards.last4,
cardholderName: companyCards.cardholderName,
expiryMonth: companyCards.expiryMonth,
expiryYear: companyCards.expiryYear,
nickname: companyCards.nickname,
bankAccountId: companyCards.bankAccountId,
bankAccountName: companyBankAccounts.bankName,
isActive: companyCards.isActive,
notes: companyCards.notes,
createdAt: companyCards.createdAt,
updatedAt: companyCards.updatedAt
})
.from(companyCards)
.leftJoin(companyBankAccounts, eq(companyCards.bankAccountId, companyBankAccounts.id))
.where(eq(companyCards.companyId, companyId))
.orderBy(asc(companyCards.brand));
const rows: unknown[][] = [
[
'id', 'brand', 'last4', 'cardholderName', 'expiryMonth', 'expiryYear',
'nickname', 'bankAccountId', 'bankAccountName', 'isActive', 'notes',
'createdAt', 'updatedAt'
]
];
for (const c of cardRows) {
rows.push([
c.id, c.brand, c.last4, c.cardholderName,
c.expiryMonth ?? '', c.expiryYear ?? '',
c.nickname ?? '', c.bankAccountId ?? '', c.bankAccountName ?? '',
c.isActive, c.notes ?? '',
c.createdAt.toISOString(), c.updatedAt.toISOString()
]);
}
zip.file('company_cards.csv', withBom(csvBuild(rows)));
}
// ── company_addresses.csv ──────────────────────────
{
const addrRows = await db
.select()
.from(companyAddresses)
.where(eq(companyAddresses.companyId, companyId))
.orderBy(asc(companyAddresses.type));
const rows: unknown[][] = [
[
'id', 'type', 'label', 'recipient',
'addressLine1', 'addressLine2', 'subdistrict', 'district', 'province',
'postalCode', 'country', 'contactPerson', 'contactPhone',
'isDefault', 'notes', 'createdAt', 'updatedAt'
]
];
for (const a of addrRows) {
rows.push([
a.id, a.type, a.label ?? '', a.recipient ?? '',
a.addressLine1 ?? '', a.addressLine2 ?? '', a.subdistrict ?? '',
a.district ?? '', a.province ?? '', a.postalCode ?? '', a.country,
a.contactPerson ?? '', a.contactPhone ?? '',
a.isDefault, a.notes ?? '',
a.createdAt.toISOString(), a.updatedAt.toISOString()
]);
}
zip.file('company_addresses.csv', withBom(csvBuild(rows)));
}
// ── projects.csv ──────────────────────────────────── // ── projects.csv ────────────────────────────────────
const projectRows = await db const projectRows = await db
.select() .select()