Årsavslutning med eksisterende bokføringer

Denne siden beskriver hvordan årsavslutningskalkulatoren håndterer en saldobalanse som allerede inneholder årsavslutningsposteringer (skatt, utsatt skatt, disponering).

Denne beskrivelsen reflekterer den target-drevne kalkulator-kontrakten (YecVersion.V1_TargetDrivenCalc). Eldre årsregnskap kan være beregnet under den delta-drevne V0-modellen. Se YEC-versjonering for detaljer.

Utgangspunkt

Finsta støtter både tilfellet der saldobalansen ikke inneholder noen årsavslutningsposter — der Finsta beregner alt fra bunnen av — og tilfellet der det allerede finnes eksisterende bokføringer.

I praksis kan regnskapsfører allerede ha bokført deler av årsavslutningen (for eksempel skatt og disponering) før saldobalansen importeres til Finsta. I noen tilfeller er hele årsavslutningen allerede bokført.

Problemstilling

Når saldobalansen inneholder eksisterende årsavslutningsposter på kontoer i 83xx (skattekostnad) og 89xx (disponering), må Finsta:

  1. Finne hva som allerede er bokført

  2. Beregne korrekte verdier fra en ren TB (uten YEC-effekter)

  3. Postere kun differansen (delta) mellom korrekt og eksisterende verdi

  4. Sikre at egenkapitalavstemmingen (EK170) stemmer

Sirkulær avhengighet

Årsavslutningsberegningen har en sirkulær avhengighet: eksisterende 83xx-poster i saldobalansen påvirker næringsspesifikasjonen (beregnet næringsinntekt, permanente forskjeller), som endrer beregnet skatt og utsatt skatt, som gir feil delta.

Eksempel

Hvis regnskapsfører har bokført 8300 = 120 000 (skatt) og 8322 = -59 400 (utsatt skatt):

  • Post 0620 (permanente forskjeller, tillegg) leser fra 8300-8399 → inflatert med 120 000

  • Post 9200 (årsresultat) inkluderer 83xx via 9150 → inflatert

  • Post 0920 (grunnlag beregnet næringsinntekt) leser fra 9200 → inflatert

  • Beregnet næringsinntekt blir feil → skatt blir feil → delta blir feil

Løsning: To saldobalanser

Nøkkelprinsippet er å starte med rene data i stedet for å forsøke å kompensere for kontaminerte data.

Beregningen leser post 9100 (resultat før skattekostnad), som aldri inneholder 83xx/89xx-kontoer. Skatt og utsatt skatt trekkes fra eksplisitt. Samme prinsipp gjelder for den rene saldobalansen: i stedet for å fjerne YEC-effekter fra en kontaminert TB, bygges en TB som representerer tilstanden før noen årsavslutning ble gjort.

Beregningen starter med å bygge to versjoner av saldobalansen:

TB 1: Ren saldobalanse (uten noe YEC)

Fjerner alle spor av årsavslutning — både regnskapsførers manuelle bokføringer og Finstas egne transaksjoner. Denne TB-en representerer tilstanden som om ingen årsavslutning har blitt gjort. Vi bruker den til å beregne korrekte mål-verdier for skatt, utsatt skatt, utbytte og disponering.

For YEC-relaterte kontoer nullstilles temporaryClosingBalance ulikt avhengig av kontotype:

  • Resultatkontoer (83xx, 89xx): temporaryClosingBalance settes til null (nulles ut)

  • Balansekontoer (2500, 1070, 2120, 2050, 2080): temporaryClosingBalance tilbakestilles til previousClosingBalance

Ren BI aktiveres kun når 83xx-kontoer har ikke-null UB. 89xx alene utløser ikke ren BI. Differansene hentes fra den reelle BI-en (ikke rekalkulert).

Kontoer som påvirkes: alle kontoer definert i YearEndClosingSpec (resultatkontoer i 83xx/89xx OG balansekontoer som 2500, 1070, 2120, 2050, 2080). Transaksjoner med opphav YearEndClosing ekskluderes også.

TB 2: Saldobalanse uten Finstas YEC

Den reelle saldobalansen der kun Finstas egne YEC-transaksjoner er fjernet (via ExistingAccounts.withoutYec()). Denne beholder regnskapsførers manuelle bokføringer. Vi bruker den til å finne hva som allerede er registrert.

Beregning

Fra disse to TB-ene utledes:

Mål-verdier

Beregnet fra TB 1 (ren næringsspesifikasjon → full YEC-beregning)

Allerede registrert

Lest fra TB 2 (eksisterende saldoer på YEC-kontoer)

