119 lines
4.7 KiB
JavaScript
119 lines
4.7 KiB
JavaScript
const { all, audit, now, one, run } = require('../db');
|
|
|
|
let cache = null;
|
|
|
|
function clearCache() {
|
|
cache = null;
|
|
}
|
|
|
|
function lookup() {
|
|
if (!cache) {
|
|
cache = {};
|
|
for (const row of all('SELECT * FROM depreciation_zones')) cache[row.code] = row;
|
|
}
|
|
return cache;
|
|
}
|
|
|
|
// Raw row (incl. dates) for the engine; null when unknown or disabled.
|
|
function getZone(code) {
|
|
if (!code) return null;
|
|
const zone = lookup()[code];
|
|
return zone && zone.enabled ? zone : null;
|
|
}
|
|
|
|
function slugify(value) {
|
|
return String(value || '').trim().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '').slice(0, 40);
|
|
}
|
|
|
|
function fromRow(row) {
|
|
if (!row) return null;
|
|
return {
|
|
id: row.id,
|
|
code: row.code,
|
|
name: row.name,
|
|
allowance_percent: row.allowance_percent,
|
|
pis_start: row.pis_start,
|
|
pis_end: row.pis_end,
|
|
real_property_end: row.real_property_end,
|
|
max_recovery_years: row.max_recovery_years,
|
|
leasehold_life_years: row.leasehold_life_years,
|
|
section_179_increase: row.section_179_increase,
|
|
section_179_cost_factor: row.section_179_cost_factor,
|
|
notes: row.notes,
|
|
enabled: Boolean(row.enabled),
|
|
asset_count: one('SELECT COUNT(*) AS c FROM assets WHERE special_zone = ?', [row.code]).c
|
|
};
|
|
}
|
|
|
|
function list() {
|
|
return all('SELECT * FROM depreciation_zones ORDER BY name').map(fromRow);
|
|
}
|
|
|
|
function normalize(body) {
|
|
const num = (v) => (v === '' || v === null || v === undefined ? null : Number(v));
|
|
return {
|
|
name: String(body.name || '').trim(),
|
|
allowance_percent: Number(body.allowance_percent) || 0,
|
|
pis_start: body.pis_start || null,
|
|
pis_end: body.pis_end || null,
|
|
real_property_end: body.real_property_end || null,
|
|
max_recovery_years: num(body.max_recovery_years),
|
|
leasehold_life_years: num(body.leasehold_life_years),
|
|
section_179_increase: Number(body.section_179_increase) || 0,
|
|
section_179_cost_factor: body.section_179_cost_factor === '' || body.section_179_cost_factor === null || body.section_179_cost_factor === undefined ? 1 : Number(body.section_179_cost_factor),
|
|
notes: body.notes || null,
|
|
enabled: body.enabled === false ? 0 : 1
|
|
};
|
|
}
|
|
|
|
function createZone(body, userId) {
|
|
const input = normalize(body);
|
|
if (!input.name) throw Object.assign(new Error('A zone name is required'), { status: 400 });
|
|
const code = slugify(body.code || input.name);
|
|
if (!code) throw Object.assign(new Error('A valid zone code is required'), { status: 400 });
|
|
if (one('SELECT id FROM depreciation_zones WHERE code = ?', [code])) {
|
|
throw Object.assign(new Error('A zone with that code already exists'), { status: 400 });
|
|
}
|
|
const ts = now();
|
|
run(
|
|
`INSERT INTO depreciation_zones (code, name, allowance_percent, pis_start, pis_end, real_property_end, max_recovery_years, leasehold_life_years, section_179_increase, section_179_cost_factor, notes, enabled, created_at, updated_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
[code, input.name, input.allowance_percent, input.pis_start, input.pis_end, input.real_property_end, input.max_recovery_years, input.leasehold_life_years, input.section_179_increase, input.section_179_cost_factor, input.notes, input.enabled, ts, ts]
|
|
);
|
|
clearCache();
|
|
audit(userId, 'create', 'depreciation_zone', code, null, input);
|
|
return fromRow(one('SELECT * FROM depreciation_zones WHERE code = ?', [code]));
|
|
}
|
|
|
|
function updateZone(code, body, userId) {
|
|
const before = one('SELECT * FROM depreciation_zones WHERE code = ?', [code]);
|
|
if (!before) return null;
|
|
const input = normalize({ ...before, ...body, enabled: body.enabled === undefined ? Boolean(before.enabled) : body.enabled });
|
|
run(
|
|
`UPDATE depreciation_zones SET name = ?, allowance_percent = ?, pis_start = ?, pis_end = ?, real_property_end = ?,
|
|
max_recovery_years = ?, leasehold_life_years = ?, section_179_increase = ?, section_179_cost_factor = ?, notes = ?, enabled = ?, updated_at = ? WHERE code = ?`,
|
|
[input.name, input.allowance_percent, input.pis_start, input.pis_end, input.real_property_end, input.max_recovery_years, input.leasehold_life_years, input.section_179_increase, input.section_179_cost_factor, input.notes, input.enabled, now(), code]
|
|
);
|
|
clearCache();
|
|
audit(userId, 'update', 'depreciation_zone', code, before, input);
|
|
return fromRow(one('SELECT * FROM depreciation_zones WHERE code = ?', [code]));
|
|
}
|
|
|
|
function deleteZone(code, userId) {
|
|
const before = one('SELECT * FROM depreciation_zones WHERE code = ?', [code]);
|
|
if (!before) return false;
|
|
run('DELETE FROM depreciation_zones WHERE code = ?', [code]);
|
|
clearCache();
|
|
audit(userId, 'delete', 'depreciation_zone', code, before, null);
|
|
return true;
|
|
}
|
|
|
|
module.exports = {
|
|
clearCache,
|
|
createZone,
|
|
deleteZone,
|
|
getZone,
|
|
list,
|
|
updateZone
|
|
};
|