Skip to content

Commit c4c729c

Browse files
authored
Merge pull request #3389 from navikt/start-ny-behandling-vedtak
Kan starte ny behandling fra et avslagsvedtak
2 parents 3de7a42 + 23f15e3 commit c4c729c

File tree

15 files changed

+147
-19
lines changed

15 files changed

+147
-19
lines changed

src/api/VedtakApi.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Søknadsbehandling } from '~src/types/Søknadsbehandling';
2+
3+
import apiClient, { ApiClientResult } from './apiClient';
4+
5+
export async function startNySøknadsbehandling(arg: {
6+
sakId: string;
7+
vedtakId: string;
8+
}): Promise<ApiClientResult<Søknadsbehandling>> {
9+
return apiClient({
10+
url: `/saker/${arg.sakId}/vedtak/${arg.vedtakId}/nySoknadsbehandling`,
11+
method: 'POST',
12+
});
13+
}

src/api/søknadApi.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Nullable } from '~src/lib/types';
22
import { AvvistBrevConfig } from '~src/pages/saksbehandling/avsluttBehandling/lukkSøknad/lukkSøknadUtils';
33
import { Sak } from '~src/types/Sak';
4-
import { LukkSøknadBegrunnelse, Søknad } from '~src/types/Søknad';
4+
import { LukkSøknadBegrunnelse, LukkSøknadResponse, Søknad } from '~src/types/Søknad';
55
import { SøknadInnholdAlder, SøknadInnholdUføre } from '~src/types/Søknadinnhold';
66

77
import apiClient, { ApiClientResult } from './apiClient';
@@ -45,7 +45,10 @@ export async function sendAlderssøknad(søknad: SøknadInnholdAlder): Promise<A
4545
});
4646
}
4747

