sales tax 2.

This commit is contained in:
2026-05-31 13:03:27 -05:00
parent 3517c9aec2
commit 8672eb6340
6 changed files with 123 additions and 20 deletions

View File

@@ -118,6 +118,12 @@ router.post('/sales-tax/periods/:id/record', async (req, res) => {
} catch (err) { handleQboError(err, res, 'sales-tax-record'); }
});
router.post('/sales-tax/periods/:id/mark-external', async (req, res) => {
try {
res.json(await accountingService.markTaxPaidExternal(req.params.id));
} catch (err) { handleQboError(err, res, 'sales-tax-mark-external'); }
});
// ════════════════════════════════════════════════════════════════════
// Phase 2 Lieferung 1 — Sync + Cache-Reads
// ════════════════════════════════════════════════════════════════════

View File

@@ -527,8 +527,8 @@ async function upsertTaxPeriod(period) {
(period_start, period_end, total_sales, nontaxable_sales, taxable_sales, tax_collected,
adjustment_amount, adjustment_reason, adjustment_account_id, adjustment_account_name,
net_paid, bank_account_id, bank_account_name,
sales_tax_payable_id, sales_tax_payable_name)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15)
sales_tax_payable_id, sales_tax_payable_name, status)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16)
ON CONFLICT (period_start, period_end) DO UPDATE SET
total_sales = EXCLUDED.total_sales,
nontaxable_sales = EXCLUDED.nontaxable_sales,
@@ -543,6 +543,7 @@ async function upsertTaxPeriod(period) {
bank_account_name = COALESCE(sales_tax_periods.bank_account_name, EXCLUDED.bank_account_name),
sales_tax_payable_id = COALESCE(sales_tax_periods.sales_tax_payable_id, EXCLUDED.sales_tax_payable_id),
sales_tax_payable_name = COALESCE(sales_tax_periods.sales_tax_payable_name, EXCLUDED.sales_tax_payable_name),
status = COALESCE(sales_tax_periods.status, EXCLUDED.status),
updated_at = CURRENT_TIMESTAMP
RETURNING *`,
[
@@ -551,7 +552,8 @@ async function upsertTaxPeriod(period) {
period.adjustment_amount || 0, period.adjustment_reason || null,
period.adjustment_account_id || null, period.adjustment_account_name || null,
period.net_paid || null, period.bank_account_id || null, period.bank_account_name || null,
period.sales_tax_payable_id || null, period.sales_tax_payable_name || null
period.sales_tax_payable_id || null, period.sales_tax_payable_name || null,
period.status || 'open'
]
);
return result.rows[0];
@@ -637,7 +639,7 @@ async function createTaxPaymentJE({
await pool.query(
`UPDATE sales_tax_periods
SET qbo_journal_entry_id = $1, booked_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
SET qbo_journal_entry_id = $1, status = 'booked', booked_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
WHERE id = $2`,
[je.Id, periodId]
);
@@ -645,6 +647,22 @@ async function createTaxPaymentJE({
return { qbo_journal_entry_id: je.Id, qbo_sync_token: je.SyncToken };
}
async function markTaxPaidExternal(periodId) {
const result = await pool.query(
`UPDATE sales_tax_periods
SET status = 'external', booked_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
WHERE id = $1 AND status = 'open'
RETURNING *`,
[periodId]
);
if (result.rows.length === 0) {
const existing = await pool.query('SELECT status FROM sales_tax_periods WHERE id = $1', [periodId]);
const currentStatus = existing.rows[0]?.status || 'unknown';
throw new Error(`Cannot mark as paid: period is already ${currentStatus}`);
}
return result.rows[0];
}
// ════════════════════════════════════════════════════════════════════
// Phase 2 Lieferung 1 — Caches und Sync
// ════════════════════════════════════════════════════════════════════
@@ -1700,6 +1718,7 @@ module.exports = {
getTaxPeriods,
upsertTaxPeriod,
createTaxPaymentJE,
markTaxPaidExternal,
normalizeTransactionListReport,
// Phase 2 Lieferung 1 — Sync