Files
accounted/lib/vat/period-defaults.ts
T
Mattsson 7d56e0ec01 fix(mcp): use canonical VAT deadlines (#1679)
* fix(mcp): use canonical VAT deadlines

* fix(mcp): handle incomplete VAT settings

* fix(mcp): block unknown VAT deadlines

* fix(mcp): tighten VAT tool description

* fix(mcp): fail closed on missing entity type

* ci: retry timed-out preview

* fix(vat): scope annual filing method requirement
2026-08-18 17:22:52 +02:00

64 lines
2.5 KiB
TypeScript

/**
* Default period selection for the VAT declaration view.
*
* A momsdeklaration can only ever be filed for a period that has ENDED, so
* the view defaults to the most recently ended month/quarter instead of the
* current one (which used to force a step-back click on every filing visit,
* and invited reading rutor for a period that cannot be filed yet).
*
* Monthly filers below the 40 MSEK threshold declare month M on the 12th of
* M+2 (17th when that deadline lands in January or August), mirroring
* lib/tax/deadline-config.ts. Until that deadline has passed, the declaration
* the user actually has open is M-2, not M-1, so the default tracks the
* deadline. Over-40M companies declare M on the 26th of M+1, which makes the
* most recently ended month the due one year-round.
*/
import { getVatDeadlineForPeriod } from '@/lib/tax/deadline-config'
import { adjustDeadlineToNextBankingDay } from '@/lib/tax/swedish-holidays'
export interface VatPeriodDefault {
year: number
/** 1-12 for monthly, 1-4 for quarterly. */
period: number
}
/** Return the monthly VAT period a fixed number of months before a month. */
function previousMonth(year: number, month: number, monthsBack: number): VatPeriodDefault {
const date = new Date(year, month - 1 - monthsBack, 1)
return { year: date.getFullYear(), period: date.getMonth() + 1 }
}
/** Select the latest ended VAT period that is currently relevant for filing. */
export function mostRecentEndedVatPeriod(
periodType: 'monthly' | 'quarterly',
today: Date = new Date(),
opts: { over40m?: boolean } = {},
): VatPeriodDefault {
const year = today.getFullYear()
const month = today.getMonth() + 1
if (periodType === 'monthly') {
const mostRecentEnded = previousMonth(year, month, 1)
if (opts.over40m) return mostRecentEnded
const periodDueThisMonth = previousMonth(year, month, 2)
const deadline = getVatDeadlineForPeriod(
'monthly',
periodDueThisMonth.year,
periodDueThisMonth.period,
{ vat_taxable_base_over_40m: false },
)
const adjustedDeadline = deadline
? adjustDeadlineToNextBankingDay(new Date(deadline.year, deadline.month, deadline.day))
: null
const currentDate = new Date(year, month - 1, today.getDate())
return adjustedDeadline && currentDate <= adjustedDeadline
? periodDueThisMonth
: mostRecentEnded
}
const quarter = Math.ceil(month / 3)
return quarter === 1 ? { year: year - 1, period: 4 } : { year, period: quarter - 1 }
}