48-
export async function lukkSøknad(arg: { søknadId: string; body: LukkSøknadBodyTypes }): Promise<ApiClientResult<Sak>> {
48+
export async function lukkSøknad(arg: {
49+
søknadId: string;
50+
body: LukkSøknadBodyTypes;
51+
}): Promise<ApiClientResult<LukkSøknadResponse>> {
4952
return apiClient({
5053
url: `/soknad/${arg.søknadId}/lukk`,
5154
method: 'POST',

src/components/apiErrorAlert/ApiErrorAlert-nb.ts

-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ const messages: { [key in ApiErrorCode]: string } = {
246246
[ApiErrorCode.STØNADSPERIODEN_OVERLAPPER_EKSISTERENDE]:
247247
'Stønadsperioden overlapper med en eksisterende stønadsperiode',
248248
[ApiErrorCode.SØKNAD_ALLEREDE_LUKKET]: 'Søknaden er allerede lukket',
249-
[ApiErrorCode.SØKNAD_ER_LUKKET]: 'Søknad er lukket',
250249
[ApiErrorCode.SØKNAD_HAR_BEHANDLING]: 'Søknad har allerede en behandling',
251250
[ApiErrorCode.SØKNAD_MANGLER_OPPGAVE]: 'Søknad mangler oppgave',
252251

src/components/apiErrorAlert/apiErrorCode.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,7 @@ export enum ApiErrorCode {
196196
STØNADSPERIODE_FØR_2021 = 'stønadsperiode_før_2021',
197197
STØNADSPERIODE_MAX_12MND = 'stønadsperiode_max_12mnd',
198198
STØNADSPERIODEN_OVERLAPPER_EKSISTERENDE = 'stønadsperioden_overlapper_med_eksisterende_søknadsbehandling',
199-
SØKNAD_ALLEREDE_LUKKET = 'søknad_allerede_lukket',
200-
SØKNAD_ER_LUKKET = 'søknad_er_lukket',
199+
SØKNAD_ALLEREDE_LUKKET = 'søknad_er_allerede_lukket',
201200
SØKNAD_HAR_BEHANDLING = 'søknad_har_behandling',
202201
SØKNAD_MANGLER_OPPGAVE = 'søknad_mangler_oppgave',
203202

src/components/tabell/SuTabellUtils.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,16 @@ import { erPapirSøknad, erSøknadLukket } from '~src/utils/søknad/søknadUtils
1818
import { splitStatusOgResultatFraSøkandsbehandling } from '~src/utils/SøknadsbehandlingUtils';
1919

2020
export const isRegulering = (b: TabellBehandling): b is Regulering => 'reguleringsstatus' in b;
21-
export const isSøknadMedEllerUtenBehandling = (b: TabellBehandling): b is SøknadMedEllerUtenBehandling => 'søknad' in b;
21+
export const isSøknadMedEllerUtenBehandling = (b: TabellBehandling): b is SøknadMedEllerUtenBehandlinger =>
22+
'søknad' in b;
2223
export const isRevurdering = (b: TabellBehandling): b is Revurdering => 'årsak' in b;
2324
export const isKlage = (b: TabellBehandling): b is Klage => 'klagevedtakshistorikk' in b;
2425
export const isManuellTilbakekrevingsbehandling = (b: TabellBehandling): b is ManuellTilbakekrevingsbehandling =>
2526
'kravgrunnlag' in b;
2627

27-
export type SøknadMedEllerUtenBehandling = { søknad: Søknad; søknadsbehandling?: Søknadsbehandling };
28+
export type SøknadMedEllerUtenBehandlinger = { søknad: Søknad; søknadsbehandling?: Søknadsbehandling };
2829
export type TabellBehandling =
29-
| SøknadMedEllerUtenBehandling
30+
| SøknadMedEllerUtenBehandlinger
3031
| Revurdering
3132
| Klage
3233
| Regulering

src/features/VedtakActions.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { createAsyncThunk } from '@reduxjs/toolkit';
2+
3+
import { ApiError } from '~src/api/apiClient';
4+
import * as VedtakApi from '~src/api/VedtakApi';
5+
import { Søknadsbehandling } from '~src/types/Søknadsbehandling';
6+
7+
export const startNySøknadsbehandling = createAsyncThunk<
8+
Søknadsbehandling,
9+
{ sakId: string; vedtakId: string },
10+
{ rejectValue: ApiError }
11+
>('vedtak/nySoknadsbehandling', async (args, thunkApi) => {
12+
const res = await VedtakApi.startNySøknadsbehandling(args);
13+
if (res.status === 'ok') {
14+
return res.data;
15+
}
16+
return thunkApi.rejectWithValue(res.error);
17+
});

src/features/saksoversikt/sak.slice.ts

+26-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as revurderingActions from '~src/features/revurdering/revurderingAction
1111
import * as SøknadActions from '~src/features/søknad/SøknadActions';
1212
import * as SøknadsbehandlingActions from '~src/features/SøknadsbehandlingActions';
1313
import * as tilbakekrevingActions from '~src/features/TilbakekrevingActions';
14+
import * as VedtakActions from '~src/features/VedtakActions';
1415
import { pipe } from '~src/lib/fp';
1516
import { handleAsyncThunk, simpleRejectedActionToRemoteData } from '~src/redux/utils';
1617
import { Behandlingssammendrag } from '~src/types/Behandlingssammendrag';
@@ -201,7 +202,20 @@ export default createSlice({
201202
});
202203

203204
builder.addCase(SøknadActions.lukkSøknad.fulfilled, (state, action) => {
204-
state.sak = RemoteData.success(action.payload);
205+
state.sak = pipe(
206+
state.sak,
207+
RemoteData.map((sak) => ({
208+
...sak,
209+
søknader: sak.søknader.map((s) =>
210+
s.id === action.payload.lukketSøknad.id ? action.payload.lukketSøknad : s,
211+
),
212+
behandlinger: sak.behandlinger.map((b) =>
213+
b.id === action.payload.lukketSøknadsbehandling?.id
214+
? action.payload.lukketSøknadsbehandling
215+
: b,
216+
),
217+
})),
218+
);
205219
});
206220

207221
builder.addCase(SøknadActions.avslagManglendeDokSøknad.fulfilled, (state, action) => {
@@ -424,6 +438,17 @@ export default createSlice({
424438
builder.addCase(tilbakekrevingActions.behandlingsnotatTilbakekreving.fulfilled, (state, action) => {
425439
state.sak = oppdaterTilbakekrevingPåSak(state.sak, action.payload);
426440
});
441+
442+
//---------------Vedtak-----------------//
443+
builder.addCase(VedtakActions.startNySøknadsbehandling.fulfilled, (state, action) => {
444+
state.sak = pipe(
445+
state.sak,
446+
RemoteData.map((sak) => ({
447+
...sak,
448+
behandlinger: [...sak.behandlinger, action.payload],
449+
})),
450+
);
451+
});
427452
},
428453
});
429454

src/features/søknad/SøknadActions.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ApiError } from '~src/api/apiClient';
44
import * as søknadApi from '~src/api/søknadApi';
55
import { AvslagManglendeDokType, LukkSøknadBodyTypes } from '~src/api/søknadApi';
66
import { Sak } from '~src/types/Sak';
7+
import { LukkSøknadResponse } from '~src/types/Søknad';
78

89
export const hentLukketSøknadBrevutkast = createAsyncThunk<
910
{ objectUrl: string },
@@ -24,7 +25,7 @@ export const hentLukketSøknadBrevutkast = createAsyncThunk<
2425
});
2526

2627
export const lukkSøknad = createAsyncThunk<
27-
Sak,
28+
LukkSøknadResponse,
2829
{
2930
søknadId: string;
3031
body: LukkSøknadBodyTypes;

src/pages/saksbehandling/sakintro/Sakintro.tsx

+38-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ChevronUpIcon, ChevronDownIcon } from '@navikt/aksel-icons';
22
import { Alert, Button, LinkPanel, Popover } from '@navikt/ds-react';
3-
import { isEmpty } from 'fp-ts/lib/Array';
3+
import { partition, isEmpty } from 'fp-ts/Array';
44
import { useState } from 'react';
55
import { useOutletContext } from 'react-router-dom';
66

@@ -78,14 +78,46 @@ const Sakintro = () => {
7878
const åpneRevurderinger = props.sak.revurderinger.filter(erRevurderingÅpen);
7979
const åpneReguleringer = props.sak.reguleringer.filter(erReguleringÅpen);
8080
const åpneKlager = props.sak.klager.filter(erKlageÅpen);
81+
8182
const åpneSøknader = props.sak.søknader
8283
.filter((søknad) => {
83-
const søknadsbehandling = props.sak.behandlinger.find((b) => b.søknad.id === søknad.id);
84-
return erSøknadÅpen(søknad) && (!søknadsbehandling || erSøknadsbehandlingÅpen(søknadsbehandling));
84+
const søknadsbehandlinger = props.sak.behandlinger.filter((b) => b.søknad.id === søknad.id);
85+
const parts = partition(erSøknadsbehandlingÅpen)(søknadsbehandlinger);
86+
87+
const harÅpenSøknad = erSøknadÅpen(søknad);
88+
const harÅpenSøknadsbehandling = parts.right.length > 0;
89+
const harIkkeÅpenSøknadsbehandling = parts.right.length === 0;
90+
const harAvslåttSøknadsbehandling = parts.left.length > 0;
91+
const harIkkeAvslåttSøknadsbehandling = parts.left.length === 0;
92+
const harIkkeSøknadsbehandling = harIkkeAvslåttSøknadsbehandling && harIkkeÅpenSøknadsbehandling;
93+
94+
const harSøknadMenIngenBehandling = harÅpenSøknad && harIkkeSøknadsbehandling;
95+
const harSøknadMedEnBehandling = harÅpenSøknad && (harÅpenSøknadsbehandling || harAvslåttSøknadsbehandling);
96+
const harSøknadMedFlereBehandlinger =
97+
harÅpenSøknad && harÅpenSøknadsbehandling && harAvslåttSøknadsbehandling;
98+
99+
if (harSøknadMenIngenBehandling) {
100+
return true;
101+
} else if (harSøknadMedEnBehandling) {
102+
if (harÅpenSøknadsbehandling) {
103+
return true;
104+
} else if (harAvslåttSøknadsbehandling) {
105+
return false;
106+
}
107+
} else if (harSøknadMedFlereBehandlinger) {
108+
return true;
109+
}
110+
111+
return false;
85112
})
86-
.map((åpenSøknad) => {
87-
const søknadsbehandling = props.sak.behandlinger.find((b) => b.søknad.id === åpenSøknad.id);
88-
return { søknad: åpenSøknad, søknadsbehandling: søknadsbehandling };
113+
.flatMap((åpenSøknad) => {
114+
const søknadsbehandlinger = props.sak.behandlinger.filter((b) => b.søknad.id === åpenSøknad.id);
115+
116+
const åpneSøknadsbehandlinger = søknadsbehandlinger.filter(erSøknadsbehandlingÅpen);
117+
118+
return åpneSøknadsbehandlinger.length > 0
119+
? åpneSøknadsbehandlinger.map((b) => ({ søknad: åpenSøknad, søknadsbehandling: b }))
120+
: { søknad: åpenSøknad };
89121
});
90122

91123
const åpneTilbakekrevingsbehandlinger = props.sak.tilbakekrevinger.filter(erTilbakekrevingsbehandlingÅpen);

src/pages/saksbehandling/sakintro/Vedtakstabell/Vedtakstabell.module.less

+5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66

77
.vedtaksbrevDataCell {
88
max-width: 25rem;
9+
910
> :not(:last-child) {
1011
margin-bottom: @spacing-xs;
1112
}
1213
}
14+
15+
.startNyBehandlingDataCellContainer {
16+
width: 15%;
17+
}

src/pages/saksbehandling/sakintro/Vedtakstabell/Vedtakstabell.tsx

+26-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as Ord from 'fp-ts/Ord';
66
import * as S from 'fp-ts/string';
77
import { Link } from 'react-router-dom';
88

9+
import * as VedtakActions from 'src/features/VedtakActions';
910
import * as DokumentApi from '~src/api/dokumentApi';
1011
import { forhåndsvisVedtaksbrevTilbakekrevingsbehandling } from '~src/api/tilbakekrevingApi';
1112
import ApiErrorAlert from '~src/components/apiErrorAlert/ApiErrorAlert';
@@ -15,7 +16,7 @@ import Oppsummeringspanel, {
1516
} from '~src/components/oppsummering/oppsummeringspanel/Oppsummeringspanel';
1617
import SuTabell, { AriaSortVerdi } from '~src/components/tabell/SuTabell';
1718
import { pipe } from '~src/lib/fp';
18-
import { useApiCall } from '~src/lib/hooks';
19+
import { useApiCall, useAsyncActionCreator } from '~src/lib/hooks';
1920
import { useI18n } from '~src/lib/i18n';
2021
import * as Routes from '~src/lib/routes';
2122
import { DokumentIdType } from '~src/types/dokument/Dokument';
@@ -110,6 +111,7 @@ const Vedtakstabell = (props: { sakId: string; vedtakOgOversendteKlager: VedtakO
110111
</Table.ColumnHeader>
111112
<Table.ColumnHeader></Table.ColumnHeader>
112113
<Table.ColumnHeader></Table.ColumnHeader>
114+
<Table.ColumnHeader></Table.ColumnHeader>
113115
</Table.Row>
114116
</Table.Header>
115117
)}
@@ -122,6 +124,9 @@ const Vedtakstabell = (props: { sakId: string; vedtakOgOversendteKlager: VedtakO
122124
const [tilbakekrevingsbrevStatus, hentTilbakekrevingsbrev] = useApiCall(
123125
forhåndsvisVedtaksbrevTilbakekrevingsbehandling,
124126
);
127+
const [startNysøknadsbehandlingStatus, startNySøknadsbehandling] = useAsyncActionCreator(
128+
VedtakActions.startNySøknadsbehandling,
129+
);
125130

126131
return (
127132
<Table.Row key={vedtak.id}>
@@ -202,6 +207,26 @@ const Vedtakstabell = (props: { sakId: string; vedtakOgOversendteKlager: VedtakO
202207
<ApiErrorAlert size="small" error={tilbakekrevingsbrevStatus.error} />
203208
)}
204209
</Table.DataCell>
210+
<Table.DataCell className={styles.startNyBehandlingDataCellContainer}>
211+
{isVedtak(vedtak) && vedtak.kanStarteNyBehandling && (
212+
<Button
213+
size="small"
214+
variant="tertiary"
215+
onClick={() =>
216+
startNySøknadsbehandling({
217+
sakId: props.sakId,
218+
vedtakId: vedtak.id,
219+
})
220+
}
221+
>
222+
{formatMessage('dataCell.startNyBehandling')}
223+
</Button>
224+
)}
225+
226+
{RemoteData.isFailure(startNysøknadsbehandlingStatus) && (
227+
<ApiErrorAlert size="small" error={startNysøknadsbehandlingStatus.error} />
228+
)}
229+
</Table.DataCell>
205230
</Table.Row>
206231
);
207232
})}

src/pages/saksbehandling/sakintro/sakintro-nb.ts

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export default {
9090
'dataCell.info.knapp.regulering.modal.tittel': 'Er du sikker på at du ønsker å lukke reguleringen?',
9191

9292
'dataCell.seOppsummering': 'Se oppsummering',
93+
'dataCell.startNyBehandling': 'Start ny behandling',
9394

9495
'datacell.brev.skalIkkeGenerere': 'Skal ikke sende brev',
9596
'datacell.brev.ikkeGenerert': 'Ikke generert',

src/pages/saksbehandling/sakintro/åpneBehandlingerTabell/ÅpneBehandlingerTabell.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
isRegulering,
2222
isRevurdering,
2323
isSøknadMedEllerUtenBehandling,
24-
SøknadMedEllerUtenBehandling,
24+
SøknadMedEllerUtenBehandlinger,
2525
TabellBehandling,
2626
TabellBehandlinger,
2727
} from '~src/components/tabell/SuTabellUtils';
@@ -197,7 +197,7 @@ const ÅpneBehandlingerTabell = (props: { sakId: string; tabellBehandlinger: Tab
197197

198198
export default ÅpneBehandlingerTabell;
199199

200-
const SøknadOgSøknadsbehandlingKnapper = (props: { sakId: string; b: SøknadMedEllerUtenBehandling }) => {
200+
const SøknadOgSøknadsbehandlingKnapper = (props: { sakId: string; b: SøknadMedEllerUtenBehandlinger }) => {
201201
const user = useUserContext();
202202
const navigate = useNavigate();
203203
const { formatMessage } = useI18n({ messages });

src/types/Søknad.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Nullable } from '~src/lib/types';
22

33
import { SøknadInnhold } from './Søknadinnhold';
4+
import { Søknadsbehandling } from './Søknadsbehandling';
45
import { Dokumenttilstand } from './Vedtak';
56

67
export interface Søknad {
@@ -27,3 +28,8 @@ export enum LukkSøknadBegrunnelse {
2728
interface Saksbehandler {
2829
navIdent: string;
2930
}
31+
32+
export interface LukkSøknadResponse {
33+
lukketSøknad: Søknad;
34+
lukketSøknadsbehandling: Nullable<Søknadsbehandling>;
35+
}

src/types/Vedtak.ts

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface Vedtak<T extends VedtakType = VedtakType> {
1616
simulering: Nullable<Simulering>;
1717
utbetalingId: Nullable<string>;
1818
dokumenttilstand: Dokumenttilstand;
19+
kanStarteNyBehandling: boolean;
1920
}
2021

2122
export interface AvslagVedtak extends Vedtak<VedtakType.AVSLAG> {

0 commit comments

Comments
 (0)