Validation and submission of the personlig skattemelding for an ENK (enkeltpersonforetak) to Skatteetaten / Altinn 3.
Companion to Wenche.Skattemelding (which handles the upersonlig / AS case).
The two share the næringsspesifikasjon and request-envelope generators in
Wenche.SkattemeldingXml; this module supplies the personlig-specific pieces:
- the outer document is the personlig
skattemelding(v13), generated byWenche.SkattemeldingPersonligXml; - the næringsspesifikasjon is generated with
skattepliktig_type: :personlig(ENK virksomhetstype, owner-allocated næringsresultat); - the request envelope uses
skattemelding_dokumenttype: "skattemeldingPersonlig"; - the draft
partsreferanse/ dokumentreferanse are resolved viaWenche.SkdSkattemeldingClient.hent_utkast_referanse_personlig/3.
Unlike the AS flow there is no 22 % corporate-tax beregn: an ENK owner's
personal tax (trinnskatt, trygdeavgift) is assessed by Skatteetaten. The
skattemessig næringsresultat is the figure the caller supplies; the assessed
result comes back from /valider's etter-beregning.
Authentication
Same split as Wenche.Skattemelding: validation uses a Maskinporten +
systemuser token (SkdSkattemeldingClient); submission requires an
ID-porten-derived Altinn token (AltinnClient).
Summary
Functions
Computes the ENK næringsspesifikasjon figures.
Builds the three XML documents for a personlig skattemelding submission:
{skattemelding_personlig, naeringsspesifikasjon, request_envelope}.
Parses Skatteetaten's /valider response, extracting SKD-computed values from
the embedded skattemeldingPersonligEtterBeregning document.
Submits the personlig skattemelding to Skatteetaten via Altinn 3.
Validates the personlig skattemelding against Skatteetaten's /valider API.
Functions
@spec beregn( Wenche.Models.Aarsregnskap.t(), keyword() ) :: %{ selskap: %{navn: String.t(), org_nummer: String.t()}, regnskapsaar: integer(), skattemessig_naeringsresultat: integer() }
Computes the ENK næringsspesifikasjon figures.
Returns the skattemessig næringsresultat (regnskapsmessig resultat adjusted by
any :permanent_forskjeller) plus a balance overview. The assessed personal
tax is not computed here — it comes from Skatteetaten's etter-beregning.
Options
:permanent_forskjeller— optional list (seeWenche.SkattemeldingXml.generer_permanent_forskjell_block/1).
@spec bygg_xmls(Wenche.Models.Aarsregnskap.t(), map(), keyword()) :: {String.t(), String.t(), String.t()}
Builds the three XML documents for a personlig skattemelding submission:
{skattemelding_personlig, naeringsspesifikasjon, request_envelope}.
Accepts the resolved draft reference (%{partsnummer:, skattemelding_id:, naering_id:} — partsnummer carries the partsreferanse) so callers can build
the XML without re-fetching. See valider/3 / send_inn/3 for the
fetch-and-build flow.
Options
:partsidentifikator— the tax subject's identifier (the ENK owner's fnr/d-nummer) used for the envelope<tin>. Defaults to the org number.:kontaktperson,:permanent_forskjeller— forwarded to the næringsspesifikasjon generator.:fremfoerbar_negativ_personinntekt— positive integer kroner of negative beregnet personinntekt carried forward from earlier years (skatteloven § 12-13). Forwarded to the personlig skattemelding generator; when absent or non-positive the personlig shell stays minimal. SeeWenche.SkattemeldingPersonligXml.
Parses Skatteetaten's /valider response, extracting SKD-computed values from
the embedded skattemeldingPersonligEtterBeregning document.
Best-effort: returns a map with the fields that are present, or %{} when the
etter-beregning document is absent. Keys:
:partsreferanse,:inntektsaar:personinntekt— the assessed beregnet personinntekt (samordnetPersoninntekt/personinntekt/beloep/beloepSomHeltall):aarets_fremfoerbare_negativ_personinntekt— the negative beregnet personinntekt SKD computed as carry-forward to next year (skatteloven § 12-13). Persist this and submit it next year as:fremfoerbar_negativ_personinntekt(seebygg_xmls/3). Absent/nilwhen this year's personinntekt is non-negative.
@spec send_inn(Wenche.Models.Aarsregnskap.t(), Wenche.AltinnClient.t(), keyword()) :: {:ok, Wenche.SubmissionResult.t()} | {:error, term()}
Submits the personlig skattemelding to Skatteetaten via Altinn 3.
Mirrors Wenche.Skattemelding.send_inn/4 (same skattemelding app flow);
pass a :skd_client so the draft partsreferanse + dokumentreferanse are
fetched (without it SKD rejects the submission).
Returns {:ok, %Wenche.SubmissionResult{}} (carrying the submitted XML
documents and the Altinn inbox URL) or {:error, reason}.
@spec valider( Wenche.Models.Aarsregnskap.t(), Wenche.SkdSkattemeldingClient.t(), keyword() ) :: {:ok, Wenche.SubmissionResult.t()} | {:error, term()}
Validates the personlig skattemelding against Skatteetaten's /valider API.
Resolves the draft partsreferanse + dokumentreferanse via skd_client
(unless a :partsreferanse is supplied in opts), builds the envelope, and
posts it.
Pass :partsidentifikator (the ENK owner's fnr/d-nummer) so the draft lookup
and /valider are keyed by the tax subject rather than the org number.
Returns {:ok, %Wenche.SubmissionResult{}} (carrying the generated XML
documents and the raw SKD validation response in :response) or
{:error, reason}.