plugin-financials/services/accountSeedingService.js
2025-11-03 13:51:33 +02:00

71 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { ChartOfAccountsRepository } = require('../repositories');
const logger = require('../../../src/utils/logger');
// Define the 7 default accounts to seed for every new HOA site
const DEFAULT_ACCOUNTS = [
{ code: '1000', name: 'Checking Account', type: 'asset', description: 'Holds all cash; receives monthly fees, pays all bills.' },
{ code: '1100', name: 'Accounts Receivable Owners', type: 'asset', description: 'Tracks unpaid monthly service fees (who owes what).' },
{ code: '2000', name: 'Accounts Payable Vendors', type: 'liability', description: 'Tracks unpaid bills (what the HOA owes).' },
{ code: '2100', name: 'Prepaid Assessments', type: 'liability', description: 'Records fees paid in advance (liability until earned).' },
{ code: '3100', name: 'HOA Fund Balance', type: 'equity', description: 'Starting/ending equity; required for balance sheet.' },
{ code: '4100', name: 'Monthly Service Fees', type: 'income', description: 'All regular income comes here.' },
{ code: '5100', name: 'Operating Expenses', type: 'expense', description: 'All spending (utilities, repairs, insurance, etc.).' }
];
/**
* Seed default financial accounts for a given site
* This function is idempotent per account code per site: it skips any that already exist.
* @param {string} siteId
* @param {string|null} createdByUserId
*/
async function seedDefaultAccounts(siteId, createdByUserId = null) {
const chartOfAccountsRepository = new ChartOfAccountsRepository();
const createdAccountIds = [];
try {
for (const acc of DEFAULT_ACCOUNTS) {
// Skip if exists
const exists = await chartOfAccountsRepository.findByCode(siteId, acc.code);
if (exists) {
continue;
}
const newAccount = await chartOfAccountsRepository.createAccount({
site_id: siteId,
account_code: acc.code,
account_name: acc.name,
account_type: acc.type,
description: acc.description,
is_active: true,
// created_by is optional in repository
...(createdByUserId ? { created_by: createdByUserId } : {})
});
if (newAccount && newAccount.id) {
createdAccountIds.push(newAccount.id);
}
}
logger.info(`Seeded default financial accounts for site ${siteId}: ${createdAccountIds.length} created`);
return { success: true, created: createdAccountIds.length };
} catch (error) {
// Best-effort rollback of any accounts created in this run
try {
for (const id of createdAccountIds) {
await chartOfAccountsRepository.deleteById(id);
}
logger.warn(`Rolled back ${createdAccountIds.length} seeded accounts for site ${siteId} due to error.`);
} catch (rollbackError) {
logger.error('Failed to rollback seeded accounts:', rollbackError);
}
logger.error('Failed to seed default accounts:', error);
throw error;
}
}
module.exports = {
seedDefaultAccounts,
DEFAULT_ACCOUNTS
};