Delta

Mål minus allerede registrert

Transaksjoner

Opprettes kun for differanser som ikke er null

Fra TB 1 beregnes en ren næringsspesifikasjon:

Kontoer som ekskluderes fra ren TB

Kontointervall Beskrivelse Kilde

8300-8399

Skattekostnadskontoer (betalbar skatt, utsatt skatt)

TaxSpec, DeferredTaxSpec

8900-8999

Disponeringskontoer

AllocationSpec

2500

Betalbar skatt (balanseside)

TaxSpec.taxPayable

1070, 2120

Utsatt skattefordel / -forpliktelse

DeferredTaxSpec.advantage / obligation

2050, 2080

Annen egenkapital / udekket tap

AllocationSpec.otherEquity / uncoveredLoss

Tilleggsposteringer som ikke er fra YEC (brukerens egne korreksjoner, anleggsregister-transaksjoner osv.) inkluderes i den rene TB-en.

Årsresultat rekonstruert mot post 9150

NetProfitOrLossCalculator rekonstruerer årsresultat (post 9150) slik at verdien som mates til AllocationCalculator matcher det resultatregnskapet faktisk viser — også når kunden har bokført skattekostnad på andre kontoer i tax.cost-rangen enn standardkontoen (typisk 8309, 8335).

Utgangspunktet er post 9100 (resultat før skattekostnad), som er uavhengig av alle 83xx- og 89xx-kontoer. Kompensert årsresultat beregnes som:

kompensertÅrsresultat = resultatFørSkatt - skatt - unaccountedTaxCostExtra - actualDeferredTax()

actualDeferredTax() respekterer «bokfør utsatt skattefordel»-togglen. Når fordelen ikke bokføres, brukes nbo-verdien (utsatt skatt uten fordel) i stedet for full utsatt skatt.

unaccountedTaxCostExtra — bro mellom YEC og post 9150

Posts-spec sin formel for 9150 trekker fra hele tax.cost-rangen (SUM(8300-range)). YECs tax-felt dekker derimot kun standardkontoen (8300) pluss YECTBOA-valgte kontoer — saldoer som inngår i alreadyRegisteredTax. Saldoer på øvrige kontoer i rangen (8309, 8335, …​) bidrar dermed til 9150 i resultatregnskapet, men er usynlige for tax.

unaccountedTaxCostExtra er nøyaktig dette gapet: summen av finalClosingBalance på kontoer i tax.cost-postens range, eksklusive standardkontoen og YECTBOA-valgte kontoer (og fratrukket eventuelle YEC-genererte transaksjoner på disse kontoene, for re-sync-sikkerhet). Ved å trekke det fra eksplisitt får compensatedNetProfitOrLoss() samme verdi som post 9150 i resultatregnskapet — by construction — uten å måtte kjøre posts-spec-formelvandreren på en strippet TB.

Invariant låst i kalkulator-test: npol.compensatedNetProfitOrLoss == bi.getResult().findPostAmount("9150") for enhver TB-form.

Tidligere matchet ikke dette: kunder med saldo på 8309/8335 fikk disponeringstransaksjoner som var nøyaktig overrepresentert med den ukjente bidraget, og «Sum overføringer = årsresultat»-sjekken i årsregnskapet falt ut.

Hvis posts-spec endrer 9150-formelen eller YEC tar eierskap over nye poster (f.eks. 8323/8324) må denne forenklingen byttes ut med full formel-walk over SumPostSpec.parts() — dokumentert i javadoc på NetProfitOrLossCalculator.

Beregningen bruker ikke den gamle kompensasjonsmekanismen (previousYecContribution / currentYecContribution).

Deteksjon av eksisterende YEC-verdier

Ved import oppdages alle kontoer fra YEC-spesifikasjonen som har saldo. Disse vises til bruker slik at de kan se hva som allerede er bokført.

Komponent Resultatkontoer Balansekontoer

Skatt

8300 (betalbar skatt)

2500 (betalbar skatt, ikke fastsatt)

Utsatt skatt

8321 (økt forpliktelse), 8322 (økt fordel)

1070 (utsatt skattefordel), 2120 (utsatt skatteforpliktelse)

Utbytte

8920-8923 (utbytte)

Disponering

8960 (overf. annen EK), 8961 (fra annen EK), 8969 (dekning udekket tap), 8990 (økt udekket tap)

2050 (annen egenkapital), 2080 (udekket tap)

Alle disse kontonumrene er definert i YearEndClosingSpec og kan variere mellom spec-versjoner.

Delta-beregning per komponent

