* feat: enhance JournalEntryForm with currency selection and exchange rate fetching - Added currency selection to JournalEntryForm, allowing users to choose from multiple currencies (SEK, EUR, USD, GBP, NOK, DKK). - Implemented fetching of exchange rates from Riksbanken API based on selected currency and entry date. - Updated calculations for foreign amounts and SEK equivalents based on user input and fetched exchange rates. - Improved form handling to reset currency-related fields when switching back to SEK. feat: refactor WelcomeOnboarding to streamline company creation process - Replaced direct company switching with a new server action to create a company from onboarding data. - Added validation for fiscal period during onboarding steps, allowing for mid-month starts for the first fiscal period. - Enhanced error handling and rollback mechanisms to ensure data integrity during company creation. fix: update Step3TaxRegistration to allow flexible first-year start dates - Modified date selection to include day, month, and year for the first-year start date. - Updated validation messages to reflect changes in fiscal year start date handling. test: expand validate-period-duration tests for fiscal period validation - Added tests to validate that mid-month starts are allowed for the first fiscal period. - Ensured that subsequent periods must start on the 1st of the month and enforced maximum duration constraints. feat: implement currency rate API endpoint - Created a new API route to fetch exchange rates for specified currencies, ensuring user authentication. - Validated currency input and handled errors for invalid requests. chore: update database constraints for fiscal periods - Modified database constraints to allow custom start dates for the first fiscal period while enforcing day-1 starts for subsequent periods. * fix: implement computeFiscalPeriod function for onboarding and refactor JournalEntryForm * Fixed date issue * Added migration
69 lines
2.4 KiB
TypeScript
69 lines
2.4 KiB
TypeScript
import { parseDateParts, validatePeriodDuration } from '@/lib/bookkeeping/validate-period-duration'
|
|
import type { CompanySettings } from '@/types'
|
|
|
|
export interface ComputedFiscalPeriod {
|
|
error: string | null
|
|
startStr: string
|
|
endStr: string
|
|
periodName: string
|
|
}
|
|
|
|
/**
|
|
* Derive the first fiscal period for a newly created company from the
|
|
* onboarding wizard's collected settings. Handles both the "first fiscal year"
|
|
* case (custom start/end dates per BFL 3 kap.) and the standard case where the
|
|
* period is bootstrapped from `fiscal_year_start_month`.
|
|
*
|
|
* Returns the computed dates, a Swedish period name, and a validation error
|
|
* (null if valid).
|
|
*/
|
|
export function computeFiscalPeriod(
|
|
s: Partial<CompanySettings> & Record<string, unknown>,
|
|
): ComputedFiscalPeriod {
|
|
const isFirstYear = s.is_first_fiscal_year as boolean | undefined
|
|
const firstYearStart = s.first_year_start as string | undefined
|
|
const firstYearEnd = s.first_year_end as string | undefined
|
|
|
|
let startStr: string
|
|
let endStr: string
|
|
let periodName: string
|
|
|
|
if (isFirstYear && firstYearStart && firstYearEnd) {
|
|
startStr = firstYearStart
|
|
endStr = firstYearEnd
|
|
const startYear = parseDateParts(firstYearStart).year
|
|
const endYear = parseDateParts(firstYearEnd).year
|
|
periodName = startYear === endYear
|
|
? `Första räkenskapsåret ${startYear}`
|
|
: `Första räkenskapsåret ${startYear}/${endYear}`
|
|
} else {
|
|
let startMonth = (s.fiscal_year_start_month as number) || 1
|
|
if (s.entity_type === 'enskild_firma') startMonth = 1
|
|
const currentYear = new Date().getFullYear()
|
|
startStr = `${currentYear}-${String(startMonth).padStart(2, '0')}-01`
|
|
|
|
let endYear: number
|
|
let endMonth: number
|
|
if (startMonth === 1) {
|
|
endYear = currentYear
|
|
endMonth = 12
|
|
} else {
|
|
endYear = currentYear + 1
|
|
endMonth = startMonth - 1
|
|
}
|
|
const lastDay = new Date(endYear, endMonth, 0).getDate()
|
|
endStr = `${endYear}-${String(endMonth).padStart(2, '0')}-${String(lastDay).padStart(2, '0')}`
|
|
|
|
periodName = startMonth === 1
|
|
? `Räkenskapsår ${currentYear}`
|
|
: `Räkenskapsår ${currentYear}/${currentYear + 1}`
|
|
}
|
|
|
|
const validationError = validatePeriodDuration(startStr, endStr, { isFirstPeriod: !!isFirstYear })
|
|
if (validationError) {
|
|
return { error: validationError, startStr: '', endStr: '', periodName: '' }
|
|
}
|
|
|
|
return { error: null, startStr, endStr, periodName }
|
|
}
|