feat(settings): rename or re-date an existing räkenskapsår from the fiscal-year list (#2287) (#2337)
* feat(settings): rename or re-date an existing räkenskapsår from the fiscal-year list (#2287) Inställningar > Bokföring > Räkenskapsår offered Lås, Nollställ and Skapa nytt räkenskapsår but no way to change the name or dates of a year that already exists, although PATCH /api/bookkeeping/fiscal-periods/[id] has supported both (name always on an open year, dates only while the year has no posted vouchers). The only surface over that route was the first-year date editor under Företag, so a later or backfilled year saved with the wrong name or dates (Aisen & Adison AB, #2286) could only be repaired in the database. Every open year row now gets a quiet Ändra action opening one dialog (Namn, Startdatum, Slutdatum) that posts only the changed fields to the existing route. Dates are read-only with the route's own reason when the year has posted vouchers (count from the entry-count endpoint); the name is always editable. Locked and closed years get no Ändra, matching the route's refusal and the row's chip. Route refusals are shown inline so the user can correct and retry. The name follows the dates while it still has the shape fiscalYearName() produces (new isDerivedFiscalYearName, the inverse predicate next to the one naming helper): the customer's "Räkenskapsår 2027" corrects itself to "Räkenskapsår 2022/2023" as the dates are fixed, and a hand-written name is never overwritten. Saving invalidates ref:fiscal-periods so every picker updates; the reset dialog's typed confirmation reads the name live from the reset snapshot, so a rename does not break it. No route change. New strings in both messages/sv.json and messages/en.json. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SaJfqNi4VmsG8FMKq99G6 * fix(settings): fiscal-year edit dialog is not dirty on open when the stored name has stray whitespace "Changed" now compares the raw input with the stored name and sends the trimmed value only once the user has edited it; before, a stored name with leading or trailing whitespace enabled Spara on open with a trimmed name in the payload (CodeRabbit on #2337). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
Jakob Wennberg
parent
162de2128a
commit
b2d3a3e273
@@ -2,6 +2,7 @@ import { describe, it, expect } from 'vitest'
|
||||
import {
|
||||
computeSuggestedPeriod,
|
||||
fiscalYearName,
|
||||
isDerivedFiscalYearName,
|
||||
suggestSeedDate,
|
||||
resolveCurrentPeriodId,
|
||||
} from '../suggest-fiscal-period'
|
||||
@@ -27,6 +28,29 @@ describe('fiscalYearName', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('isDerivedFiscalYearName', () => {
|
||||
it('recognises the names fiscalYearName produces', () => {
|
||||
expect(isDerivedFiscalYearName('Räkenskapsår 2025')).toBe(true)
|
||||
expect(isDerivedFiscalYearName('Räkenskapsår 2024/2025')).toBe(true)
|
||||
expect(isDerivedFiscalYearName(fiscalYearName('2022-07-28', '2023-12-31'))).toBe(true)
|
||||
})
|
||||
|
||||
it('recognises a derived name whose years no longer match the dates', () => {
|
||||
// The customer row (#2286, #2287): seeded "Räkenskapsår 2027" on a
|
||||
// 2022/2023 year. The edit dialog must let it follow corrected dates.
|
||||
expect(isDerivedFiscalYearName('Räkenskapsår 2027')).toBe(true)
|
||||
expect(isDerivedFiscalYearName(' Räkenskapsår 2027 ')).toBe(true)
|
||||
})
|
||||
|
||||
it('leaves hand-written names alone', () => {
|
||||
expect(isDerivedFiscalYearName('Första året')).toBe(false)
|
||||
expect(isDerivedFiscalYearName('Räkenskapsår 2025 (förlängt)')).toBe(false)
|
||||
expect(isDerivedFiscalYearName('2025')).toBe(false)
|
||||
expect(isDerivedFiscalYearName('Fiscal year 2025')).toBe(false)
|
||||
expect(isDerivedFiscalYearName('')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('computeSuggestedPeriod', () => {
|
||||
it('suggests a calendar year around the entry date when there are no periods', () => {
|
||||
expect(computeSuggestedPeriod('2025-06-15', [])).toEqual({
|
||||
|
||||
@@ -41,6 +41,17 @@ export function fiscalYearName(start: string, end: string): string {
|
||||
|
||||
const periodName = fiscalYearName
|
||||
|
||||
/**
|
||||
* True when `name` has the shape fiscalYearName() produces ("Räkenskapsår
|
||||
* 2025", "Räkenskapsår 2024/2025"), whatever the years say. The edit dialog
|
||||
* lets such a name follow the dates the user types, so a seed name that never
|
||||
* matched its dates (the "Räkenskapsår 2027" on a 2022/2023 year of #2286) is
|
||||
* corrected together with them; a hand-written name is left alone.
|
||||
*/
|
||||
export function isDerivedFiscalYearName(name: string): boolean {
|
||||
return /^Räkenskapsår \d{4}(\/\d{4})?$/.test(name.trim())
|
||||
}
|
||||
|
||||
/**
|
||||
* Suggest a fiscal period for the create dialog, given the date the user is
|
||||
* trying to book and the company's existing periods. Three cases:
|
||||
|
||||
Reference in New Issue
Block a user