diff --git a/src/components/navigasjonsknapper/Navigasjonsknapper.tsx b/src/components/navigasjonsknapper/Navigasjonsknapper.tsx
index 6e795dd47..76f063bab 100644
--- a/src/components/navigasjonsknapper/Navigasjonsknapper.tsx
+++ b/src/components/navigasjonsknapper/Navigasjonsknapper.tsx
@@ -51,7 +51,7 @@ const Navigasjonsknapper = (props: {
variant="secondary"
onClick={() => {
setKnappTrykket('avslutt');
- props.fortsettSenere!.onClick!();
+ props.fortsettSenere?.onClick?.();
}}
type="button"
loading={props.fortsettSenere?.loading ?? (knappTrykket === 'avslutt' && props.neste?.loading)}
diff --git a/src/components/oppsummering/kravgrunnlag/OppsummeringAvKravgrunnlag-nb.ts b/src/components/oppsummering/kravgrunnlag/OppsummeringAvKravgrunnlag-nb.ts
new file mode 100644
index 000000000..4ce68f5d5
--- /dev/null
+++ b/src/components/oppsummering/kravgrunnlag/OppsummeringAvKravgrunnlag-nb.ts
@@ -0,0 +1,18 @@
+export default {
+ 'kravgrunnlag.tittel': 'Oppsummering av kravgrunnlag',
+ 'kravgrunnlag.id': 'OS kravgrunnlags-id',
+ 'kravgrunnlag.vedtakId': 'OS vedtak-id',
+ 'kravgrunnlag.status': 'Status',
+ 'kravgrunnlag.kontrollfelt': 'Kontrollfelt',
+
+ 'kravgrunnlag.grunnlagsperiode.tittel': 'Grunnlagsperioder',
+ 'kravgrunnlag.grunnlagsperiode.periode': 'Periode',
+ 'kravgrunnlag.grunnlagsperiode.beløpSkattMnd': 'Skatt per måned',
+ 'kravgrunnlag.grunnlagsperiode.beløp.kode': 'Kode',
+ 'kravgrunnlag.grunnlagsperiode.beløp.type': 'Type',
+ 'kravgrunnlag.grunnlagsperiode.beløp.skatteProsent': 'Skatteprosent',
+ 'kravgrunnlag.grunnlagsperiode.beløp.beløpTidligereUtbetaling': 'Tidligere utbetalt',
+ 'kravgrunnlag.grunnlagsperiode.beløp.beløpNyUtbetaling': 'Ny utbetaling',
+ 'kravgrunnlag.grunnlagsperiode.beløp.beløpSkalTilbakekreves': 'Skal tilbakekreves',
+ 'kravgrunnlag.grunnlagsperiode.beløp.beløpSkalIkkeTilbakekreves': 'Skal ikke tilbakekreves',
+};
diff --git a/src/components/oppsummering/kravgrunnlag/OppsummeringAvKravgrunnlag.module.less b/src/components/oppsummering/kravgrunnlag/OppsummeringAvKravgrunnlag.module.less
new file mode 100644
index 000000000..d4975a3a3
--- /dev/null
+++ b/src/components/oppsummering/kravgrunnlag/OppsummeringAvKravgrunnlag.module.less
@@ -0,0 +1,19 @@
+@import '~/src/styles/variables.less';
+
+.kravgrunnlagOppsummeringContainer {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: @spacing-s;
+ margin-bottom: @spacing;
+}
+
+.grunnlagsbeløperContainer {
+ list-style-type: none;
+ margin-bottom: @spacing-s;
+
+ .grunnlagsbeløpContainer {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ margin-bottom: @spacing-xxs;
+ }
+}
diff --git a/src/components/oppsummering/kravgrunnlag/OppsummeringAvKravgrunnlag.tsx b/src/components/oppsummering/kravgrunnlag/OppsummeringAvKravgrunnlag.tsx
new file mode 100644
index 000000000..f9495a5a5
--- /dev/null
+++ b/src/components/oppsummering/kravgrunnlag/OppsummeringAvKravgrunnlag.tsx
@@ -0,0 +1,149 @@
+import { Heading, Accordion } from '@navikt/ds-react';
+import AccordionItem from '@navikt/ds-react/esm/accordion/AccordionItem';
+import React from 'react';
+
+import Oppsummeringspanel, {
+ Oppsummeringsikon,
+ Oppsummeringsfarge,
+} from '~src/components/oppsummeringspanel/Oppsummeringspanel';
+import { useI18n } from '~src/lib/i18n';
+import { Kravgrunnlag, Grunnlagsperiode } from '~src/types/Kravgrunnlag';
+import { formatMonthYear } from '~src/utils/date/dateUtils';
+
+import { OppsummeringPar } from '../oppsummeringpar/OppsummeringPar';
+
+import messages from './OppsummeringAvKravgrunnlag-nb';
+import styles from './OppsummeringAvKravgrunnlag.module.less';
+
+const OppsummeringAvKravgrunnlag = (props: {
+ kravgrunnlag: Kravgrunnlag;
+ visSomEnkeltPanel?: boolean;
+ bareOppsummerMetaInfo?: boolean;
+}) => {
+ const { formatMessage } = useI18n({ messages });
+
+ if (props.bareOppsummerMetaInfo) {
+ return
;
+ } else if (props.visSomEnkeltPanel) {
+ return (
+
+
+
+
+ );
+ } else {
+ return (
+
+
+
+
+ );
+ }
+};
+
+const OppsummeringAvKravgrunnlagMetaInfo = (props: { kravgrunnlag: Kravgrunnlag }) => {
+ const { formatMessage } = useI18n({ messages });
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+const OppsummeringAvGrunnlagsPerioder = (props: { grunnlagsperiode: Grunnlagsperiode[] }) => {
+ const { formatMessage } = useI18n({ messages });
+ return (
+
+
{formatMessage('kravgrunnlag.grunnlagsperiode.tittel')}
+
+
+ {props.grunnlagsperiode.map((periode) => (
+
+
+ {`${formatMonthYear(periode.periode.fraOgMed)} - ${formatMonthYear(
+ periode.periode.tilOgMed,
+ )}`}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+
+ );
+};
+
+export default OppsummeringAvKravgrunnlag;
diff --git a/src/components/tabell/SuTabellUtils.ts b/src/components/tabell/SuTabellUtils.ts
index f474b2f14..7e4c6f795 100644
--- a/src/components/tabell/SuTabellUtils.ts
+++ b/src/components/tabell/SuTabellUtils.ts
@@ -1,5 +1,6 @@
import { Nullable } from '~src/lib/types';
import { Klage } from '~src/types/Klage';
+import { ManuellTilbakekrevingsbehandling } from '~src/types/ManuellTilbakekrevingsbehandling';
import { Regulering } from '~src/types/Regulering';
import { Revurdering } from '~src/types/Revurdering';
import { Søknad } from '~src/types/Søknad';
@@ -20,9 +21,16 @@ export const isRegulering = (b: TabellBehandling): b is Regulering => 'regulerin
export const isSøknadMedEllerUtenBehandling = (b: TabellBehandling): b is SøknadMedEllerUtenBehandling => 'søknad' in b;
export const isRevurdering = (b: TabellBehandling): b is Revurdering => 'årsak' in b;
export const isKlage = (b: TabellBehandling): b is Klage => 'klagevedtakshistorikk' in b;
+export const isManuellTilbakekrevingsbehandling = (b: TabellBehandling): b is ManuellTilbakekrevingsbehandling =>
+ 'kravgrunnlag' in b;
export type SøknadMedEllerUtenBehandling = { søknad: Søknad; søknadsbehandling?: Søknadsbehandling };
-export type TabellBehandling = SøknadMedEllerUtenBehandling | Revurdering | Klage | Regulering;
+export type TabellBehandling =
+ | SøknadMedEllerUtenBehandling
+ | Revurdering
+ | Klage
+ | Regulering
+ | ManuellTilbakekrevingsbehandling;
export type TabellBehandlinger = TabellBehandling[];
export type DatacellStatus =
@@ -36,12 +44,13 @@ export type DatacellStatus =
| 'Underkjent'
| 'Iverksatt'
| 'Avsluttet'
- | 'Oversendt';
+ | 'Oversendt'
+ | 'Vurdert';
export type DataCellResultat = '-' | 'Avslag' | 'Innvilget' | 'Avvist' | 'Til vurdering' | 'Opphør' | 'Endring';
export interface DataCellInfo {
- type: 'søknad' | 'regulering' | 'revurdering' | 'klage' | 'stans' | 'gjenopptak';
+ type: 'søknad' | 'regulering' | 'revurdering' | 'klage' | 'stans' | 'gjenopptak' | 'tilbakekreving';
status: DatacellStatus;
resultat: DataCellResultat;
periode: string;
@@ -101,5 +110,31 @@ export const getDataCellInfo = (b: TabellBehandling): DataCellInfo => {
avsluttetTidspunkt: b.avsluttetTidspunkt,
};
}
+
+ if (isManuellTilbakekrevingsbehandling(b)) {
+ return {
+ type: 'tilbakekreving',
+ status: (() => {
+ switch (b.status) {
+ case 'OPPRETTET':
+ return 'Opprettet';
+ case 'VURDERT_UTEN_BREV':
+ return 'Vurdert';
+ case 'VURDERT_MED_BREV':
+ return 'Vurdert';
+ case 'TIL_ATTESTERING':
+ return 'Til attestering';
+ case 'IVERKSATT':
+ return 'Iverksatt';
+ }
+ throw new Error('Ukjent status for tilbakekreving');
+ })(),
+ resultat: '-',
+ periode: '-',
+ mottattOpprettetTidspunkt: b.opprettet,
+ avsluttetTidspunkt: null,
+ };
+ }
+
throw new Error('Feil ved mapping av behandling til dataCellInfo');
};
diff --git a/src/features/TilbakekrevingActions.ts b/src/features/TilbakekrevingActions.ts
new file mode 100644
index 000000000..9e4391139
--- /dev/null
+++ b/src/features/TilbakekrevingActions.ts
@@ -0,0 +1,62 @@
+import { createAsyncThunk } from '@reduxjs/toolkit';
+
+import { ApiError } from '~src/api/apiClient';
+import * as tilbakekrevingsApi from '~src/api/tilbakekrevingApi';
+import {
+ BrevtekstTilbakekrevingsbehandlingRequest,
+ ForhåndsvarsleTilbakekrevingRequest,
+ ManuellTilbakekrevingsbehandling,
+ OpprettNyTilbakekrevingsbehandlingRequest,
+ VurderTilbakekrevingsbehandlingRequest,
+} from '~src/types/ManuellTilbakekrevingsbehandling';
+
+export const opprettNyTilbakekrevingsbehandling = createAsyncThunk<
+ ManuellTilbakekrevingsbehandling,
+ OpprettNyTilbakekrevingsbehandlingRequest,
+ { rejectValue: ApiError }
+>('tilbakekreving/opprett', async ({ sakId, saksversjon }, thunkApi) => {
+ const res = await tilbakekrevingsApi.opprettNyTilbakekrevingsbehandling({
+ sakId,
+ saksversjon,
+ });
+ if (res.status === 'ok') {
+ return res.data;
+ }
+ return thunkApi.rejectWithValue(res.error);
+});
+
+export const vurderTilbakekrevingsbehandling = createAsyncThunk<
+ ManuellTilbakekrevingsbehandling,
+ VurderTilbakekrevingsbehandlingRequest,
+ { rejectValue: ApiError }
+>('tilbakekreving/vurder', async (args, thunkApi) => {
+ const res = await tilbakekrevingsApi.vurderTilbakekrevingsbehandling(args);
+ if (res.status === 'ok') {
+ return res.data;
+ }
+ return thunkApi.rejectWithValue(res.error);
+});
+
+export const sendForhåndsvarsel = createAsyncThunk<
+ ManuellTilbakekrevingsbehandling,
+ ForhåndsvarsleTilbakekrevingRequest,
+ { rejectValue: ApiError }
+>('tilbakekreving/forhåndsvarsel', async (args, thunkApi) => {
+ const res = await tilbakekrevingsApi.sendForhåndsvarsel(args);
+ if (res.status === 'ok') {
+ return res.data;
+ }
+ return thunkApi.rejectWithValue(res.error);
+});
+
+export const brevtekstTilbakekrevingsbehandling = createAsyncThunk<
+ ManuellTilbakekrevingsbehandling,
+ BrevtekstTilbakekrevingsbehandlingRequest,
+ { rejectValue: ApiError }
+>('tilbakekreving/brev', async (args, thunkApi) => {
+ const res = await tilbakekrevingsApi.brevtekstTilbakekrevingsbehandling(args);
+ if (res.status === 'ok') {
+ return res.data;
+ }
+ return thunkApi.rejectWithValue(res.error);
+});
diff --git a/src/features/saksoversikt/sak.slice.ts b/src/features/saksoversikt/sak.slice.ts
index d6141c7a0..8baeb6bdf 100644
--- a/src/features/saksoversikt/sak.slice.ts
+++ b/src/features/saksoversikt/sak.slice.ts
@@ -10,11 +10,13 @@ import * as klageActions from '~src/features/klage/klageActions';
import * as revurderingActions from '~src/features/revurdering/revurderingActions';
import * as SøknadActions from '~src/features/søknad/SøknadActions';
import * as SøknadsbehandlingActions from '~src/features/SøknadsbehandlingActions';
+import * as tilbakekrevingActions from '~src/features/TilbakekrevingActions';
import { pipe } from '~src/lib/fp';
import { handleAsyncThunk, simpleRejectedActionToRemoteData } from '~src/redux/utils';
import { Behandlingssammendrag } from '~src/types/Behandlingssammendrag';
import { Dokument, DokumentIdType } from '~src/types/dokument/Dokument';
import { Klage } from '~src/types/Klage';
+import { ManuellTilbakekrevingsbehandling } from '~src/types/ManuellTilbakekrevingsbehandling';
import {
OppdaterRegistrertUtenlandsoppholdRequest,
RegistrerteUtenlandsopphold,
@@ -362,6 +364,24 @@ export default createSlice({
builder.addCase(GrunnlagOgVilkårActions.lagreOpplysningsplikt.fulfilled, (state, action) => {
state.sak = opprettEllerOppdaterRevurderingISak(state.sak, action.payload.revurdering);
});
+
+ //---------------Tilbakekreving-----------------//
+ builder.addCase(tilbakekrevingActions.opprettNyTilbakekrevingsbehandling.fulfilled, (state, action) => {
+ state.sak = pipe(
+ state.sak,
+ RemoteData.map((s) => ({
+ ...s,
+ tilbakekrevinger: [...s.tilbakekrevinger, action.payload],
+ })),
+ );
+ });
+
+ builder.addCase(tilbakekrevingActions.vurderTilbakekrevingsbehandling.fulfilled, (state, action) => {
+ state.sak = oppdaterTilbakekrevingPåSak(state.sak, action.payload);
+ });
+ builder.addCase(tilbakekrevingActions.brevtekstTilbakekrevingsbehandling.fulfilled, (state, action) => {
+ state.sak = oppdaterTilbakekrevingPåSak(state.sak, action.payload);
+ });
},
});
@@ -444,3 +464,16 @@ function oppdaterUtenlandsoppholdISak(
})),
);
}
+
+function oppdaterTilbakekrevingPåSak(
+ sak: RemoteData.RemoteData
,
+ tilbakekreving: ManuellTilbakekrevingsbehandling,
+) {
+ return pipe(
+ sak,
+ RemoteData.map((s) => ({
+ ...s,
+ tilbakekrevinger: s.tilbakekrevinger.map((t) => (t.id === tilbakekreving.id ? tilbakekreving : t)),
+ })),
+ );
+}
diff --git a/src/lib/hooks.ts b/src/lib/hooks.ts
index 48df6b47e..5e50eb25b 100644
--- a/src/lib/hooks.ts
+++ b/src/lib/hooks.ts
@@ -1,6 +1,6 @@
import * as RemoteData from '@devexperts/remote-data-ts';
import { AsyncThunk } from '@reduxjs/toolkit';
-import React, { useMemo, useState } from 'react';
+import React, { useEffect, useMemo, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { ApiClientResult, ApiError } from '~src/api/apiClient';
@@ -135,3 +135,56 @@ export const useExclusiveCombine = (...args: Array !RemoteData.isInitial(a)) ?? args[0];
}, [args]);
};
+
+/**
+ * useAutosave er for bruk dersom du vil kalle på en funksjon etter X sekunder, der endringer i dependencies resetter timeren.
+ *
+ * @param callback - funksjonen som skal kjøres for hver delay
+ * @param delay - tiden i millisekunder autosaven skal kjøres
+ * @param deps - Et set med dependencies som resetter timeren for hver endring
+ */
+export const useAutosave = (callback: () => void, delay = 5000, deps: unknown[] = []) => {
+ React.useEffect(() => {
+ if (delay) {
+ const interval = setInterval(callback, delay);
+
+ return () => clearInterval(interval);
+ }
+
+ return;
+ }, [delay, ...deps]);
+};
+
+/**
+ * useAutosaveOnChange er for bruk dersom du vil kalle på en funksjon hvert X sekund, & dersom data har endret på seg
+ *
+ * @param data - dataen som sjekkes på om ting har endret seg
+ * @param callback - funksjonen som skal kjøres
+ * @param delay - tiden i millisekunder autosaven skal kjøres
+ */
+export const useAutosaveOnChange = (data: T, callback: () => void, delay = 5000) => {
+ const [isSaving, setIsSaving] = React.useState(false);
+ const initialRender = React.useRef(true);
+ const prev = React.useRef(data);
+ const live = React.useRef(data);
+
+ useAutosave(() => {
+ if (prev.current !== live.current) {
+ prev.current = live.current;
+ callback();
+ } else {
+ setIsSaving(false);
+ }
+ }, delay);
+
+ useEffect(() => {
+ if (initialRender.current) {
+ initialRender.current = false;
+ } else {
+ setIsSaving(true);
+ }
+ live.current = data;
+ }, [data]);
+
+ return { isSaving };
+};
diff --git a/src/lib/routes.ts b/src/lib/routes.ts
index b2b508326..dde631d59 100644
--- a/src/lib/routes.ts
+++ b/src/lib/routes.ts
@@ -1,7 +1,7 @@
import { NavigateFunction, useParams } from 'react-router-dom';
import * as Routes from '~src/lib/routes';
-import { KlageSteg, SaksbehandlingMenyvalg } from '~src/pages/saksbehandling/types';
+import { KlageSteg, SaksbehandlingMenyvalg, TilbakekrevingSteg } from '~src/pages/saksbehandling/types';
import { Søknadssteg } from '~src/pages/søknad/types';
import { RevurderingSeksjoner, RevurderingSteg } from '~src/types/Revurdering';
import { Sakstype } from '~src/types/Sak';
@@ -257,12 +257,6 @@ export const klage: Route<{
absPath: '/saksoversikt/:sakId/klage/:klageId/:steg/',
createURL: (args) => `/saksoversikt/${args.sakId}/klage/${args.klageId}/${args.steg}/`,
};
-//---------------Regulering-------------------------
-export const manuellRegulering: Route<{ sakId: string; reguleringId: string }> = {
- path: 'reguler/:reguleringId',
- absPath: '/saksoversikt/:sakId/reguler/:reguleringId',
- createURL: (args) => `/saksoversikt/${args.sakId}/reguler/${args.reguleringId}`,
-};
export const klageOpprett: Route<{ sakId: string }> = {
path: 'opprett',
@@ -270,6 +264,13 @@ export const klageOpprett: Route<{ sakId: string }> = {
createURL: ({ sakId }) => `/saksoversikt/${sakId}/klage/opprett`,
};
+//---------------Regulering-------------------------
+export const manuellRegulering: Route<{ sakId: string; reguleringId: string }> = {
+ path: 'reguler/:reguleringId',
+ absPath: '/saksoversikt/:sakId/reguler/:reguleringId',
+ createURL: (args) => `/saksoversikt/${args.sakId}/reguler/${args.reguleringId}`,
+};
+
export interface SuccessNotificationState {
notification?: string;
}
@@ -309,3 +310,24 @@ export const brevPage: Route<{ sakId: string }> = {
absPath: '/saksoversikt/:sakId/brev',
createURL: (args) => `/saksoversikt/${args.sakId}/brev/`,
};
+
+//---------------Tilbakekreving-------------------------
+export const tilbakekrevingRoot: Route<{
+ sakId: string;
+}> = {
+ path: 'tilbakekreving/*',
+ absPath: 'saksoversikt/:sakId/tilbakekreving',
+ createURL: ({ sakId }) => `/saksoversikt/${sakId}/tilbakekreving`,
+};
+
+export const tilbakekrevValgtSak: Route<{ sakId: string }> = {
+ path: 'opprett',
+ absPath: '/saksoversikt/:sakId/tilbakekreving/opprett',
+ createURL: (args) => `/saksoversikt/${args.sakId}/tilbakekreving/opprett`,
+};
+
+export const tilbakekrevingValgtBehandling: Route<{ sakId: string; behandlingId: string; steg: TilbakekrevingSteg }> = {
+ path: ':behandlingId/:steg',
+ absPath: '/saksoversikt/:sakId/tilbakekreving/:behandlingId/:steg',
+ createURL: (args) => `/saksoversikt/${args.sakId}/tilbakekreving/${args.behandlingId}/${args.steg}`,
+};
diff --git a/src/pages/saksbehandling/sakintro/Sakintro.tsx b/src/pages/saksbehandling/sakintro/Sakintro.tsx
index c6011fa47..e1544494e 100644
--- a/src/pages/saksbehandling/sakintro/Sakintro.tsx
+++ b/src/pages/saksbehandling/sakintro/Sakintro.tsx
@@ -1,7 +1,7 @@
import { ChevronUpIcon, ChevronDownIcon } from '@navikt/aksel-icons';
import { Alert, Button, LinkPanel, Popover } from '@navikt/ds-react';
import { isEmpty } from 'fp-ts/lib/Array';
-import React, { PropsWithChildren, useState } from 'react';
+import React, { useState } from 'react';
import { useOutletContext } from 'react-router-dom';
import { ÅpentBrev } from '~src/assets/Illustrations';
@@ -16,6 +16,7 @@ import Utbetalinger from '~src/pages/saksbehandling/sakintro/Utbetalinger';
import { KlageStatus } from '~src/types/Klage';
import { Sakstype } from '~src/types/Sak';
import { erKlageAvsluttet, erKlageÅpen } from '~src/utils/klage/klageUtils';
+import { erTilbakekrevingsbehandlingÅpen } from '~src/utils/ManuellTilbakekrevingsbehandlingUtils';
import { erReguleringAvsluttet, erReguleringÅpen } from '~src/utils/ReguleringUtils';
import { erRevurderingAvsluttet, erRevurderingÅpen } from '~src/utils/revurdering/revurderingUtils';
import { getIverksatteInnvilgedeSøknader, erSøknadLukket, erSøknadÅpen } from '~src/utils/søknad/søknadUtils';
@@ -38,6 +39,7 @@ const SuksessStatuser = (props: { locationState: Nullable {
@@ -45,15 +47,6 @@ const Sakintro = () => {
const { formatMessage } = useI18n({ messages });
const locationState = useNotificationFromLocation();
- const nyBehandlingTilRoute = (nyBehandling: NyBehandling): string => {
- switch (nyBehandling) {
- case NyBehandling.REVURDER:
- return Routes.revurderValgtSak.createURL({ sakId: props.sak.id });
- case NyBehandling.KLAGE:
- return Routes.klageOpprett.createURL({ sakId: props.sak.id });
- }
- };
-
const iverksatteInnvilgedeSøknader = getIverksatteInnvilgedeSøknader(props.sak);
const harUtbetalinger = !isEmpty(props.sak.utbetalinger);
@@ -89,7 +82,15 @@ const Sakintro = () => {
return { søknad: åpenSøknad, søknadsbehandling: søknadsbehandling };
});
- const alleÅpneBehandlinger = [...åpneRevurderinger, ...åpneReguleringer, ...åpneSøknader, ...åpneKlager];
+ const åpneTilbakekrevingsbehandlinger = props.sak.tilbakekrevinger.filter(erTilbakekrevingsbehandlingÅpen);
+
+ const alleÅpneBehandlinger = [
+ ...åpneRevurderinger,
+ ...åpneReguleringer,
+ ...åpneSøknader,
+ ...åpneKlager,
+ ...åpneTilbakekrevingsbehandlinger,
+ ];
return (
@@ -97,24 +98,10 @@ const Sakintro = () => {
{harVedtak && props.sak.sakstype !== Sakstype.Alder && (
-
- {iverksatteInnvilgedeSøknader.length > 0 && (
-
- {formatMessage('popover.option.revurder')}
-
- )}
-
- {formatMessage('popover.option.klage')}
-
-
+
0}
+ />
)}
{harUtbetalinger && (
{
);
};
-const NyBehandlingVelger: React.FC = (props) => {
+const NyBehandlingVelger = (props: { sakId: string; kanRevurdere: boolean }) => {
const { formatMessage } = useI18n({ messages });
const [anchorEl, setAnchorEl] = useState>(null);
+ const nyBehandlingTilRoute = (nyBehandling: NyBehandling): string => {
+ switch (nyBehandling) {
+ case NyBehandling.REVURDER:
+ return Routes.revurderValgtSak.createURL({ sakId: props.sakId });
+ case NyBehandling.KLAGE:
+ return Routes.klageOpprett.createURL({ sakId: props.sakId });
+ case NyBehandling.TILBAKEKREVING:
+ return Routes.tilbakekrevValgtSak.createURL({ sakId: props.sakId });
+ }
+ };
+
return (
);
diff --git a/src/pages/saksbehandling/sakintro/sakintro-nb.ts b/src/pages/saksbehandling/sakintro/sakintro-nb.ts
index ff3589cfa..0cb54aae0 100644
--- a/src/pages/saksbehandling/sakintro/sakintro-nb.ts
+++ b/src/pages/saksbehandling/sakintro/sakintro-nb.ts
@@ -16,6 +16,7 @@ export default {
'popover.default': 'Velg behandling',
'popover.option.klage': 'Klage',
'popover.option.revurder': 'Revurder',
+ 'popover.option.tilbakekreving': 'Tilbakekreving',
'link.dokumenter': 'Brev sendt fra SU',
'link.kontrollsamtale': 'Kontrollsamtale',
@@ -55,6 +56,7 @@ export default {
'datacell.behandlingstype.klage': 'Klage',
'datacell.behandlingstype.stans': 'Stans',
'datacell.behandlingstype.gjenopptak': 'Gjenopptak',
+ 'datacell.behandlingstype.tilbakekreving': 'Tilbakekreving',
'datacell.status.-': '-',
'datacell.status.nySøknad': 'Ny søknad',
@@ -67,6 +69,7 @@ export default {
'datacell.status.Iverksatt': 'Iverksatt',
'datacell.status.Avsluttet': 'Avsluttet',
'datacell.status.Oversendt': 'Oversendt',
+ 'datacell.status.Vurdert': 'Vurdert',
'datacell.resultat.-': '-',
'datacell.resultat.Avslag': 'Avslag',
diff --git "a/src/pages/saksbehandling/sakintro/\303\245pneBehandlingerTabell/\303\205pneBehandlingerTabell.tsx" "b/src/pages/saksbehandling/sakintro/\303\245pneBehandlingerTabell/\303\205pneBehandlingerTabell.tsx"
index e6bfb42d4..5e8206a8d 100644
--- "a/src/pages/saksbehandling/sakintro/\303\245pneBehandlingerTabell/\303\205pneBehandlingerTabell.tsx"
+++ "b/src/pages/saksbehandling/sakintro/\303\245pneBehandlingerTabell/\303\205pneBehandlingerTabell.tsx"
@@ -17,6 +17,7 @@ import SuTabell, { AriaSortVerdi } from '~src/components/tabell/SuTabell';
import {
getDataCellInfo,
isKlage,
+ isManuellTilbakekrevingsbehandling,
isRegulering,
isRevurdering,
isSøknadMedEllerUtenBehandling,
@@ -31,11 +32,13 @@ import { useApiCall, useAsyncActionCreator } from '~src/lib/hooks';
import { useI18n } from '~src/lib/i18n';
import * as Routes from '~src/lib/routes';
import { Klage } from '~src/types/Klage';
+import { ManuellTilbakekrevingsbehandling } from '~src/types/ManuellTilbakekrevingsbehandling';
import { Regulering, Reguleringstype } from '~src/types/Regulering';
import { Revurdering } from '~src/types/Revurdering';
import { Vilkårtype } from '~src/types/Vilkårsvurdering';
import { formatDateTime } from '~src/utils/date/dateUtils';
import { erKlageTilAttestering, hentSisteVurderteSteg } from '~src/utils/klage/klageUtils';
+import { erTilbakekrevingTilAttestering } from '~src/utils/ManuellTilbakekrevingsbehandlingUtils';
import {
erInformasjonsRevurdering,
erRevurderingGjenopptak,
@@ -49,6 +52,7 @@ import {
kanNavigeresTilOppsummering,
} from '~src/utils/SøknadsbehandlingUtils';
+import { TilbakekrevingSteg } from '../../types';
import messages from '../sakintro-nb';
import styles from './ÅpneBehandlingerTabell.module.less';
@@ -111,6 +115,9 @@ const ÅpneBehandlingerTabell = (props: { sakId: string; tabellBehandlinger: Tab
{isRevurdering(props.b) && }
{isKlage(props.b) && }
{isRegulering(props.b) && }
+ {isManuellTilbakekrevingsbehandling(props.b) && (
+
+ )}
);
};
@@ -444,3 +451,54 @@ const ReguleringKnapper = (props: { sakId: string; r: Regulering }) => {
);
};
+
+const TilbakekrevingsKnapper = (props: { sakId: string; t: ManuellTilbakekrevingsbehandling }) => {
+ const user = useUserContext();
+ const { formatMessage } = useI18n({ messages });
+
+ if (erTilbakekrevingTilAttestering(props.t)) {
+ if (user.isAttestant && user.navIdent !== props.t.opprettetAv) {
+ return (
+
+ {formatMessage('attestering.attester')}
+
+ );
+ }
+ return <>>;
+ }
+
+ return (
+
+
+ {formatMessage('datacell.info.knapp.avsluttBehandling')}
+
+
+
+ {formatMessage('datacell.info.knapp.fortsettBehandling')}
+
+
+ );
+};
diff --git "a/src/pages/saksbehandling/s\303\270knadsbehandling/FormWrapper.tsx" "b/src/pages/saksbehandling/s\303\270knadsbehandling/FormWrapper.tsx"
index e5b20eeaa..50b8f2e38 100644
--- "a/src/pages/saksbehandling/s\303\270knadsbehandling/FormWrapper.tsx"
+++ "b/src/pages/saksbehandling/s\303\270knadsbehandling/FormWrapper.tsx"
@@ -26,7 +26,7 @@ interface Props
{
savingState: ApiResult;
onSuccess?: (res: U) => void;
};
- tilbake?: {
+ tilbake: {
url?: string;
onClick?: () => void;
};
diff --git a/src/pages/saksbehandling/tilbakekreving/Tilbakekreving-nb.ts b/src/pages/saksbehandling/tilbakekreving/Tilbakekreving-nb.ts
new file mode 100644
index 000000000..c2e48d3e7
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/Tilbakekreving-nb.ts
@@ -0,0 +1,31 @@
+export default {
+ 'tilbakekreving.tittel': 'Tilbakekreving',
+
+ 'stegIndikator.vurdering': 'Vurdering',
+ 'stegIndikator.brev': 'Brev',
+ 'stegIndikator.forhandsvarsling': 'Forhåndsvarsel',
+
+ 'vurderTilbakekreving.tittel': 'Vurdering av kravgrunnlag',
+ 'vurderTilbakekreving.skalBeløpBliTilbakekrevd': 'Skal beløpet tilbakekreves?',
+ 'vurderTilbakekreving.skalTilbakekreve': 'Beløpet skal tilbakekreves',
+ 'vurderTilbakekreving.skalIkkeTilbakekreve': 'Beløpet skal ikke tilbakekreves',
+ 'vurderTilbakekreving.feiloppsummering': 'Du må rette følgende feil',
+ 'vurderTilbakekreving.kravgrunnlagsInfo.skatteprosent': 'Skatteprosent',
+ 'vurderTilbakekreving.kravgrunnlagsInfo.tidligereUtbetalt': 'Tidligere utbetalt',
+ 'vurderTilbakekreving.kravgrunnlagsInfo.nyUtbetaling': 'Ny utbetaling',
+ 'vurderTilbakekreving.kravgrunnlagsInfo.skalTilbakekreves': 'Skal tilbakekreves',
+ 'vurderTilbakekreving.kravgrunnlagsInfo.skalIkkeTilbakekreves': 'Skal ikke tilbakekreves',
+
+ 'forhåndsvarsleTilbakekreving.tittel': 'Forhåndsvarsling',
+ 'forhåndsvarsleTilbakekreving.skalForhåndsvarsle': 'Skal det forhåndsvarsles?',
+ 'forhåndsvarsleTilbakekreving.skalForhåndsvarsle.ja': 'Ja',
+ 'forhåndsvarsleTilbakekreving.skalForhåndsvarsle.nei': 'Nei',
+ 'forhåndsvarsleTilbakekreving.fritekst.label': 'Fritekst til brev',
+ 'forhåndsvarsleTilbakekreving.navigering.sendOgFortsett': 'Send og fortsett til saksoversikt',
+ 'forhåndsvarsleTilbakekreving.navigering.fortsettSenere': 'Fortsett senere',
+
+ 'brevForTilbakekreving.tittel': 'Brev',
+ 'brevForTilbakekreving.fritekst.label': 'Fritekst til brev',
+
+ 'knapp.seBrev': 'Se brev',
+};
diff --git a/src/pages/saksbehandling/tilbakekreving/Tilbakekreving.tsx b/src/pages/saksbehandling/tilbakekreving/Tilbakekreving.tsx
new file mode 100644
index 000000000..5aed9fd6b
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/Tilbakekreving.tsx
@@ -0,0 +1,39 @@
+import React from 'react';
+import { Route, Routes, useOutletContext } from 'react-router-dom';
+
+import { SaksoversiktContext } from '~src/context/SaksoversiktContext';
+import * as routes from '~src/lib/routes';
+
+import BehandleTilbakekreving from './behandleTilbakekreving/BehandleTilbakekreving';
+import OpprettTilbakekreving from './opprettTilbakekreving/OpprettTilbakekreving';
+
+const Tilbakekreving = () => {
+ const { sak } = useOutletContext();
+
+ return (
+
+
+ }
+ />
+
+ }
+ />
+
+ );
+};
+
+export default Tilbakekreving;
diff --git a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/BehandleTilbakekreving.module.less b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/BehandleTilbakekreving.module.less
new file mode 100644
index 000000000..15f79592e
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/BehandleTilbakekreving.module.less
@@ -0,0 +1,16 @@
+@import '~/src/styles/variables.less';
+
+.pageContainer {
+ width: 100%;
+}
+
+.pageTittel {
+ width: 100%;
+ padding: @spacing-xs 13rem;
+ border-bottom: 1px solid @navBorder;
+}
+
+.contentContainerMedFramdriftsindikator {
+ display: flex;
+ width: 100%;
+}
diff --git a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/BehandleTilbakekreving.tsx b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/BehandleTilbakekreving.tsx
new file mode 100644
index 000000000..10fbafe5d
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/BehandleTilbakekreving.tsx
@@ -0,0 +1,73 @@
+import { Heading } from '@navikt/ds-react';
+import React from 'react';
+
+import { useI18n } from '~src/lib/i18n';
+import * as routes from '~src/lib/routes';
+import { ManuellTilbakekrevingsbehandling } from '~src/types/ManuellTilbakekrevingsbehandling';
+
+import { TilbakekrevingSteg } from '../../types';
+import messages from '../Tilbakekreving-nb';
+
+import styles from './BehandleTilbakekreving.module.less';
+import BrevForTilbakekreving from './brevForTilbakekreving/BrevForTilbakekreving';
+import ForhåndsvarsleTilbakekreving from './forhåndsvarsleTilbakekreving/ForhåndsvarsleTilbakekreving';
+import TilbakekrevingStegIndikator from './TilbakekrevingStegIndikator';
+import VurderTilbakekreving from './vurderTilbakekreving/VurderTilbakekreving';
+
+const BehandleTilbakekreving = (props: {
+ sakId: string;
+ saksversjon: number;
+ tilbakekrevinger: ManuellTilbakekrevingsbehandling[];
+}) => {
+ const { formatMessage } = useI18n({ messages });
+ const { behandlingId, steg } = routes.useRouteParams();
+
+ const behandling = props.tilbakekrevinger.find((t) => t.id === behandlingId);
+
+ if (!behandling) {
+ return (
+
+ Her skulle det visst vært en behandling, men var ingenting. Er URLen i riktig format, men en
+ eksisterende id?
+
+ );
+ }
+
+ return (
+
+
+ {formatMessage('tilbakekreving.tittel')}
+
+
+
+ {steg === TilbakekrevingSteg.Vurdering && (
+
+ )}
+ {steg === TilbakekrevingSteg.Forhåndsvarsling && (
+
+ )}
+ {steg === TilbakekrevingSteg.Brev && (
+
+ )}
+
+
+ );
+};
+
+export default BehandleTilbakekreving;
diff --git a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/TilbakekrevingStegIndikator.tsx b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/TilbakekrevingStegIndikator.tsx
new file mode 100644
index 000000000..b94c8247d
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/TilbakekrevingStegIndikator.tsx
@@ -0,0 +1,61 @@
+import React from 'react';
+
+import Framdriftsindikator, { Linjestatus } from '~src/components/framdriftsindikator/Framdriftsindikator';
+import { useI18n } from '~src/lib/i18n';
+import * as Routes from '~src/lib/routes';
+import { ManuellTilbakekrevingsbehandling } from '~src/types/ManuellTilbakekrevingsbehandling';
+import {
+ erTilbakekrevingForhåndsvarsletEllerSenere,
+ erTilbakekrevingVurdertMedBrevEllerSenere,
+ erTilbakekrevingVurdertUtenBrevEllerSenere,
+} from '~src/utils/ManuellTilbakekrevingsbehandlingUtils';
+
+import { TilbakekrevingSteg } from '../../types';
+import messages from '../Tilbakekreving-nb';
+
+const stegsInformasjon = (behandling: ManuellTilbakekrevingsbehandling, steg: TilbakekrevingSteg) => {
+ switch (steg) {
+ case TilbakekrevingSteg.Vurdering:
+ return erTilbakekrevingVurdertUtenBrevEllerSenere(behandling)
+ ? { erKlikkbar: true, linjeStatus: Linjestatus.Ok }
+ : { erKlikkbar: false, linjeStatus: Linjestatus.Ingenting };
+ case TilbakekrevingSteg.Forhåndsvarsling:
+ return erTilbakekrevingForhåndsvarsletEllerSenere(behandling)
+ ? { erKlikkbar: true, linjeStatus: Linjestatus.Ok }
+ : { erKlikkbar: false, linjeStatus: Linjestatus.Ingenting };
+ case TilbakekrevingSteg.Brev:
+ return erTilbakekrevingVurdertMedBrevEllerSenere(behandling)
+ ? { erKlikkbar: true, linjeStatus: Linjestatus.Ok }
+ : { erKlikkbar: false, linjeStatus: Linjestatus.Ingenting };
+ }
+};
+
+const TilbakekrevingStegIndikator = (props: {
+ sakId: string;
+ behandling: ManuellTilbakekrevingsbehandling;
+ aktivSteg: TilbakekrevingSteg;
+}) => {
+ const { formatMessage } = useI18n({ messages });
+
+ return (
+ {
+ const stegInfo = stegsInformasjon(props.behandling, steg);
+ return {
+ id: steg,
+ erKlikkbar: stegInfo.erKlikkbar,
+ label: formatMessage(`stegIndikator.${steg}`),
+ status: stegInfo.linjeStatus,
+ url: Routes.tilbakekrevingValgtBehandling.createURL({
+ sakId: props.sakId,
+ behandlingId: props.behandling.id,
+ steg: steg,
+ }),
+ };
+ })}
+ aktivId={props.aktivSteg}
+ />
+ );
+};
+
+export default TilbakekrevingStegIndikator;
diff --git a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.module.less b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.module.less
new file mode 100644
index 000000000..ec0268170
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.module.less
@@ -0,0 +1,20 @@
+@import '~/src/styles/variables.less';
+
+.fritesktOgVisBrevContainer {
+ margin-bottom: @spacing;
+
+ > :not(:last-child) {
+ margin-bottom: @spacing-xs;
+ }
+}
+
+.textareaLabel {
+ //ganske så statisk verdi som setter loading ikonet på enden av textarea. Må sikkert endres dersom textarea endres
+ width: 400px;
+ display: flex;
+ justify-content: space-between;
+}
+
+.seBrevButton {
+ width: @knappBredde;
+}
diff --git a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.tsx b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.tsx
new file mode 100644
index 000000000..b0b3af228
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekreving.tsx
@@ -0,0 +1,161 @@
+import * as RemoteData from '@devexperts/remote-data-ts';
+import { yupResolver } from '@hookform/resolvers/yup';
+import { Button, Loader, Textarea } from '@navikt/ds-react';
+import React from 'react';
+import { Controller, UseFormTrigger, useForm } from 'react-hook-form';
+import { useNavigate } from 'react-router-dom';
+
+import { ErrorIcon, SuccessIcon } from '~src/assets/Icons';
+import ApiErrorAlert from '~src/components/apiErrorAlert/ApiErrorAlert';
+import Feiloppsummering from '~src/components/feiloppsummering/Feiloppsummering';
+import Navigasjonsknapper from '~src/components/navigasjonsknapper/Navigasjonsknapper';
+import ToKolonner from '~src/components/toKolonner/ToKolonner';
+import { brevtekstTilbakekrevingsbehandling } from '~src/features/TilbakekrevingActions';
+import { useAsyncActionCreator, useAutosaveOnChange } from '~src/lib/hooks';
+import { useI18n } from '~src/lib/i18n';
+import * as routes from '~src/lib/routes';
+import { hookFormErrorsTilFeiloppsummering } from '~src/lib/validering';
+import { TilbakekrevingSteg } from '~src/pages/saksbehandling/types';
+import { ManuellTilbakekrevingsbehandling } from '~src/types/ManuellTilbakekrevingsbehandling';
+
+import messages from '../../Tilbakekreving-nb';
+
+import styles from './BrevForTilbakekreving.module.less';
+import { BrevForTilbakekrevingFormData, brevForTilbakekrevingSchema } from './BrevForTilbakekrevingUtils';
+
+const BrevForTilbakekreving = (props: {
+ sakId: string;
+ saksversjon: number;
+ tilbakekreving: ManuellTilbakekrevingsbehandling;
+}) => {
+ const navigate = useNavigate();
+ const { formatMessage } = useI18n({ messages });
+ const [brevStatus, lagreBrev] = useAsyncActionCreator(brevtekstTilbakekrevingsbehandling);
+ const [autosaveStatus, autosave] = useAsyncActionCreator(brevtekstTilbakekrevingsbehandling);
+
+ const form = useForm({
+ resolver: yupResolver(brevForTilbakekrevingSchema),
+ defaultValues: {
+ brevtekst: props.tilbakekreving.fritekst,
+ },
+ });
+
+ const save = (data: BrevForTilbakekrevingFormData, onSuccess: () => void) => {
+ lagreBrev(
+ {
+ sakId: props.sakId,
+ saksversjon: props.saksversjon,
+ behandlingId: props.tilbakekreving.id,
+ brevtekst: data.brevtekst!,
+ },
+ onSuccess,
+ );
+ };
+
+ const handleLagreOgFortsettSenereClick = async (
+ data: BrevForTilbakekrevingFormData,
+ trigger: UseFormTrigger,
+ ) => {
+ await trigger().then((isValid) => {
+ if (isValid) {
+ save(data, () => navigate(routes.saksoversiktValgtSak.createURL({ sakId: props.sakId })));
+ }
+ });
+ };
+
+ const handleSubmit = (data: BrevForTilbakekrevingFormData) => {
+ save(data, () => {
+ console.log('navigering til neste steg');
+ });
+ };
+
+ const onSeBrevClick = () => {
+ console.log('onSeBrevClick');
+ };
+
+ const { isSaving } = useAutosaveOnChange(form.watch('brevtekst'), () =>
+ autosave({
+ sakId: props.sakId,
+ saksversjon: props.saksversjon,
+ behandlingId: props.tilbakekreving.id,
+ brevtekst: form.watch('brevtekst') ?? '',
+ }),
+ );
+
+ return (
+
+ {{
+ left: (
+
+
+
+
handleLagreOgFortsettSenereClick(form.getValues(), form.trigger),
+ }}
+ tilbake={{
+ url: routes.tilbakekrevingValgtBehandling.createURL({
+ sakId: props.sakId,
+ behandlingId: props.tilbakekreving.id,
+ steg: TilbakekrevingSteg.Vurdering,
+ }),
+ }}
+ />
+
+ {RemoteData.isFailure(brevStatus) && }
+
+
+ ),
+ right: <>>,
+ }}
+
+ );
+};
+
+export default BrevForTilbakekreving;
diff --git a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekrevingUtils.ts b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekrevingUtils.ts
new file mode 100644
index 000000000..c42bf0449
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/brevForTilbakekreving/BrevForTilbakekrevingUtils.ts
@@ -0,0 +1,17 @@
+import { struct } from 'fp-ts/lib/Eq';
+import * as S from 'fp-ts/lib/string';
+
+import { Nullable, eqNullable } from '~src/lib/types';
+import yup from '~src/lib/validering';
+
+export interface BrevForTilbakekrevingFormData {
+ brevtekst: Nullable;
+}
+
+export const eqBrevForTilbakekrevingFormData = struct({
+ brevtekst: eqNullable(S.Eq),
+});
+
+export const brevForTilbakekrevingSchema = yup.object({
+ brevtekst: yup.string().nullable().required(),
+});
diff --git "a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/forh\303\245ndsvarsleTilbakekreving/Forh\303\245ndsvarsleTilbakekreving.module.less" "b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/forh\303\245ndsvarsleTilbakekreving/Forh\303\245ndsvarsleTilbakekreving.module.less"
new file mode 100644
index 000000000..26c22e554
--- /dev/null
+++ "b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/forh\303\245ndsvarsleTilbakekreving/Forh\303\245ndsvarsleTilbakekreving.module.less"
@@ -0,0 +1 @@
+@import '~/src/styles/variables.less';
diff --git "a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/forh\303\245ndsvarsleTilbakekreving/Forh\303\245ndsvarsleTilbakekreving.tsx" "b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/forh\303\245ndsvarsleTilbakekreving/Forh\303\245ndsvarsleTilbakekreving.tsx"
new file mode 100644
index 000000000..81f44159e
--- /dev/null
+++ "b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/forh\303\245ndsvarsleTilbakekreving/Forh\303\245ndsvarsleTilbakekreving.tsx"
@@ -0,0 +1,143 @@
+import * as RemoteData from '@devexperts/remote-data-ts';
+import { yupResolver } from '@hookform/resolvers/yup';
+import { Radio, RadioGroup } from '@navikt/ds-react';
+import React from 'react';
+import { Controller, useForm } from 'react-hook-form';
+import { useNavigate } from 'react-router-dom';
+
+import * as PdfApi from '~src/api/pdfApi';
+import ApiErrorAlert from '~src/components/apiErrorAlert/ApiErrorAlert';
+import { BrevInput } from '~src/components/brevInput/BrevInput';
+import Feiloppsummering from '~src/components/feiloppsummering/Feiloppsummering';
+import Navigasjonsknapper from '~src/components/navigasjonsknapper/Navigasjonsknapper';
+import ToKolonner from '~src/components/toKolonner/ToKolonner';
+import * as TilbakekrevingActions from '~src/features/TilbakekrevingActions';
+import { useAsyncActionCreator } from '~src/lib/hooks';
+import { useI18n } from '~src/lib/i18n';
+import * as Routes from '~src/lib/routes';
+import { hookFormErrorsTilFeiloppsummering } from '~src/lib/validering';
+import { TilbakekrevingSteg } from '~src/pages/saksbehandling/types';
+import { ManuellTilbakekrevingsbehandling } from '~src/types/ManuellTilbakekrevingsbehandling';
+
+import messages from '../../Tilbakekreving-nb';
+
+import {
+ ForhåndsvarsleTilbakekrevingFormData,
+ forhåndsvarsleTilbakekrevingFormSchema,
+} from './ForhåndsvarsleTilbakekrevingUtils';
+
+const ForhåndsvarsleTilbakekreving = (props: {
+ sakId: string;
+ saksversjon: number;
+ tilbakekreving: ManuellTilbakekrevingsbehandling;
+}) => {
+ const navigate = useNavigate();
+ const { formatMessage } = useI18n({ messages });
+ const [lagreForhåndsvarselStatus, lagreForhåndsvarsel] = useAsyncActionCreator(
+ TilbakekrevingActions.sendForhåndsvarsel,
+ );
+
+ const form = useForm({
+ defaultValues: {
+ skalForhåndsvarsle: false,
+ fritekst: '',
+ },
+ resolver: yupResolver(forhåndsvarsleTilbakekrevingFormSchema),
+ });
+
+ const handleSubmit = (data: ForhåndsvarsleTilbakekrevingFormData) => {
+ lagreForhåndsvarsel(
+ {
+ sakId: props.sakId,
+ saksversjon: props.saksversjon,
+ behandlingId: props.tilbakekreving.id,
+ fritekst: data.fritekst,
+ },
+ () => {
+ navigate(Routes.saksoversiktValgtSak.createURL({ sakId: props.sakId }));
+ },
+ );
+ };
+
+ return (
+
+ {{
+ left: (
+
+ ),
+ right: TODO
,
+ }}
+
+ );
+};
+
+export default ForhåndsvarsleTilbakekreving;
diff --git "a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/forh\303\245ndsvarsleTilbakekreving/Forh\303\245ndsvarsleTilbakekrevingUtils.ts" "b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/forh\303\245ndsvarsleTilbakekreving/Forh\303\245ndsvarsleTilbakekrevingUtils.ts"
new file mode 100644
index 000000000..485f9b2e8
--- /dev/null
+++ "b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/forh\303\245ndsvarsleTilbakekreving/Forh\303\245ndsvarsleTilbakekrevingUtils.ts"
@@ -0,0 +1,8 @@
+import yup from '~src/lib/validering';
+
+export interface ForhåndsvarsleTilbakekrevingFormData {
+ skalForhåndsvarsle: boolean;
+ fritekst: string;
+}
+
+export const forhåndsvarsleTilbakekrevingFormSchema = yup.object({});
diff --git a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/vurderTilbakekreving/VurderTilbakekreving.module.less b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/vurderTilbakekreving/VurderTilbakekreving.module.less
new file mode 100644
index 000000000..0bfa5c740
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/vurderTilbakekreving/VurderTilbakekreving.module.less
@@ -0,0 +1,24 @@
+@import '~/src/styles/variables.less';
+
+.grunnlagsperioderContainer {
+ display: flex;
+ flex-direction: column;
+ gap: @spacing-s;
+ margin-bottom: @spacing-s;
+}
+
+.periodePanel {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+}
+
+.kravgrunnlagsInfoContainer {
+ display: flex;
+ flex-direction: column;
+ gap: @spacing-s;
+
+ .detalje {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ }
+}
diff --git a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/vurderTilbakekreving/VurderTilbakekreving.tsx b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/vurderTilbakekreving/VurderTilbakekreving.tsx
new file mode 100644
index 000000000..3e4a66545
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/vurderTilbakekreving/VurderTilbakekreving.tsx
@@ -0,0 +1,243 @@
+import * as RemoteData from '@devexperts/remote-data-ts';
+import { yupResolver } from '@hookform/resolvers/yup';
+import { Heading, Panel, Radio, RadioGroup } from '@navikt/ds-react';
+import React from 'react';
+import { Controller, UseFormTrigger, useFieldArray, useForm } from 'react-hook-form';
+import { useNavigate } from 'react-router-dom';
+
+import ApiErrorAlert from '~src/components/apiErrorAlert/ApiErrorAlert';
+import Feiloppsummering from '~src/components/feiloppsummering/Feiloppsummering';
+import Navigasjonsknapper from '~src/components/navigasjonsknapper/Navigasjonsknapper';
+import OppsummeringAvKravgrunnlag from '~src/components/oppsummering/kravgrunnlag/OppsummeringAvKravgrunnlag';
+import { OppsummeringPar } from '~src/components/oppsummering/oppsummeringpar/OppsummeringPar';
+import ToKolonner from '~src/components/toKolonner/ToKolonner';
+import { vurderTilbakekrevingsbehandling } from '~src/features/TilbakekrevingActions';
+import { useAsyncActionCreator } from '~src/lib/hooks';
+import { useI18n } from '~src/lib/i18n';
+import * as routes from '~src/lib/routes';
+import { hookFormErrorsTilFeiloppsummering } from '~src/lib/validering';
+import { TilbakekrevingSteg } from '~src/pages/saksbehandling/types';
+import {
+ ManuellTilbakekrevingsbehandling,
+ TilbakekrevingsVurdering,
+} from '~src/types/ManuellTilbakekrevingsbehandling';
+import Måned from '~src/types/Måned';
+
+import messages from '../../Tilbakekreving-nb';
+
+import styles from './VurderTilbakekreving.module.less';
+import {
+ VurderTilbakekrevingFormData,
+ eqVurderTilbakekrevingFormData,
+ vurderTilbakekrevingSchema,
+} from './VurderTilbakekrevingUtils';
+
+const VurderTilbakekreving = (props: {
+ sakId: string;
+ saksversjon: number;
+ tilbakekreving: ManuellTilbakekrevingsbehandling;
+}) => {
+ const fieldName = 'grunnlagsperioder';
+ const navigate = useNavigate();
+ const { formatMessage } = useI18n({ messages });
+ const [status, lagre] = useAsyncActionCreator(vurderTilbakekrevingsbehandling);
+
+ const nesteUrl = routes.tilbakekrevingValgtBehandling.createURL({
+ sakId: props.sakId,
+ behandlingId: props.tilbakekreving.id,
+ steg: TilbakekrevingSteg.Forhåndsvarsling,
+ });
+
+ const defaultValuesFraBehandling = props.tilbakekreving.månedsvurderinger.map((måned) => ({
+ måned: Måned.fromString(måned.måned),
+ vurdering: måned.vurdering,
+ }));
+
+ const defaultValuesFraKravgunnlag = props.tilbakekreving.kravgrunnlag.grunnlagsperiode.map((periode) => ({
+ måned: Måned.fromStringPeriode(periode.periode),
+ vurdering: null,
+ }));
+
+ const initialValues =
+ defaultValuesFraBehandling.length > 0
+ ? { grunnlagsperioder: defaultValuesFraBehandling }
+ : { grunnlagsperioder: defaultValuesFraKravgunnlag };
+
+ const form = useForm({
+ defaultValues: initialValues,
+ resolver: yupResolver(vurderTilbakekrevingSchema),
+ });
+ const { fields } = useFieldArray({ name: fieldName, control: form.control });
+
+ const save = (data: VurderTilbakekrevingFormData, onSuccess: () => void) => {
+ lagre(
+ {
+ sakId: props.sakId,
+ saksversjon: props.saksversjon,
+ behandlingId: props.tilbakekreving.id,
+ måneder: data.grunnlagsperioder.map((periode) => ({
+ måned: periode.måned.toString(),
+ vurdering: periode.vurdering!,
+ })),
+ },
+ onSuccess,
+ );
+ };
+
+ const handleLagreOgFortsettSenereClick = async (
+ data: VurderTilbakekrevingFormData,
+ trigger: UseFormTrigger,
+ ) => {
+ if (eqVurderTilbakekrevingFormData.equals(initialValues, data)) {
+ navigate(routes.saksoversiktValgtSak.createURL({ sakId: props.sakId }));
+ return;
+ }
+
+ await trigger().then((isValid) => {
+ if (isValid) {
+ save(data, () => navigate(routes.saksoversiktValgtSak.createURL({ sakId: props.sakId })));
+ }
+ });
+ };
+
+ const handleSubmit = (values: VurderTilbakekrevingFormData) => {
+ if (eqVurderTilbakekrevingFormData.equals(initialValues, values)) {
+ navigate(nesteUrl);
+ return;
+ }
+ save(values, () => navigate(nesteUrl));
+ };
+
+ return (
+
+ {{
+ left: (
+
+ ),
+ right: (
+
+ ),
+ }}
+
+ );
+};
+
+export default VurderTilbakekreving;
diff --git a/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/vurderTilbakekreving/VurderTilbakekrevingUtils.ts b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/vurderTilbakekreving/VurderTilbakekrevingUtils.ts
new file mode 100644
index 000000000..f11dd663d
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/behandleTilbakekreving/vurderTilbakekreving/VurderTilbakekrevingUtils.ts
@@ -0,0 +1,45 @@
+import { getEq } from 'fp-ts/Array';
+import { struct } from 'fp-ts/lib/Eq';
+import * as S from 'fp-ts/lib/string';
+
+import { Nullable, eqNullable } from '~src/lib/types';
+import yup from '~src/lib/validering';
+import { TilbakekrevingsVurdering } from '~src/types/ManuellTilbakekrevingsbehandling';
+import Måned from '~src/types/Måned';
+
+export interface VurderTilbakekrevingFormData {
+ grunnlagsperioder: GrunnlagsperiodeFormData[];
+}
+
+interface GrunnlagsperiodeFormData {
+ måned: Måned;
+ vurdering: Nullable;
+}
+
+export const eqGrunnlagsperiodeFormData = struct({
+ måned: Måned.eq(),
+ vurdering: eqNullable(S.Eq),
+});
+
+export const eqVurderTilbakekrevingFormData = struct({
+ grunnlagsperioder: getEq(eqGrunnlagsperiodeFormData),
+});
+
+export const vurderTilbakekrevingSchema = yup.object({
+ grunnlagsperioder: yup
+ .array(
+ yup
+ .object({
+ måned: yup.object().required(),
+ vurdering: yup
+ .mixed()
+ .oneOf([
+ TilbakekrevingsVurdering.SKAL_IKKE_TILBAKEKREVES,
+ TilbakekrevingsVurdering.SKAL_TILBAKEKREVES,
+ ])
+ .required(),
+ })
+ .required(),
+ )
+ .required(),
+});
diff --git a/src/pages/saksbehandling/tilbakekreving/opprettTilbakekreving/OpprettTilbakekreving-nb.ts b/src/pages/saksbehandling/tilbakekreving/opprettTilbakekreving/OpprettTilbakekreving-nb.ts
new file mode 100644
index 000000000..f0a2636c6
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/opprettTilbakekreving/OpprettTilbakekreving-nb.ts
@@ -0,0 +1,12 @@
+export default {
+ 'page.heading': 'Tilbakekreving',
+
+ 'tilbakekreving.kanTilbakekreves.ny': 'Start tilbakekrevingsbehandling',
+ 'tilbakekreving.kanTilbakekreves.heading': 'Saken har en aktiv kravgrunnlag som kan tilbakekreves',
+ 'tilbakekreving.kanTilbakekreves.text': 'Du kan starte en ny tilbakekrevingsbehandling',
+
+ 'tilbakekreving.kanIkkeTilbakekreves.heading': 'Kan ikke tilbakekreves',
+ 'tilbakekreving.kanIkkeTilbakekreves.text': 'Saken har ikke en aktiv kravgrunnlag som kan tilbakekreves.',
+
+ 'knapp.tilbake': 'Tilbake',
+};
diff --git a/src/pages/saksbehandling/tilbakekreving/opprettTilbakekreving/OpprettTilbakekreving.module.less b/src/pages/saksbehandling/tilbakekreving/opprettTilbakekreving/OpprettTilbakekreving.module.less
new file mode 100644
index 000000000..24ad3e255
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/opprettTilbakekreving/OpprettTilbakekreving.module.less
@@ -0,0 +1,37 @@
+@import '~/src/styles/variables.less';
+
+.pageContainer {
+ width: 100%;
+}
+
+.headingContainer {
+ border-bottom: 1px solid black;
+ margin-bottom: @spacing-s;
+
+ .tilbakekrevingHeading {
+ margin-top: @spacing-s;
+ margin-left: 10rem;
+ margin-bottom: @spacing-s;
+ }
+}
+
+.mainContentContainer {
+ display: flex;
+ gap: @spacing-xxl;
+ margin: 0 10rem;
+ flex-wrap: wrap;
+}
+
+.panelContentContainer {
+ display: flex;
+ flex-direction: column;
+ gap: @spacing-s;
+ align-items: flex-start;
+ height: max-content;
+ width: 35%;
+}
+
+.knappContainer {
+ display: flex;
+ gap: @spacing-s;
+}
diff --git a/src/pages/saksbehandling/tilbakekreving/opprettTilbakekreving/OpprettTilbakekreving.tsx b/src/pages/saksbehandling/tilbakekreving/opprettTilbakekreving/OpprettTilbakekreving.tsx
new file mode 100644
index 000000000..7512b693b
--- /dev/null
+++ b/src/pages/saksbehandling/tilbakekreving/opprettTilbakekreving/OpprettTilbakekreving.tsx
@@ -0,0 +1,111 @@
+import * as RemoteData from '@devexperts/remote-data-ts';
+import { Button, Heading, Panel } from '@navikt/ds-react';
+import React from 'react';
+import { useNavigate } from 'react-router-dom';
+
+import ApiErrorAlert from '~src/components/apiErrorAlert/ApiErrorAlert';
+import LinkAsButton from '~src/components/linkAsButton/LinkAsButton';
+import OppsummeringAvKravgrunnlag from '~src/components/oppsummering/kravgrunnlag/OppsummeringAvKravgrunnlag';
+import { opprettNyTilbakekrevingsbehandling } from '~src/features/TilbakekrevingActions';
+import { useAsyncActionCreator } from '~src/lib/hooks';
+import { useI18n } from '~src/lib/i18n';
+import * as routes from '~src/lib/routes';
+import { Nullable } from '~src/lib/types';
+import { Kravgrunnlag } from '~src/types/Kravgrunnlag';
+
+import { TilbakekrevingSteg } from '../../types';
+
+import messages from './OpprettTilbakekreving-nb';
+import styles from './OpprettTilbakekreving.module.less';
+
+const OpprettTilbakekreving = (props: {
+ sakId: string;
+ sakVersjon: number;
+ uteståendeKravgrunnlag: Nullable;
+}) => {
+ const { formatMessage } = useI18n({ messages });
+
+ return (
+
+
+
+ {formatMessage('page.heading')}
+
+
+
+
+ {props.uteståendeKravgrunnlag ? (
+
+ ) : (
+
+ )}
+
+
+ );
+};
+
+const KanTilbakekreves = (props: { sakId: string; saksversjon: number; kravgrunnlag: Kravgrunnlag }) => {
+ const navigate = useNavigate();
+ const { formatMessage } = useI18n({ messages });
+ const [opprettStatus, opprett] = useAsyncActionCreator(opprettNyTilbakekrevingsbehandling);
+
+ return (
+ <>
+
+
+ {formatMessage('tilbakekreving.kanTilbakekreves.heading')}
+ {formatMessage('tilbakekreving.kanTilbakekreves.text')}
+
+
+
+
+ {formatMessage('knapp.tilbake')}
+
+
+
+ {RemoteData.isFailure(opprettStatus) && }
+
+
+ >
+ );
+};
+
+const KanIkkeTilbakekreves = (props: { sakId: string }) => {
+ const { formatMessage } = useI18n({ messages });
+ return (
+
+
+ {formatMessage('tilbakekreving.kanIkkeTilbakekreves.heading')}
+ {formatMessage('tilbakekreving.kanIkkeTilbakekreves.text')}
+
+
+
+ {formatMessage('knapp.tilbake')}
+
+
+ );
+};
+
+export default OpprettTilbakekreving;
diff --git a/src/pages/saksbehandling/types.ts b/src/pages/saksbehandling/types.ts
index 9c28bdc4f..87548cd3f 100644
--- a/src/pages/saksbehandling/types.ts
+++ b/src/pages/saksbehandling/types.ts
@@ -14,3 +14,9 @@ export enum KlageSteg {
Avvisning = 'avvisning',
Oppsummering = 'oppsummering',
}
+
+export enum TilbakekrevingSteg {
+ Vurdering = 'vurdering',
+ Forhåndsvarsling = 'forhandsvarsling',
+ Brev = 'brev',
+}
diff --git a/src/types/Kravgrunnlag.ts b/src/types/Kravgrunnlag.ts
new file mode 100644
index 000000000..3b521cacf
--- /dev/null
+++ b/src/types/Kravgrunnlag.ts
@@ -0,0 +1,35 @@
+import { Periode } from './Periode';
+
+export interface Kravgrunnlag {
+ eksternKravgrunnlagsId: string;
+ eksternVedtakId: string;
+ kontrollfelt: string;
+ status: KravgrunnlagStatus;
+ grunnlagsperiode: Grunnlagsperiode[];
+}
+
+export enum KravgrunnlagStatus {
+ ANNU = 'ANNU',
+ ANOM = 'ANOM',
+ AVSL = 'AVSL',
+ BEHA = 'BEHA',
+ ENDR = 'ENDR',
+ FEIL = 'FEIL',
+ MANU = 'MANU',
+ NY = 'NY',
+ SPER = 'SPER',
+}
+
+export interface Grunnlagsperiode {
+ periode: Periode;
+ beløpSkattMnd: number;
+ ytelse: Grunnlagsbeløp;
+}
+
+export interface Grunnlagsbeløp {
+ beløpTidligereUtbetaling: number;
+ beløpNyUtbetaling: number;
+ beløpSkalTilbakekreves: number;
+ beløpSkalIkkeTilbakekreves: number;
+ skatteProsent: number;
+}
diff --git a/src/types/ManuellTilbakekrevingsbehandling.ts b/src/types/ManuellTilbakekrevingsbehandling.ts
new file mode 100644
index 000000000..d7a2c4d2d
--- /dev/null
+++ b/src/types/ManuellTilbakekrevingsbehandling.ts
@@ -0,0 +1,59 @@
+import { Nullable } from '~src/lib/types';
+
+import { Kravgrunnlag } from './Kravgrunnlag';
+
+export interface ManuellTilbakekrevingsbehandling {
+ id: string;
+ sakId: string;
+ opprettet: string;
+ opprettetAv: string;
+ kravgrunnlag: Kravgrunnlag;
+ status: TilbakekrevingsbehandlingStatus;
+ månedsvurderinger: Månedsvurdering[];
+ dokumenter: string[];
+ fritekst: Nullable;
+}
+
+export enum TilbakekrevingsbehandlingStatus {
+ OPPRETTET = 'OPPRETTET',
+ VURDERT_UTEN_BREV = 'VURDERT_UTEN_BREV',
+ VURDERT_MED_BREV = 'VURDERT_MED_BREV',
+ TIL_ATTESTERING = 'TIL_ATTESTERING',
+ IVERKSATT = 'IVERKSATT',
+}
+
+export interface Månedsvurdering {
+ måned: string;
+ vurdering: TilbakekrevingsVurdering;
+}
+
+export interface OpprettNyTilbakekrevingsbehandlingRequest {
+ sakId: string;
+ saksversjon: number;
+}
+
+export enum TilbakekrevingsVurdering {
+ SKAL_TILBAKEKREVES = 'SkalTilbakekreve',
+ SKAL_IKKE_TILBAKEKREVES = 'SkalIkkeTilbakekreve',
+}
+
+export interface VurderTilbakekrevingsbehandlingRequest {
+ sakId: string;
+ saksversjon: number;
+ behandlingId: string;
+ måneder: Array<{ måned: string; vurdering: TilbakekrevingsVurdering }>;
+}
+
+export interface ForhåndsvarsleTilbakekrevingRequest {
+ sakId: string;
+ saksversjon: number;
+ behandlingId: string;
+ fritekst: string;
+}
+
+export interface BrevtekstTilbakekrevingsbehandlingRequest {
+ sakId: string;
+ saksversjon: number;
+ behandlingId: string;
+ brevtekst: string;
+}
diff --git "a/src/types/M\303\245ned.ts" "b/src/types/M\303\245ned.ts"
index 629be896f..ced9e384a 100644
--- "a/src/types/M\303\245ned.ts"
+++ "b/src/types/M\303\245ned.ts"
@@ -1,4 +1,6 @@
import * as DateFns from 'date-fns';
+import { Eq, contramap } from 'fp-ts/lib/Eq';
+import * as S from 'fp-ts/lib/string';
import * as DateUtils from '~src/utils/date/dateUtils';
@@ -18,14 +20,24 @@ class Måned {
return new Måned(år, måned);
}
- static fromDate(input: Date) {
+ static fromDate(input: Date): Måned {
if (!Måned.isStringInputValid(`${input.getFullYear()}-${input.getMonth() + 1}`)) {
- throw new Error('Invalid input for måned');
+ throw new Error('Invalid date input for måned');
}
return new Måned(input.getFullYear().toString(), (input.getMonth() + 1).toString());
}
+ static fromStringPeriode(periode: Periode): Måned {
+ if (!Måned.isStringPeriodeValid(periode)) {
+ throw new Error('Invalid periode input for måned');
+ }
+
+ const [år, måned] = periode.fraOgMed.split('-');
+
+ return new Måned(år, måned);
+ }
+
private constructor(år: string, måned: string) {
this.#år = år;
this.#måned = måned;
@@ -39,6 +51,14 @@ class Måned {
return `${this.#år}-${this.#måned}`;
}
+ /**
+ *
+ * @returns måned på format MM-yyyy
+ */
+ toFormattedString(): string {
+ return `${this.#måned}.${this.#år}`;
+ }
+
/**
*
* @returns Returnerer en periode for måneden
@@ -55,6 +75,10 @@ class Måned {
};
}
+ static eq(): Eq {
+ return contramap((måned: Måned) => `${måned.#år}-${måned.#måned}`)(S.Eq);
+ }
+
/**
*
* @param input et vilkårlig string input, som helst skal være på formatet yyyy-mm eller yyyy-mm-dd
@@ -79,6 +103,21 @@ class Måned {
values[1] <= 12
);
}
+
+ /**
+ * @note året, og måneden i perioden må være den samme
+ */
+ private static isStringPeriodeValid(periode: Periode): boolean {
+ const splitFraOgMed = periode.fraOgMed.split('-');
+ const splitTilOgMed = periode.tilOgMed.split('-');
+
+ return (
+ Måned.isStringInputValid(periode.fraOgMed) &&
+ Måned.isStringInputValid(periode.tilOgMed) &&
+ splitFraOgMed[0] === splitTilOgMed[0] &&
+ splitFraOgMed[1] === splitTilOgMed[1]
+ );
+ }
}
export default Måned;
diff --git a/src/types/Sak.ts b/src/types/Sak.ts
index d7c98ba02..24cced66f 100644
--- a/src/types/Sak.ts
+++ b/src/types/Sak.ts
@@ -2,6 +2,8 @@ import { Nullable } from '~src/lib/types';
import { Utbetalingsperiode } from '~src/types/Utbetalingsperiode';
import { Klage } from './Klage';
+import { Kravgrunnlag } from './Kravgrunnlag';
+import { ManuellTilbakekrevingsbehandling } from './ManuellTilbakekrevingsbehandling';
import { Periode } from './Periode';
import { RegistrerteUtenlandsopphold } from './RegistrertUtenlandsopphold';
import { Regulering } from './Regulering';
@@ -29,6 +31,8 @@ export interface Sak {
utenlandsopphold: RegistrerteUtenlandsopphold;
versjon: number;
uteståendeAvkorting: Nullable;
+ tilbakekrevinger: ManuellTilbakekrevingsbehandling[];
+ uteståendeKravgrunnlag: Nullable;
}
export enum KanStansesEllerGjenopptas {
diff --git a/src/utils/ManuellTilbakekrevingsbehandlingUtils.ts b/src/utils/ManuellTilbakekrevingsbehandlingUtils.ts
new file mode 100644
index 000000000..183a5a0c6
--- /dev/null
+++ b/src/utils/ManuellTilbakekrevingsbehandlingUtils.ts
@@ -0,0 +1,30 @@
+import {
+ ManuellTilbakekrevingsbehandling,
+ TilbakekrevingsbehandlingStatus,
+} from '~src/types/ManuellTilbakekrevingsbehandling';
+
+export const erTilbakekrevingsbehandlingÅpen = (t: ManuellTilbakekrevingsbehandling): boolean =>
+ t.status === TilbakekrevingsbehandlingStatus.OPPRETTET ||
+ t.status === TilbakekrevingsbehandlingStatus.VURDERT_UTEN_BREV ||
+ t.status === TilbakekrevingsbehandlingStatus.VURDERT_MED_BREV ||
+ t.status === TilbakekrevingsbehandlingStatus.TIL_ATTESTERING;
+
+export const erTilbakekrevingTilAttestering = (t: ManuellTilbakekrevingsbehandling): boolean =>
+ t.status === TilbakekrevingsbehandlingStatus.TIL_ATTESTERING;
+
+export const erTilbakekrevingVurdertUtenBrevEllerSenere = (t: ManuellTilbakekrevingsbehandling): boolean =>
+ t.status === TilbakekrevingsbehandlingStatus.VURDERT_UTEN_BREV ||
+ t.status === TilbakekrevingsbehandlingStatus.VURDERT_MED_BREV ||
+ t.status === TilbakekrevingsbehandlingStatus.TIL_ATTESTERING ||
+ t.status === TilbakekrevingsbehandlingStatus.IVERKSATT;
+
+export const erTilbakekrevingForhåndsvarsletEllerSenere = (t: ManuellTilbakekrevingsbehandling): boolean =>
+ t?.dokumenter?.length > 0 ||
+ t.status === TilbakekrevingsbehandlingStatus.VURDERT_MED_BREV ||
+ t.status === TilbakekrevingsbehandlingStatus.TIL_ATTESTERING ||
+ t.status === TilbakekrevingsbehandlingStatus.IVERKSATT;
+
+export const erTilbakekrevingVurdertMedBrevEllerSenere = (t: ManuellTilbakekrevingsbehandling): boolean =>
+ t.status === TilbakekrevingsbehandlingStatus.VURDERT_MED_BREV ||
+ t.status === TilbakekrevingsbehandlingStatus.TIL_ATTESTERING ||
+ t.status === TilbakekrevingsbehandlingStatus.IVERKSATT;