Skatt

TaxCalculator beregner skatt fra den rene beregnet næringsinntekt. Den oppdager eksisterende skatt på debet-kontoen (typisk 8300) via ExistingAccounts.withoutYec() og posterer kun differansen:

delta = beregnetSkatt - eksisterendePå8300

Bruker kan overstyre den oppdagede verdien via input-post YECT003.

Den oppdagede verdien lagres i TaxBasis.alreadyRegisteredTax.

Utsatt skatt

DeferredTaxCalculator beregner full utsatt skatt fra grunnlaget (endring i midlertidige forskjeller + fremførbart underskudd). Den beregner hva MÅL-saldoene på 1070 (fordel) og 2120 (forpliktelse) skal være, og beregner delta:

deltaFordel = målFordel - eksisterendeFordel
deltaForpliktelse = målForpliktelse - eksisterendeForpliktelse

Transaksjoner opprettes kun for differanser som ikke er null.

deferredTax-verdien på API-et beregnes fra grunnlaget (full verdi) og brukes til visning/rapportering. For årsresultatet brukes deferredTaxPnlEffect (sum av 8321/8322-linjene fra delta-transaksjonene) — det er beløpet som faktisk påvirker resultatregnskapet. Disse to verdiene er like når det ikke finnes eksisterende IB på 1070/2120, men forskjellige når det gjør det.

Eksisterende verdier på 1070 og 2120 oppdages ved import og vises til bruker, på samme måte som 83xx-kontoene. Verdiene lagres i DeferredTaxBasis.existingAdvantage og DeferredTaxBasis.existingObligation.

Fra 2025.3 kan brukeren også opt-in ekstra kontoer i 1071-1079 (YECDTAA) og 2121-2129 (YECDTOA). Valgte saldoer leses rett fra saldobalansen og telles inn i samme existingAdvantage / existingObligation; YEC posterer fortsatt delta på 1070 / 2120.

removeDeferredTaxAdvantage (nbo)

Når «bokfør utsatt skattefordel» er avslått, reverseres eksisterende carry-over på 1070 via ExistingAccounts.withoutYec. Eventuell fordel som allerede ligger på 1070 fra regnskapsførers bokføring fjernes slik at balanseposten nulles ut.

Utbytte

DividendCalculator leser eksisterende utbytteposteringer fra saldobalansen via ExistingAccounts.withoutYec() på kontoene spesifisert i DividendSpec (typisk 8920-8923). Disse verdiene brukes til å beregne tilgjengelig utbytte for neste år og eventuelt ekstra avsatt utbytte.

Utbyttekalkulatoren oppdager eksisterende verdier, men genererer kun en ekstra-utbytte-transaksjon dersom bruker har lagt inn ekstra avsatt utbytte utover det som allerede er bokført.

Disponering

AllocationCalculator beregner total disponering fra kompensertÅrsresultat - konsernbidrag - utbytte. Den summerer eksisterende disponeringer på tvers av ALLE disponeringskontoer (8960, 8961, 8969, 8990), uavhengig av hvilken gren som opprinnelig posterte dem:

totalEksisterende = eksisterende8960 + eksisterende8961 + eksisterende8969 + eksisterende8990
delta = beregnetDisponering - totalEksisterende

Hvis delta er null, genereres ingen transaksjoner. Hvis ikke null, bestemmer standard forgreningslogikk (overskudd/underskudd, udekket tap, annen EK) hvor deltaen posteres.

Den oppdagede totalen lagres i AllocationBasis.alreadyRegisteredAllocation.

Advarsler for ukjente kontoer

YearEndClosingRemarkAssembler skanner saldobalansen etter kontoer med saldo i intervallene 8300-8399 og 8900-8999 som ikke er tilordnet en kjent YEC-rolle. En advarsel (YearEndClosingUnknownAccountInRange, kode 24013) genereres for hver.

Brukervalg av ekstra kontoer (BookedOnly opt-in)

Hver YEC-rolle er definert som en mengde av kontoer (AccountNos) i CSV-spesifikasjonen, ikke en enkelt konto. Standardkontoen for bokføring styres av eksplisitt angivelse (→@<konto>) eller — i fravær — første konto i mengden.

Fra og med 2025.2 kan en YEC-rolle peke på en separat choose-account-post (med BookedOnly-trait, BKO) i posts-spec. Den eksterne posten eier sitt eget område og sin egen postNo for å persistere brukerens valg. Brukeren ser kun valg-UIet i grensesnittet når trial-balansen inneholder kontoer med saldo i området.

