Skip to content

Commit

Permalink
feat: BE: Hyväksymispäätöskuulutus kansalaispuolella (#320)
Browse files Browse the repository at this point in the history
  • Loading branch information
haapamakim committed Aug 17, 2022
1 parent d6246dd commit 55983d8
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 31 deletions.
68 changes: 68 additions & 0 deletions backend/integrationtest/api/__snapshots__/api.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2726,6 +2726,8 @@ Object {
},
],
},
"kuulutusPaiva": "2022-06-09",
"kuulutusVaihePaattyyPaiva": "2100-01-01",
"kuulutusYhteysHenkilot": Array [
"A000112",
],
Expand Down Expand Up @@ -2826,6 +2828,8 @@ Object {
},
],
},
"kuulutusPaiva": "2022-06-09",
"kuulutusVaihePaattyyPaiva": "2100-01-01",
"kuulutusYhteysHenkilot": Array [
"A000112",
],
Expand Down Expand Up @@ -2915,6 +2919,8 @@ Object {
"__typename": "Kielitiedot",
"ensisijainenKieli": "SUOMI",
},
"kuulutusPaiva": "2022-06-09",
"kuulutusVaihePaattyyPaiva": "2100-01-01",
"kuulutusYhteysHenkilot": Array [
"A000112",
],
Expand Down Expand Up @@ -2964,3 +2970,65 @@ Object {
},
}
`;

exports[`Api should search, load and save a project 29`] = `
Object {
"description": "publicProjektiHyvaksymisPaatosVaiheJulkinenAfterApproval",
"obj": Object {
"__typename": "HyvaksymisPaatosVaiheJulkaisuJulkinen",
"aineistoNahtavilla": undefined,
"hallintoOikeus": "HAMEENLINNA",
"hyvaksymisPaatos": undefined,
"kielitiedot": Object {
"__typename": "Kielitiedot",
"ensisijainenKieli": "SUOMI",
},
"kuulutusPaiva": "2022-06-09",
"kuulutusVaihePaattyyPaiva": "2022-06-08",
"kuulutusYhteysHenkilot": Array [
"0",
],
"kuulutusYhteystiedot": Array [
Object {
"__typename": "Yhteystieto",
"etunimi": "Etunimi",
"organisaatio": "",
"puhelinnumero": "0293121213",
"sahkoposti": "Etunimi.Sukunimi@vayla.fi",
"sukunimi": "Sukunimi",
"titteli": "Projektipäällikkö",
},
Object {
"__typename": "Yhteystieto",
"etunimi": "Joku",
"organisaatio": "",
"puhelinnumero": "02998765",
"sahkoposti": "Joku.Jokunen@vayla.fi",
"sukunimi": "Jokunen",
"titteli": "Konsultti",
},
],
"velho": Object {
"__typename": "VelhoJulkinen",
"asiatunnusELY": undefined,
"asiatunnusVayla": undefined,
"kunnat": Array [
"Helsinki",
"Vantaa",
],
"kuvaus": undefined,
"maakunnat": Array [
"Uusimaa",
],
"nimi": "HASSU AUTOMAATTITESTIPROJEKTI1",
"suunnittelustaVastaavaViranomainen": "VAYLAVIRASTO",
"tilaajaOrganisaatio": "Väylävirasto",
"toteuttavaOrganisaatio": undefined,
"tyyppi": "TIE",
"vaylamuoto": Array [
"tie",
],
},
},
}
`;
3 changes: 3 additions & 0 deletions backend/integrationtest/api/testUtil/cleanUpFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ export function cleanupHyvaksymisPaatosVaiheTimestamps(
export function cleanupHyvaksymisPaatosVaiheJulkaisuJulkinenTimestamps(
hyvaksymisPaatosVaihe: HyvaksymisPaatosVaiheJulkaisuJulkinen
): HyvaksymisPaatosVaiheJulkaisuJulkinen {
if (!hyvaksymisPaatosVaihe) {
return undefined;
}
hyvaksymisPaatosVaihe.aineistoNahtavilla?.forEach((aineisto) => (aineisto.tuotu = "***unittest***"));
hyvaksymisPaatosVaihe.hyvaksymisPaatos?.forEach((aineisto) => (aineisto.tuotu = "***unittest***"));
return hyvaksymisPaatosVaihe;
Expand Down
48 changes: 34 additions & 14 deletions backend/integrationtest/api/testUtil/hyvaksymisPaatosVaihe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { projektiDatabase } from "../../../src/database/projektiDatabase";
import { loadProjektiFromDatabase, loadProjektiJulkinenFromDatabase } from "./tests";
import { loadProjektiFromDatabase, loadProjektiJulkinenFromDatabase, testPublicAccessToProjekti } from "./tests";
import {
HallintoOikeus,
HyvaksymisPaatosVaiheTila,
Expand All @@ -15,14 +15,26 @@ import { expect } from "chai";
import { api } from "../apiClient";
import { adaptAineistoToInput, expectToMatchSnapshot } from "./util";
import { apiTestFixture } from "../apiTestFixture";
import { cleanupHyvaksymisPaatosVaiheTimestamps } from "./cleanUpFunctions";
import {
cleanupHyvaksymisPaatosVaiheJulkaisuJulkinenTimestamps,
cleanupHyvaksymisPaatosVaiheTimestamps
} from "./cleanUpFunctions";

export async function testHyvaksymisPaatosVaiheHyvaksymismenettelyssa(oid: string, userFixture: UserFixture): Promise<void> {
const dbProjekti = await projektiDatabase.loadProjektiByOid(oid);
const julkaisu = dbProjekti.nahtavillaoloVaiheJulkaisut[0];
julkaisu.kuulutusVaihePaattyyPaiva = "2022-06-08";
await projektiDatabase.updateNahtavillaoloVaiheJulkaisu(dbProjekti, julkaisu);

userFixture.loginAsAdmin();
await api.tallennaProjekti({
oid,
kasittelynTila: {
hyvaksymispaatos: { asianumero: "asianro123", paatoksenPvm: "2022-06-09" }
},
});

userFixture.loginAs(UserFixture.mattiMeikalainen);
await loadProjektiFromDatabase(oid, Status.HYVAKSYMISMENETTELYSSA); // Verify status in yllapito

// Verify status in public
Expand Down Expand Up @@ -53,7 +65,10 @@ export async function testImportHyvaksymisPaatosAineistot(
ilmoituksenVastaanottajat: apiTestFixture.ilmoituksenVastaanottajat,
kuulutusYhteystiedot: apiTestFixture.esitettavatYhteystiedotInput,
kuulutusYhteysHenkilot: [projektiPaallikko],
hallintoOikeus: HallintoOikeus.HAMEENLINNA
hallintoOikeus: HallintoOikeus.HAMEENLINNA,

kuulutusPaiva: "2022-06-09",
kuulutusVaihePaattyyPaiva: "2100-01-01",
},
});

Expand Down Expand Up @@ -91,15 +106,20 @@ export async function testHyvaksymisPaatosVaiheApproval(
hyvaksymisPaatosVaiheJulkaisut: projekti.hyvaksymisPaatosVaiheJulkaisut.map(cleanupHyvaksymisPaatosVaiheTimestamps),
});

// TODO
// await testPublicAccessToProjekti(
// oid,
// Status.HYVAKSYMISMENETTELYSSA,
// userFixture,
// "HyvaksymisPaatosVaiheJulkinenAfterApproval",
// (projektiJulkinen) =>
// (projektiJulkinen.hyvaksymisPaatosVaihe = cleanupHyvaksymisPaatosVaiheJulkaisuJulkinenTimestamps(
// projektiJulkinen.hyvaksymisPaatosVaihe
// ))
// );
// Move hyvaksymisPaatosVaiheJulkaisu into the past
const dbProjekti = await projektiDatabase.loadProjektiByOid(oid);
const julkaisu = dbProjekti.hyvaksymisPaatosVaiheJulkaisut[0];
julkaisu.kuulutusVaihePaattyyPaiva = "2022-06-08";
await projektiDatabase.updateHyvaksymisPaatosVaiheJulkaisu(dbProjekti, julkaisu);

await testPublicAccessToProjekti(
oid,
Status.HYVAKSYTTY,
userFixture,
"HyvaksymisPaatosVaiheJulkinenAfterApproval",
(projektiJulkinen) =>
(projektiJulkinen.hyvaksymisPaatosVaihe = cleanupHyvaksymisPaatosVaiheJulkaisuJulkinenTimestamps(
projektiJulkinen.hyvaksymisPaatosVaihe
))
);
}
13 changes: 9 additions & 4 deletions backend/src/handler/projektiAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,20 +231,25 @@ export class ProjektiAdapter {
}

function checkSuunnittelu() {
if (projekti?.aloitusKuulutusJulkaisut) {
if (projekti.aloitusKuulutusJulkaisut) {
projekti.status = API.Status.SUUNNITTELU;
}
}

function checkNahtavillaolo() {
if (projekti?.suunnitteluVaihe?.julkinen) {
if (projekti.suunnitteluVaihe?.julkinen) {
projekti.status = API.Status.NAHTAVILLAOLO;
}
}

function checkHyvaksymisMenettelyssa() {
const nahtavillaoloVaihe = projekti?.nahtavillaoloVaiheJulkaisut?.filter(julkaisu => julkaisu.tila == NahtavillaoloVaiheTila.HYVAKSYTTY).pop();
if (isDateInThePast(nahtavillaoloVaihe?.kuulutusVaihePaattyyPaiva)) {
const hyvaksymisPaatos = projekti.kasittelynTila?.hyvaksymispaatos;
const hasHyvaksymisPaatos = hyvaksymisPaatos && hyvaksymisPaatos.asianumero && hyvaksymisPaatos.paatoksenPvm;

const nahtavillaoloVaihe = projekti.nahtavillaoloVaiheJulkaisut?.filter(julkaisu => julkaisu.tila == NahtavillaoloVaiheTila.HYVAKSYTTY).pop();
const nahtavillaoloKuulutusPaattyyInThePast = isDateInThePast(nahtavillaoloVaihe?.kuulutusVaihePaattyyPaiva);

if (hasHyvaksymisPaatos && nahtavillaoloKuulutusPaattyyInThePast) {
projekti.status = API.Status.HYVAKSYMISMENETTELYSSA;
}
}
Expand Down
87 changes: 82 additions & 5 deletions backend/src/handler/projektiAdapterJulkinen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
AloitusKuulutusPDF,
DBProjekti,
DBVaylaUser,
HyvaksymisPaatosVaiheJulkaisu,
LocalizedMap,
NahtavillaoloVaiheJulkaisu,
SuunnitteluSopimus,
Expand All @@ -12,7 +13,10 @@ import {
VuorovaikutusTilaisuus,
} from "../database/model";
import * as API from "../../../common/graphql/apiModel";
import { NahtavillaoloVaiheJulkaisuJulkinen } from "../../../common/graphql/apiModel";
import {
HyvaksymisPaatosVaiheJulkaisuJulkinen,
NahtavillaoloVaiheJulkaisuJulkinen
} from "../../../common/graphql/apiModel";
import pickBy from "lodash/pickBy";
import dayjs, { Dayjs } from "dayjs";
import {
Expand Down Expand Up @@ -65,6 +69,13 @@ class ProjektiAdapterJulkinen {
}
}

function checkHyvaksytty() {
const hyvaksymisPaatosVaihe = projekti.hyvaksymisPaatosVaihe;
if (isDateInThePast(hyvaksymisPaatosVaihe?.kuulutusPaiva)) {
projekti.status = API.Status.HYVAKSYTTY;
}
}

projekti.status = API.Status.EI_JULKAISTU;

checkAloituskuulutus();
Expand All @@ -75,7 +86,7 @@ class ProjektiAdapterJulkinen {

checkHyvaksymisMenettelyssa();

// checkPaatos();
checkHyvaksytty();

// checkLainvoima();

Expand All @@ -100,6 +111,8 @@ class ProjektiAdapterJulkinen {
}

const nahtavillaoloVaihe = ProjektiAdapterJulkinen.adaptNahtavillaoloVaiheJulkaisu(dbProjekti, projektiHenkilot);
const hyvaksymisPaatosVaihe = ProjektiAdapterJulkinen.adaptHyvaksymisPaatosVaihe(dbProjekti, projektiHenkilot);

const projekti: API.ProjektiJulkinen = {
__typename: "ProjektiJulkinen",
oid: dbProjekti.oid,
Expand All @@ -111,6 +124,7 @@ class ProjektiAdapterJulkinen {
paivitetty: dbProjekti.paivitetty,
projektiHenkilot: Object.values(projektiHenkilot),
nahtavillaoloVaihe,
hyvaksymisPaatosVaihe,
};
const projektiJulkinen = removeUndefinedFields(projekti) as API.ProjektiJulkinen;
return this.applyStatus(projektiJulkinen);
Expand Down Expand Up @@ -219,7 +233,7 @@ class ProjektiAdapterJulkinen {
const paths = new ProjektiPaths(dbProjekti.oid).nahtavillaoloVaihe(julkaisu);

let apiAineistoNahtavilla: API.Aineisto[];
if (!isNahtavillaoloVaiheOver(julkaisu)) {
if (!isKuulutusNahtavillaVaiheOver(julkaisu)) {
apiAineistoNahtavilla = adaptAineistotJulkinen(dbProjekti.oid, aineistoNahtavilla, paths);
}
return {
Expand All @@ -235,6 +249,46 @@ class ProjektiAdapterJulkinen {
};
}
}

private static adaptHyvaksymisPaatosVaihe(
dbProjekti: DBProjekti,
projektiHenkilot: ProjektiHenkilot,
): API.HyvaksymisPaatosVaiheJulkaisuJulkinen {
const julkaisu = pickExactlyOneHyvaksymisPaatosVaihe(dbProjekti.hyvaksymisPaatosVaiheJulkaisut);
if (julkaisu) {
const {
hyvaksymisPaatos,
aineistoNahtavilla,
kuulutusPaiva,
kuulutusVaihePaattyyPaiva,
kuulutusYhteysHenkilot,
kuulutusYhteystiedot,
velho,
kielitiedot,
hallintoOikeus,
} = julkaisu;
const paths = new ProjektiPaths(dbProjekti.oid).hyvaksymisPaatosVaihe(julkaisu);

let apiHyvaksymisPaatos: API.Aineisto[];
let apiAineistoNahtavilla: API.Aineisto[];
if (!isKuulutusNahtavillaVaiheOver(julkaisu)) {
apiHyvaksymisPaatos = adaptAineistotJulkinen(dbProjekti.oid, hyvaksymisPaatos, paths);
apiAineistoNahtavilla = adaptAineistotJulkinen(dbProjekti.oid, aineistoNahtavilla, paths);
}
return {
__typename: "HyvaksymisPaatosVaiheJulkaisuJulkinen",
hyvaksymisPaatos: apiHyvaksymisPaatos,
aineistoNahtavilla: apiAineistoNahtavilla,
kuulutusPaiva,
kuulutusVaihePaattyyPaiva,
kuulutusYhteysHenkilot: adaptUsernamesToProjektiHenkiloIds(kuulutusYhteysHenkilot, projektiHenkilot),
kuulutusYhteystiedot: adaptYhteystiedot(kuulutusYhteystiedot),
velho: adaptVelho(velho),
kielitiedot: adaptKielitiedot(kielitiedot),
hallintoOikeus,
};
}
}
}

function pickExactlyOneNahtavillaoloVaiheJulkaisu(
Expand All @@ -249,6 +303,29 @@ function pickExactlyOneNahtavillaoloVaiheJulkaisu(
}
}

function pickExactlyOneHyvaksymisPaatosVaihe(
hyvaksymisPaatosVaiheJulkaisut: HyvaksymisPaatosVaiheJulkaisu[],
): HyvaksymisPaatosVaiheJulkaisu | undefined {
const julkaisut = hyvaksymisPaatosVaiheJulkaisut?.filter(isHyvaksymisPaatosVaihePublic);
if (julkaisut) {
if (julkaisut.length > 1) {
throw new Error("Bug: vain yksi HyvaksymisPaatosVaiheJulkaisu voi olla julkinen kerrallaan");
}
return julkaisut.pop();
}
}

function isHyvaksymisPaatosVaihePublic(vaihe: HyvaksymisPaatosVaiheJulkaisu): boolean {
if (!vaihe) {
return false;
}
if (!vaihe.kuulutusPaiva || parseDate(vaihe.kuulutusPaiva).isAfter(dayjs())) {
return false;
}
return vaihe.tila === API.HyvaksymisPaatosVaiheTila.HYVAKSYTTY;
}


function isUnsetOrInPast(julkaisuPaiva: dayjs.Dayjs) {
return !julkaisuPaiva || julkaisuPaiva.isBefore(dayjs());
}
Expand Down Expand Up @@ -381,8 +458,8 @@ function isNahtavillaoloVaihePublic(nahtavillaoloVaihe: NahtavillaoloVaiheJulkai
return nahtavillaoloVaihe.tila === API.NahtavillaoloVaiheTila.HYVAKSYTTY;
}

function isNahtavillaoloVaiheOver(
nahtavillaoloVaihe: NahtavillaoloVaiheJulkaisu | NahtavillaoloVaiheJulkaisuJulkinen
function isKuulutusNahtavillaVaiheOver(
nahtavillaoloVaihe: NahtavillaoloVaiheJulkaisu | NahtavillaoloVaiheJulkaisuJulkinen | HyvaksymisPaatosVaiheJulkaisu | HyvaksymisPaatosVaiheJulkaisuJulkinen
): boolean {
return (
!nahtavillaoloVaihe.kuulutusVaihePaattyyPaiva ||
Expand Down
6 changes: 3 additions & 3 deletions backend/src/handler/projektiHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export async function arkistoiProjekti(oid: string): Promise<ArkistointiTunnus>

export async function createOrUpdateProjekti(input: TallennaProjektiInput): Promise<string> {
if (input.kasittelynTila) {
requireAdmin(); // Hyvaksymispaatoksia voi tallentaa vain Hasssun yllapitaja
requireAdmin("Hyvaksymispaatoksia voi tallentaa vain Hasssun yllapitaja");
}
requirePermissionLuku();
const oid = input.oid;
Expand Down Expand Up @@ -120,7 +120,7 @@ export async function createOrUpdateProjekti(input: TallennaProjektiInput): Prom
export async function createProjektiFromVelho(
oid: string,
vaylaUser: NykyinenKayttaja,
input?: TallennaProjektiInput
input?: TallennaProjektiInput,
): Promise<{ projekti: DBProjekti; virhetiedot?: API.ProjektipaallikkoVirhe }> {
try {
log.info("Loading projekti from Velho", { oid });
Expand Down Expand Up @@ -233,7 +233,7 @@ async function handleEvents(projektiAdaptationResult: ProjektiAdaptationResult)
ProjektiEventType.VUOROVAIKUTUS_PUBLISHED,
async (event: VuorovaikutusPublishedEvent, projekti: DBProjekti) => {
return vuorovaikutusService.handleVuorovaikutusKutsu(projekti.oid, event.vuorovaikutusNumero);
}
},
);
await projektiAdaptationResult.onEvent(ProjektiEventType.AINEISTO_CHANGED, async (_event, projekti) => {
return aineistoService.importAineisto(projekti.oid);
Expand Down
Loading

0 comments on commit 55983d8

Please sign in to comment.