Pub 946 Compliance
This commit is contained in:
95
server/services/section280fLimits.js
Normal file
95
server/services/section280fLimits.js
Normal file
@@ -0,0 +1,95 @@
|
||||
const { all, audit, now, one, run } = require('../db');
|
||||
|
||||
// §280F passenger-automobile annual depreciation caps, keyed by placed-in-service year (IRS Rev. Proc.,
|
||||
// indexed annually). Mirrors the §179-limits reference service: cached for the engine, CRUD for admins.
|
||||
|
||||
let cache = null;
|
||||
|
||||
function clearCache() {
|
||||
cache = null;
|
||||
}
|
||||
|
||||
function rows() {
|
||||
if (!cache) cache = all('SELECT * FROM section_280f_limits ORDER BY pis_year');
|
||||
return cache;
|
||||
}
|
||||
|
||||
// Caps for a placed-in-service year: the most recent configured year at or before it, or null.
|
||||
function getLimit(year) {
|
||||
const y = Number(year);
|
||||
if (!y) return null;
|
||||
let match = null;
|
||||
for (const row of rows()) {
|
||||
if (row.pis_year <= y) match = row;
|
||||
else break;
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
function fromRow(row) {
|
||||
return {
|
||||
id: row.id,
|
||||
pis_year: row.pis_year,
|
||||
year1_no_bonus: row.year1_no_bonus,
|
||||
year1_bonus: row.year1_bonus,
|
||||
year2: row.year2,
|
||||
year3: row.year3,
|
||||
year4plus: row.year4plus
|
||||
};
|
||||
}
|
||||
|
||||
function list() {
|
||||
return all('SELECT * FROM section_280f_limits ORDER BY pis_year DESC').map(fromRow);
|
||||
}
|
||||
|
||||
function normalize(body) {
|
||||
return {
|
||||
pis_year: Math.trunc(Number(body.pis_year)) || 0,
|
||||
year1_no_bonus: Number(body.year1_no_bonus) || 0,
|
||||
year1_bonus: Number(body.year1_bonus) || 0,
|
||||
year2: Number(body.year2) || 0,
|
||||
year3: Number(body.year3) || 0,
|
||||
year4plus: Number(body.year4plus) || 0
|
||||
};
|
||||
}
|
||||
|
||||
function createLimit(body, userId) {
|
||||
const input = normalize(body);
|
||||
if (!input.pis_year) throw Object.assign(new Error('A valid placed-in-service year is required'), { status: 400 });
|
||||
if (one('SELECT id FROM section_280f_limits WHERE pis_year = ?', [input.pis_year])) {
|
||||
throw Object.assign(new Error('Caps for that year already exist'), { status: 400 });
|
||||
}
|
||||
const ts = now();
|
||||
run(
|
||||
`INSERT INTO section_280f_limits (pis_year, year1_no_bonus, year1_bonus, year2, year3, year4plus, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[input.pis_year, input.year1_no_bonus, input.year1_bonus, input.year2, input.year3, input.year4plus, ts, ts]
|
||||
);
|
||||
clearCache();
|
||||
audit(userId, 'create', 'section_280f_limit', String(input.pis_year), null, input);
|
||||
return fromRow(one('SELECT * FROM section_280f_limits WHERE pis_year = ?', [input.pis_year]));
|
||||
}
|
||||
|
||||
function updateLimit(year, body, userId) {
|
||||
const before = one('SELECT * FROM section_280f_limits WHERE pis_year = ?', [Number(year)]);
|
||||
if (!before) return null;
|
||||
const input = normalize({ ...fromRow(before), ...body, pis_year: before.pis_year });
|
||||
run(
|
||||
'UPDATE section_280f_limits SET year1_no_bonus = ?, year1_bonus = ?, year2 = ?, year3 = ?, year4plus = ?, updated_at = ? WHERE pis_year = ?',
|
||||
[input.year1_no_bonus, input.year1_bonus, input.year2, input.year3, input.year4plus, now(), before.pis_year]
|
||||
);
|
||||
clearCache();
|
||||
audit(userId, 'update', 'section_280f_limit', String(before.pis_year), fromRow(before), input);
|
||||
return fromRow(one('SELECT * FROM section_280f_limits WHERE pis_year = ?', [before.pis_year]));
|
||||
}
|
||||
|
||||
function deleteLimit(year, userId) {
|
||||
const before = one('SELECT * FROM section_280f_limits WHERE pis_year = ?', [Number(year)]);
|
||||
if (!before) return false;
|
||||
run('DELETE FROM section_280f_limits WHERE pis_year = ?', [before.pis_year]);
|
||||
clearCache();
|
||||
audit(userId, 'delete', 'section_280f_limit', String(before.pis_year), fromRow(before), null);
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = { clearCache, createLimit, deleteLimit, getLimit, list, updateLimit };
|
||||
Reference in New Issue
Block a user