Syntaks i yec-spec: <standard-konto>;<post-id>→@<standard-konto>.

Versjon Rolle Verdi Bakgrunn

2025.2

tax.cost

8300;YECTBOA→@8300

Kunder bruker andre kontoer i post 8300-rangen (8301-8319, 8330-8399) som alternative kontoer for skattekostnad. Brukeren krysser av kontoer med saldo i YECTBOA-posten; valgte saldoer telles som allerede registrert skattekostnad, ny tx posteres fortsatt på 8300.

2025.3

deferred-tax.advantage

1070;YECDTAA→@1070

Kunder bokfører utsatt skattefordel på 1071-1079 i stedet for 1070. Valgte saldoer telles inn i existingAdvantage; YEC posterer fortsatt delta på 1070.

2025.3

deferred-tax.obligation

2120;YECDTOA→@2120

Som over, for utsatt skatteforpliktelse på 2121-21292120.

Eksisterende årsoppgjør på lavere inkrement beholder den smale mengden (kun standardkontoen) og påvirkes ikke. Saldo på ikke-valgte kontoer i opt-in-området fortsetter å utløse YearEndClosingUnknownAccountInRange (kode 24013) — varselet undertrykkes kun for brukerens valg.

Reversering ved «ikke bokfør» (advantage)

Når brukeren har valgt ikke å bokføre utsatt skattefordel (register=No) og samtidig har valgt ekstra kontoer via YECDTAA med saldo, blir YEC-transaksjonen flerlinjet: én reverseringslinje per ikke-null 107x-konto pluss 1070 selv, med samlet motpost på resultatkontoen. Dette sikrer at ingen utsatt skattefordel står bokført noe sted — i tråd med valget om ikke å balanseføre. Saldoer på 107x-kontoer flyttes aldri til 1070 automatisk; konsolidering må gjøres manuelt.

Egenkapitalavstemming (EK170)

Egenkapitalavstemmingen (EK170 = EK150 - EK160) stemmer når:

  • Den rene næringsspesifikasjonen gir samme beregnet næringsinntekt uavhengig av eksisterende poster → samme skatt

  • Utsatt skatt bruker full verdi fra grunnlaget → korrekt årsresultat

  • Disponering bruker total-delta → håndterer kryssende grener i eksisterende poster

  • Etter at YEC-transaksjoner er flettet inn og næringsspesifikasjonen er rekalkulert, reflekterer begge sider av avstemmingen de samme endringene

ExistingAccounts.withoutYec()

Denne hjelperen er grunnlaget for all delta-deteksjon. Den leser kontosaldoer og trekker fra beløp fra transaksjoner med opphav i Finstas egen YEC-beregning (TransactionOriginType.YearEndClosing). Dermed:

  • Ved fersk import: returnerer regnskapsførers manuelle verdier (ingen Finsta-txer å ekskludere)

  • Ved rekjøring: fjerner Finstas forrige beregning, returnerer de opprinnelige manuelle verdiene

  • Resultat: idempotent beregning uavhengig av hvor mange ganger YEC kjøres

Beregningsflyt

flowchart TD
    TB["Importert saldobalanse<br>(med evt. eksisterende YEC)"]

    TB1["TB 1: Ren TB<br>(ingen YEC-kontoer)"]
    TB2["TB 2: Uten Finstas YEC<br>(beholder manuelle bokføringer)"]

    CleanBI["Ren næringsspesifikasjon<br>(Resultat + Forskjeller + EBI)"]

    Tax["1. TaxCalculator<br>→ mål-skatt"]
    DT["2. DeferredTaxCalculator<br>→ mål-utsatt skatt"]
    NPOL["3. NetProfitOrLossCalculator<br>→ kompensert årsresultat"]
    Div["4. DividendCalculator"]
    Alloc["5. AllocationCalculator<br>→ mål-disponering"]

    DeltaTax["Delta skatt<br>= mål - eksisterende på 8300"]
    DeltaDT["Delta utsatt skatt<br>= mål - eksisterende på 1070/2120"]
    DeltaAlloc["Delta disponering<br>= mål - eksisterende på 89xx"]

    Result["YearEndClosingEntity<br>+ delta-transaksjoner<br>+ merknader"]

    TB --> TB1
    TB --> TB2

    TB1 --> CleanBI --> Tax --> DT --> NPOL --> Div --> Alloc

    TB2 --> DeltaTax
    TB2 --> DeltaDT
    TB2 --> DeltaAlloc

    Tax --> DeltaTax --> Result
    DT --> DeltaDT --> Result
    Alloc --> DeltaAlloc --> Result