Files
accounted/lib/bookkeeping/__tests__/validate-period-duration.test.ts
T
Mattsson aa405b9a74 Fix/company creation bug (#212)
* 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
2026-04-10 11:02:28 +02:00

111 lines
3.8 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import { validatePeriodDuration, monthsBetween } from '../validate-period-duration'
describe('monthsBetween', () => {
it('returns 12 for a standard calendar year', () => {
expect(monthsBetween('2025-01-01', '2025-12-31')).toBe(12)
})
it('returns 18 for an 18-month period', () => {
expect(monthsBetween('2025-07-01', '2026-12-31')).toBe(18)
})
it('returns 1 for a single month', () => {
expect(monthsBetween('2025-03-01', '2025-03-31')).toBe(1)
})
it('returns 3 for a quarter', () => {
expect(monthsBetween('2025-10-01', '2025-12-31')).toBe(3)
})
})
describe('validatePeriodDuration', () => {
it('returns null for a valid 12-month period', () => {
expect(validatePeriodDuration('2025-01-01', '2025-12-31')).toBeNull()
})
it('returns null for exactly 18 months (max allowed)', () => {
expect(validatePeriodDuration('2025-07-01', '2026-12-31')).toBeNull()
})
it('returns null for a short first year (1 month)', () => {
expect(validatePeriodDuration('2025-12-01', '2025-12-31')).toBeNull()
})
it('returns null for a short first year (3 months)', () => {
expect(validatePeriodDuration('2025-10-01', '2025-12-31')).toBeNull()
})
it('returns error for 19 months (exceeds max)', () => {
const result = validatePeriodDuration('2025-06-01', '2026-12-31')
expect(result).toContain('19 months')
expect(result).toContain('18 months')
})
it('returns error when end is before start', () => {
expect(validatePeriodDuration('2025-06-01', '2025-01-31')).toBe(
'Period end must be after period start'
)
})
it('returns error when start is not 1st of month (default)', () => {
expect(validatePeriodDuration('2025-01-15', '2025-12-31')).toBe(
'Period start must be the 1st of a month'
)
})
it('returns error when start is not 1st of month (isFirstPeriod: false)', () => {
expect(validatePeriodDuration('2025-03-25', '2025-12-31', { isFirstPeriod: false })).toBe(
'Period start must be the 1st of a month'
)
})
it('allows mid-month start for first fiscal period', () => {
expect(validatePeriodDuration('2025-03-25', '2025-12-31', { isFirstPeriod: true })).toBeNull()
})
it('allows mid-month start for first period (October)', () => {
expect(validatePeriodDuration('2025-10-15', '2025-12-31', { isFirstPeriod: true })).toBeNull()
})
it('still allows day-1 start for first period', () => {
expect(validatePeriodDuration('2025-10-01', '2025-12-31', { isFirstPeriod: true })).toBeNull()
})
it('enforces end-of-month even for first period', () => {
expect(validatePeriodDuration('2025-03-25', '2025-12-15', { isFirstPeriod: true })).toBe(
'Period end must be the last day of a month'
)
})
it('enforces 18-month max for first period with mid-month start', () => {
const result = validatePeriodDuration('2025-01-15', '2026-12-31', { isFirstPeriod: true })
expect(result).toContain('months')
expect(result).toContain('18 months')
})
it('returns error when end is not last day of month', () => {
expect(validatePeriodDuration('2025-01-01', '2025-12-15')).toBe(
'Period end must be the last day of a month'
)
})
it('handles February end correctly (non-leap year)', () => {
expect(validatePeriodDuration('2025-01-01', '2025-02-28')).toBeNull()
})
it('handles February end correctly (leap year)', () => {
expect(validatePeriodDuration('2024-01-01', '2024-02-29')).toBeNull()
})
it('rejects Feb 28 in a leap year (not last day)', () => {
expect(validatePeriodDuration('2024-01-01', '2024-02-28')).toBe(
'Period end must be the last day of a month'
)
})
it('returns null for a broken fiscal year (May-Apr)', () => {
expect(validatePeriodDuration('2025-05-01', '2026-04-30')).toBeNull()
})
})