diff --git a/src/client/pages/VergunningenV2/VergunningDetail.tsx b/src/client/pages/VergunningenV2/VergunningDetail.tsx index 9bf2c45ea..6f6193bb9 100644 --- a/src/client/pages/VergunningenV2/VergunningDetail.tsx +++ b/src/client/pages/VergunningenV2/VergunningDetail.tsx @@ -1,10 +1,7 @@ import { Grid } from '@amsterdam/design-system-react'; import { useParams } from 'react-router-dom'; -import { - VergunningDocument, - VergunningFrontendV2, -} from '../../../server/services/vergunningen-v2/config-and-types'; +import { VergunningFrontendV2 } from '../../../server/services/vergunningen-v2/config-and-types'; import { isError, isLoading } from '../../../universal/helpers/api'; import { CaseTypeV2 } from '../../../universal/types/vergunningen'; import { ThemaIcon } from '../../components'; @@ -17,6 +14,7 @@ import { AanbiedenDienstenContent } from './detail-page-content/AanbiedenDienste import { GPPContent } from './detail-page-content/GPP'; import { WVOSContent } from './detail-page-content/WVOS'; import { LinkProps } from '../../../universal/types'; +import { VergunningDocument } from '../../../server/services'; interface DetailPageContentProps { vergunning: VergunningFrontendV2; diff --git a/src/server/services/decos/decos-service.test.ts b/src/server/services/decos/decos-service.test.ts index 2aa757c9d..1fb37a9cf 100644 --- a/src/server/services/decos/decos-service.test.ts +++ b/src/server/services/decos/decos-service.test.ts @@ -3,7 +3,7 @@ import uid from 'uid-safe'; import { fetchDecosDocumentList, fetchDecosZaken, - fetchDecosWorkflowDate, + fetchDecosWorkflowDates, fetchDecosZakenFromSource, forTesting, } from './decos-service'; @@ -198,15 +198,13 @@ describe('decos-service', () => { .get(/\/decos\/items\/123-abc-000\/workflowlinkinstances/) .reply(200); - const responseData = await fetchDecosWorkflowDate( - reqID, - 'zaak-id-1', - 'zaak - behandelen' - ); + const responseData = await fetchDecosWorkflowDates(reqID, 'zaak-id-1', [ + 'zaak - behandelen', + ]); expect(responseData).toMatchInlineSnapshot(` { - "content": null, + "content": {}, "status": "OK", } `); @@ -221,18 +219,14 @@ describe('decos-service', () => { .get(/\/decos\/items\/123-abc-000\/workflowlinkinstances/) .reply(200, workflowInstance); - const responseData = await fetchDecosWorkflowDate( - reqID, - 'zaak-id-1', - 'Zaak - behandelen' - ); + const responseData = await fetchDecosWorkflowDates(reqID, 'zaak-id-1', [ + 'Zaak - behandelen', + ]); - expect(responseData).toMatchInlineSnapshot(` - { - "content": "2021-09-13T17:09:00", - "status": "OK", - } - `); + expect(responseData).toMatchObject({ + content: { 'Zaak - behandelen': '2021-09-13T17:09:00' }, + status: 'OK', + }); }); test('Without date', async () => { @@ -250,18 +244,14 @@ describe('decos-service', () => { .get(/\/decos\/items\/123-abc-000\/workflowlinkinstances/) .reply(200, workflowInstance2); - const responseData = await fetchDecosWorkflowDate( - reqID, - 'zaak-id-1', - 'Zaak - behandelen' - ); + const responseData = await fetchDecosWorkflowDates(reqID, 'zaak-id-1', [ + 'Zaak - behandelen', + ]); - expect(responseData).toMatchInlineSnapshot(` - { - "content": null, - "status": "OK", - } - `); + expect(responseData).toMatchObject({ + content: { 'Zaak - behandelen': null }, + status: 'OK', + }); }); }); @@ -572,27 +562,29 @@ describe('decos-service', () => { delete (fields as Partial).date1; const date = forTesting.transformDecosWorkflowDateResponse( - 'Zaak - behandelen', + ['Zaak - behandelen'], workflowInstance2 ); - expect(date).toBe(null); + expect(date).toMatchObject({ 'Zaak - behandelen': null }); }); test('Has date', () => { const date = forTesting.transformDecosWorkflowDateResponse( - 'Zaak - behandelen', + ['Zaak - behandelen'], workflowInstance ); - expect(date).toBe(workflowInstance.content[0].fields.date1); + expect(date).toMatchObject({ + 'Zaak - behandelen': workflowInstance.content[0].fields.date1, + }); }); test('Wrong step title', () => { const date = forTesting.transformDecosWorkflowDateResponse( - 'Zaak - in behandeling', + ['Zaak - in behandeling'], workflowInstance ); - expect(date).toBe(null); + expect(date).toMatchObject({ 'Zaak - in behandeling': null }); }); }); @@ -635,26 +627,29 @@ describe('decos-service', () => { zakenSource.content[0] ); - expect(transformed).toMatchInlineSnapshot(` - { - "caseType": "Werk en vervoer op straat", - "dateDecision": null, - "dateEnd": "2023-12-14T00:00:00", - "dateInBehandeling": "2024-05-04", - "dateRequest": "2023-11-06T00:00:00", - "dateStart": "2023-11-27T00:00:00", - "decision": null, - "id": "Z-23-2230424", - "identifier": "Z/23/2230424", - "kentekens": "95GHZ4", - "key": "084239C942C647F79F1C2B5CCF8DC5DA", - "location": null, - "processed": false, - "status": "In behandeling", - "title": "Werkzaamheden en vervoer op straat (95GHZ4)", - "werkzaamheden": [], - } - `); + expect(transformed).toMatchObject({ + caseType: 'Werk en vervoer op straat', + dateDecision: null, + dateEnd: '2023-12-14T00:00:00', + dateRequest: '2023-11-06T00:00:00', + dateStart: '2023-11-27T00:00:00', + decision: null, + id: 'Z-23-2230424', + identifier: 'Z/23/2230424', + kentekens: '95GHZ4', + key: '084239C942C647F79F1C2B5CCF8DC5DA', + location: null, + processed: false, + status: 'In behandeling', + statusDates: [ + { + status: 'In behandeling', + datePublished: '2024-05-04', + }, + ], + title: 'Werkzaamheden en vervoer op straat (95GHZ4)', + werkzaamheden: [], + }); }); test('Excluded', async () => { diff --git a/src/server/services/decos/decos-service.ts b/src/server/services/decos/decos-service.ts index e27d6cc64..e1e675466 100644 --- a/src/server/services/decos/decos-service.ts +++ b/src/server/services/decos/decos-service.ts @@ -19,6 +19,7 @@ import { DecosZakenResponse, SELECT_FIELDS_META, SELECT_FIELDS_TRANSFORM_BASE, + DecosWorkflowResponse, } from './decos-types'; import { getDecosZaakTypeFromSource, @@ -27,6 +28,7 @@ import { } from './helpers'; import { ApiErrorResponse, + ApiResponse, ApiSuccessResponse, apiSuccessResult, getSettledResult, @@ -155,8 +157,8 @@ async function transformDecosZaakResponse< } // Reference to decos workflow service for use in transformers - const fetchWorkflowDate = (stepTitle: string) => { - return fetchDecosWorkflowDate(requestID, decosZaakSource.key, stepTitle); + const fetchWorkflowDates = (stepTitles: string[]) => { + return fetchDecosWorkflowDates(requestID, decosZaakSource.key, stepTitles); }; // Iterates over the desired data fields (key=>value pairs) and transforms values if necessary. @@ -178,7 +180,7 @@ async function transformDecosZaakResponse< typeof fieldTransformer.transform === 'function' ? fieldTransformer.transform(value, { decosZaakTransformer, - fetchDecosWorkflowDate: fetchWorkflowDate, + fetchDecosWorkflowDates: fetchWorkflowDates, }) : value; } catch (err) { @@ -200,17 +202,23 @@ async function transformDecosZaakResponse< 'unknown-decoszaak-id', key: decosZaakSource.key, title: decosZaakTransformer.title, - dateInBehandeling: null, // Serves as placeholder, value for this property will be added async below. + statusDates: [], // Serves as placeholder, values for this property will be added async below. ...transformedFields, }; - // Try to fetch and assign a specific date on which the zaak was "In behandeling" - if (decosZaakTransformer.dateInBehandelingWorkflowStepTitle) { - const { content: dateInBehandeling } = await fetchWorkflowDate( - decosZaakTransformer.dateInBehandelingWorkflowStepTitle + if (decosZaakTransformer.fetchWorkflowStatusDatesFor) { + const stepTitles = decosZaakTransformer.fetchWorkflowStatusDatesFor.map( + ({ stepTitle }) => stepTitle ); - if (dateInBehandeling) { - decosZaak.dateInBehandeling = dateInBehandeling; + const workFlowDates = await fetchWorkflowDates(stepTitles); + if (workFlowDates.status === 'OK') { + decosZaak.statusDates = + decosZaakTransformer.fetchWorkflowStatusDatesFor.map( + ({ status, stepTitle }) => ({ + status, + datePublished: workFlowDates.content[stepTitle], + }) + ); } } @@ -225,7 +233,7 @@ async function transformDecosZaakResponse< decosZaak, decosZaakSource, { - fetchDecosWorkflowDate: fetchWorkflowDate, + fetchDecosWorkflowDates: fetchWorkflowDates, decosZaakTransformer, } ); @@ -412,23 +420,34 @@ function transformDecosWorkflowKeysResponse(workflowsResponseData: { } function transformDecosWorkflowDateResponse( - stepTitle: DecosWorkflowStepTitle, - singleWorkflowResponseData: { - content: Array<{ fields: { text7: string; date1?: string } }>; - } -) { - return ( - singleWorkflowResponseData.content?.find((workflowStep) => { - return workflowStep.fields.text7 === stepTitle; - })?.fields.date1 ?? null + stepTitles: DecosWorkflowStepTitle[], + singleWorkflowResponseData: DecosWorkflowResponse +): { [key: DecosWorkflowStepTitle]: string | null } { + const responseStepTitleDates = singleWorkflowResponseData.content + .filter((workflowStep) => workflowStep.fields.text7 != null) + .reduce( + (acc, workflowStep) => ({ + ...acc, + [workflowStep.fields.text7]: workflowStep.fields.date1 ?? null, + }), + {} as Record + ); + + const stepTitleToDate = stepTitles.reduce( + (acc, stepTitle) => ({ + ...acc, + [stepTitle]: responseStepTitleDates[stepTitle] ?? null, + }), + {} as Record ); + return stepTitleToDate; } -export async function fetchDecosWorkflowDate( +export async function fetchDecosWorkflowDates( requestID: RequestID, zaakID: DecosZaakBase['key'], - stepTitle: DecosWorkflowStepTitle -) { + stepTitles: DecosWorkflowStepTitle[] +): Promise>> { const apiConfigWorkflows = getApiConfig('DECOS_API', { formatUrl: (config) => { return `${config.url}/items/${zaakID}/workflows`; @@ -442,18 +461,26 @@ export async function fetchDecosWorkflowDate( ); if (!latestWorkflowKey) { - return apiSuccessResult(null); + return apiSuccessResult({}); } + const urlParams = new URLSearchParams({ + top: '50', + properties: 'false', + fetchParents: 'false', + select: ['mark', 'date1', 'date2', 'text7'].join(','), + filter: stepTitles.map((stepTitle) => `text7 eq ${stepTitle}`).join(' or '), + }); + const apiConfigSingleWorkflow = getApiConfig('DECOS_API', { formatUrl: (config) => { - return `${config.url}/items/${latestWorkflowKey}/workflowlinkinstances?properties=false&fetchParents=false&select=mark,date1,date2,text7,sequence&orderBy=sequence&filter=text7 eq '${stepTitle}'`; + return `${config.url}/items/${latestWorkflowKey}/workflowlinkinstances?'${urlParams}'`; }, - transformResponse: (responseData) => - transformDecosWorkflowDateResponse(stepTitle, responseData), + transformResponse: (responseData: DecosWorkflowResponse) => + transformDecosWorkflowDateResponse(stepTitles, responseData), }); - return requestData(apiConfigSingleWorkflow, requestID); + return requestData(apiConfigSingleWorkflow, requestID); } async function fetchIsPdfDocument( diff --git a/src/server/services/decos/decos-types.ts b/src/server/services/decos/decos-types.ts index b56266dee..55d23e2fa 100644 --- a/src/server/services/decos/decos-types.ts +++ b/src/server/services/decos/decos-types.ts @@ -1,4 +1,5 @@ import { ApiResponse } from '../../../universal/helpers/api'; +import { SomeOtherString } from '../../../universal/helpers/types'; import { GenericDocument } from '../../../universal/types'; import { DecosCaseType } from '../../../universal/types/vergunningen'; import { NotificationLabelByType } from '../vergunningen-v2/config-and-types'; @@ -38,6 +39,10 @@ export type DecosDocumentSource = { fields: DecosDocumentBase & DecosFieldsObject; }; +export type DecosWorkflowSource = { + fields: DecosWorkflowFieldsSource; +}; + export type DecosDocumentBlobSource = { key: DecosZaakID; links: string[]; @@ -49,6 +54,8 @@ export type DecosZakenResponse = { content: T; }; +export type DecosWorkflowResponse = DecosZakenResponse; + export type DecosResponse = { itemDataResultSet: { content: T[]; @@ -86,6 +93,10 @@ export type DecosZaakFieldsSource = { // Info regarding possible payment text12?: string | null; }; +type DecosWorkflowFieldsSource = { + text7: string; + date1?: string; +}; export type AddressBookEntry = { key: string; }; @@ -111,9 +122,9 @@ export type DecosFieldTransformer = { }; export type DecosTransformerOptions = { decosZaakTransformer?: DecosZaakTransformer; - fetchDecosWorkflowDate?: ( - stepTitle: DecosWorkflowStepTitle - ) => Promise>; + fetchDecosWorkflowDates?: ( + stepTitles: DecosWorkflowStepTitle[] + ) => Promise>>; }; export type DecosZaakTransformer = { @@ -139,8 +150,8 @@ export type DecosZaakTransformer = { requirePayment?: boolean; // Decision (resultaat) values are generalized here. For example. The sourceValues can be one of: `Toegekend met borden`, `Toegekend zonder dingen` which we want to show to the user as `Toegekend`. decisionTranslations?: Record; - // The title of the workflow step that is used to find a date for the InBehandeling status. - dateInBehandelingWorkflowStepTitle?: string; + // The titles of the workflow steps that are used to find a corresponding date like the InBehandeling status. + fetchWorkflowStatusDatesFor?: { status: ZaakStatus; stepTitle: string }[]; // Indicates if the Zaak should be shown to the user / is expected to be transformed. isActive: boolean; // Initially we request a set of fields to be included in the responseData (?select=). For some cases we need a (few) custom field(s) included in the initial response. @@ -160,7 +171,6 @@ export type DecosZakenSourceFilter = ( export interface DecosZaakBase { caseType: DecosCaseType; dateDecision: string | null; - dateInBehandeling: string | null; dateRequest: string; // DateStart and DateEnd are not applicable to every single decosZaak but general enough to but in base Type. @@ -183,6 +193,9 @@ export interface DecosZaakBase { processed: boolean; status: ZaakStatus; + // WorkflowStep statusses + statusDates: ZaakStatusDate[]; + paymentStatus: string | null; paymentMethod: string | null; } @@ -191,7 +204,11 @@ export type ZaakStatus = | 'Ontvangen' | 'In behandeling' | 'Afgehandeld' - | string; + | SomeOtherString; +export type ZaakStatusDate = { + status: ZaakStatus; + datePublished: string | null; +}; export interface DecosZaakWithLocation extends DecosZaakBase { location: string | null; } diff --git a/src/server/services/decos/helpers.ts b/src/server/services/decos/helpers.ts index 2aa740cab..ffd958f41 100644 --- a/src/server/services/decos/helpers.ts +++ b/src/server/services/decos/helpers.ts @@ -3,6 +3,7 @@ import type { DecosZaakSource, DecosZaakBase, DecosZaakWithKentekens, + ZaakStatus, } from './decos-types'; import { DECOS_EXCLUDE_CASES_WITH_INVALID_DFUNCTION, @@ -175,3 +176,14 @@ export function hasOtherActualDecosZaakOfSameType( export function toDateFormatted(input: string | null) { return input ? defaultDateFormat(input) : null; } + +// Try to fetch and assign a specific date on which the zaak was "In behandeling" +export function getStatusDate( + zaakStatus: ZaakStatus, + decosZaak: DecosZaakBase +) { + return ( + decosZaak.statusDates.find(({ status }) => status === zaakStatus) + ?.datePublished || null + ); +} diff --git a/src/server/services/vergunningen-v2/config-and-types.ts b/src/server/services/vergunningen-v2/config-and-types.ts index b71b0e5a7..947a590f7 100644 --- a/src/server/services/vergunningen-v2/config-and-types.ts +++ b/src/server/services/vergunningen-v2/config-and-types.ts @@ -280,6 +280,7 @@ export interface VergunningOptions { export type VergunningFrontendV2 = T & { dateDecisionFormatted?: string | null; + dateInBehandeling: string | null; dateInBehandelingFormatted: string | null; dateRequestFormatted: string; dateStartFormatted?: string | null; diff --git a/src/server/services/vergunningen-v2/decos-zaken.ts b/src/server/services/vergunningen-v2/decos-zaken.ts index 3e8541c4b..a05dd204a 100644 --- a/src/server/services/vergunningen-v2/decos-zaken.ts +++ b/src/server/services/vergunningen-v2/decos-zaken.ts @@ -247,7 +247,12 @@ export const Omzettingsvergunning: DecosZaakTransformer caseType: CaseTypeV2.NachtwerkOntheffing, title: 'Geluidsontheffing werken in de openbare ruimte (nachtwerkontheffing)', - dateInBehandelingWorkflowStepTitle: 'Nachtwerkontheffing - Behandelen', + fetchWorkflowStatusDatesFor: [ + { + status: 'In behandeling', + stepTitle: 'Nachtwerkontheffing - Behandelen', + }, + ], requirePayment: true, transformFields: { ...SELECT_FIELDS_TRANSFORM_BASE, @@ -438,8 +448,12 @@ export const Samenvoegingsvergunning: DecosZaakTransformer isActive: true, caseType: CaseTypeV2.VormenVanWoonruimte, title: 'VergunningV2 voor woningvorming', - dateInBehandelingWorkflowStepTitle: - 'Woningvormingsvergunning - Beoordelen en besluiten', + fetchWorkflowStatusDatesFor: [ + { + status: 'In behandeling', + stepTitle: 'Woningvormingsvergunning - Beoordelen en besluiten', + }, + ], transformFields: { ...SELECT_FIELDS_TRANSFORM_BASE, text6: location, @@ -494,7 +522,12 @@ export const Splitsingsvergunning: DecosZaakTransformer = { isActive: true, caseType: CaseTypeV2.VOB, title: 'Ligplaatsvergunning', - dateInBehandelingWorkflowStepTitle: 'VOB - Beoordelen en besluiten', + fetchWorkflowStatusDatesFor: [ + { status: 'In behandeling', stepTitle: 'VOB - Beoordelen en besluiten' }, + ], transformFields: { ...SELECT_FIELDS_TRANSFORM_BASE, text9: { name: 'requestKind' }, @@ -523,8 +558,13 @@ export const ExploitatieHorecabedrijf: DecosZaakTransformer = { isActive: !IS_PRODUCTION, caseType: CaseTypeV2.RVVHeleStad, title: 'RVV-verkeersontheffing', - dateInBehandelingWorkflowStepTitle: - 'Status bijwerken en notificatie verzenden - In behandeling', + fetchWorkflowStatusDatesFor: [ + { + status: 'In behandeling', + stepTitle: 'Status bijwerken en notificatie verzenden - In behandeling', + }, + ], requirePayment: true, transformFields: { ...SELECT_FIELDS_TRANSFORM_BASE, @@ -559,7 +603,9 @@ export const RVVSloterweg: DecosZaakTransformer = { isActive: true, caseType: CaseTypeV2.RVVSloterweg, title: 'RVV ontheffing Sloterweg', - dateInBehandelingWorkflowStepTitle: 'RVV Sloterweg - Behandelen', + fetchWorkflowStatusDatesFor: [ + { status: 'In behandeling', stepTitle: 'RVV Sloterweg - Behandelen' }, + ], transformFields: { ...SELECT_FIELDS_TRANSFORM_BASE, text8: { @@ -578,8 +624,9 @@ export const RVVSloterweg: DecosZaakTransformer = { Ingetrokken: ['Ingetrokken door gemeente'], }, async afterTransform(vergunning, zaakSource, options) { - const dateVerleend = - await options?.fetchDecosWorkflowDate?.('Status naar actief'); + const dateVerleend = await options?.fetchDecosWorkflowDates?.([ + 'Status naar actief', + ]); if (dateVerleend) { vergunning.processed = true; @@ -616,8 +663,12 @@ export const EigenParkeerplaats: DecosZaakTransformer = isActive: true, caseType: CaseTypeV2.EigenParkeerplaats, title: CaseTypeV2.EigenParkeerplaats, - dateInBehandelingWorkflowStepTitle: - 'Status bijwerken en notificatie verzenden - In behandeling', + fetchWorkflowStatusDatesFor: [ + { + status: 'In behandeling', + stepTitle: 'Status bijwerken en notificatie verzenden - In behandeling', + }, + ], transformFields: { ...SELECT_FIELDS_TRANSFORM_BASE, date6: dateStart, @@ -692,8 +743,12 @@ export const EigenParkeerplaatsOpheffen: DecosZaakTransformer ({ title: 'Bekijk details', @@ -27,9 +28,7 @@ const statusInBehandeling: NotificationLabels = { description: (vergunning) => `Wij hebben uw aanvraag ${vergunning.title} in behandeling genomen.`, datePublished: (vergunning) => - vergunning.dateInBehandeling - ? vergunning.dateInBehandeling - : vergunning.dateRequest, + getStatusDate('In behandeling', vergunning) ?? vergunning.dateRequest, link, }; diff --git a/src/server/services/vergunningen-v2/vergunningen-notifications.ts b/src/server/services/vergunningen-v2/vergunningen-notifications.ts index 9075ae5a9..aeef80e73 100644 --- a/src/server/services/vergunningen-v2/vergunningen-notifications.ts +++ b/src/server/services/vergunningen-v2/vergunningen-notifications.ts @@ -9,9 +9,7 @@ import { VergunningFrontendV2, } from './config-and-types'; import { decosCaseToZaakTransformers } from './decos-zaken'; -import { - fetchVergunningenV2, -} from './vergunningen'; +import { fetchVergunningenV2 } from './vergunningen'; import { AppRoute, AppRoutes } from '../../../universal/config/routes'; import { Thema, Themas } from '../../../universal/config/thema'; import { @@ -22,7 +20,7 @@ import { isRecentNotification } from '../../../universal/helpers/utils'; import { MyNotification } from '../../../universal/types'; import { AuthProfileAndToken } from '../../auth/auth-types'; import { DEFAULT_API_CACHE_TTL_MS } from '../../config/source-api'; -import { isNearEndDate } from '../decos/helpers'; +import { getStatusDate, isNearEndDate } from '../decos/helpers'; // prettier-ignore export function getNotificationLabels( @@ -34,19 +32,34 @@ export function getNotificationLabels( // Ignore formatting of the switch case statements for readability switch (true) { // TODO: Check if we always have Verleend as decision for expirable vergunning - case notificationLabels.verlooptBinnenkort && vergunning.decision === 'Verleend' && isNearEndDate(vergunning, compareToDate): + case notificationLabels.verlooptBinnenkort && + vergunning.decision === 'Verleend' && + isNearEndDate(vergunning, compareToDate): return notificationLabels.verlooptBinnenkort; - case notificationLabels.isVerlopen && vergunning.decision === 'Verleend' && vergunning.isExpired && vergunning.dateEnd && differenceInMonths(parseISO(vergunning.dateEnd), compareToDate) < NOTIFICATION_MAX_MONTHS_TO_SHOW_EXPIRED: + case notificationLabels.isVerlopen && + vergunning.decision === 'Verleend' && + vergunning.isExpired && + vergunning.dateEnd && + differenceInMonths(parseISO(vergunning.dateEnd), compareToDate) < + NOTIFICATION_MAX_MONTHS_TO_SHOW_EXPIRED: return notificationLabels.isVerlopen; - case notificationLabels.isIngetrokken && vergunning.decision === 'Ingetrokken' && vergunning.dateDecision && isRecentNotification(vergunning.dateDecision): + case notificationLabels.isIngetrokken && + vergunning.decision === 'Ingetrokken' && + vergunning.dateDecision && + isRecentNotification(vergunning.dateDecision): return notificationLabels.isIngetrokken; - case notificationLabels.statusAfgehandeld && vergunning.processed && vergunning.dateDecision && isRecentNotification(vergunning.dateDecision): + case notificationLabels.statusAfgehandeld && + vergunning.processed && + vergunning.dateDecision && + isRecentNotification(vergunning.dateDecision): return notificationLabels.statusAfgehandeld; - case notificationLabels.statusInBehandeling && !vergunning.processed && !!vergunning.dateInBehandeling: + case notificationLabels.statusInBehandeling && + !vergunning.processed && + !!getStatusDate('In behandeling', vergunning): return notificationLabels.statusInBehandeling; case notificationLabels.statusAanvraag && !vergunning.processed: diff --git a/src/server/services/vergunningen-v2/vergunningen-status-steps.ts b/src/server/services/vergunningen-v2/vergunningen-status-steps.ts index 867a6c4c9..06253b2ed 100644 --- a/src/server/services/vergunningen-v2/vergunningen-status-steps.ts +++ b/src/server/services/vergunningen-v2/vergunningen-status-steps.ts @@ -1,6 +1,7 @@ import { RVVSloterweg, VergunningFrontendV2 } from './config-and-types'; import { StatusLineItem } from '../../../universal/types'; import { CaseTypeV2 } from '../../../universal/types/vergunningen'; +import { getStatusDate } from '../decos/helpers'; export function getStatusStepsRVVSloterweg( vergunning: RVVSloterweg @@ -12,11 +13,12 @@ export function getStatusStepsRVVSloterweg( // Update of the kentekens on an active permit. const isChangeRequest = vergunning.requestType !== 'Nieuw'; + const statusDateInProgress = getStatusDate('In behandeling', vergunning); const isReceived = - (!vergunning.dateInBehandeling || !vergunning.dateWorkflowVerleend) && + (!statusDateInProgress || !vergunning.dateWorkflowVerleend) && !vergunning.decision; - const isInprogress = !!vergunning.dateInBehandeling || !isChangeRequest; + const isInprogress = !!statusDateInProgress || !isChangeRequest; const isGranted = !!vergunning.dateWorkflowVerleend; const isExpiredByEndDate = vergunning.dateEnd && @@ -26,8 +28,7 @@ export function getStatusStepsRVVSloterweg( isExpiredByEndDate || vergunning.decision === RVV_SLOTERWEG_RESULT_EXPIRED; const dateInProgress = - (isChangeRequest ? vergunning.dateInBehandeling : vergunning.dateRequest) ?? - ''; + (isChangeRequest ? statusDateInProgress : vergunning.dateRequest) ?? ''; const hasDecision = [ RVV_SLOTERWEG_RESULT_NOT_APPLICABLE, @@ -130,7 +131,8 @@ export function getStatusSteps(vergunning: VergunningFrontendV2) { } const isAfgehandeld = vergunning.processed; - const hasDateInBehandeling = !!vergunning.dateInBehandeling; + const dateInBehandeling = getStatusDate('In behandeling', vergunning); + const hasDateInBehandeling = !!dateInBehandeling; const isInBehandeling = hasDateInBehandeling && !isAfgehandeld; const isExpiredByEndDate = !!vergunning.dateEnd && @@ -151,7 +153,7 @@ export function getStatusSteps(vergunning: VergunningFrontendV2) { { id: 'step-2', status: 'In behandeling', - datePublished: vergunning.dateInBehandeling || '', + datePublished: dateInBehandeling || '', description: '', documents: [], isActive: isInBehandeling, diff --git a/src/server/services/vergunningen-v2/vergunningen.ts b/src/server/services/vergunningen-v2/vergunningen.ts index fb5e64671..5b14dad1b 100644 --- a/src/server/services/vergunningen-v2/vergunningen.ts +++ b/src/server/services/vergunningen-v2/vergunningen.ts @@ -20,7 +20,7 @@ import { BffEndpoints } from '../../routing/bff-routes'; import { generateFullApiUrlBFF } from '../../routing/route-helpers'; import { fetchDecosZaak, fetchDecosZaken } from '../decos/decos-service'; import { DecosZaakDocument, ZakenFilter } from '../decos/decos-types'; -import { isExpired, toDateFormatted } from '../decos/helpers'; +import { getStatusDate, isExpired, toDateFormatted } from '../decos/helpers'; import { decryptEncryptedRouteParamAndValidateSessionID } from '../shared/decrypt-route-param'; export const FILTER_VERGUNNINGEN_DEFAULT: ZakenFilter = ( @@ -43,7 +43,10 @@ function transformVergunningFrontend( const vergunningFrontend: VergunningFrontendV2 = { ...vergunning, dateDecisionFormatted: toDateFormatted(vergunning.dateDecision), - dateInBehandelingFormatted: toDateFormatted(vergunning.dateInBehandeling), + dateInBehandeling: getStatusDate('In behandeling', vergunning), + dateInBehandelingFormatted: toDateFormatted( + getStatusDate('In behandeling', vergunning) + ), dateRequestFormatted: defaultDateFormat(vergunning.dateRequest), // Assign Status steps later on steps: [], diff --git a/src/universal/helpers/types.ts b/src/universal/helpers/types.ts new file mode 100644 index 000000000..ddb7134f1 --- /dev/null +++ b/src/universal/helpers/types.ts @@ -0,0 +1 @@ +export type SomeOtherString = string & NonNullable; // Shows autocomplete in editor for string literals that also can be any string