diff --git a/backend/integrationtest/aloitusKuulutus/__snapshots__/aloitusKuulutusHandler.test.ts.snap b/backend/integrationtest/aloitusKuulutus/__snapshots__/aloitusKuulutusHandler.test.ts.snap index c9ab0eac2..151483195 100644 --- a/backend/integrationtest/aloitusKuulutus/__snapshots__/aloitusKuulutusHandler.test.ts.snap +++ b/backend/integrationtest/aloitusKuulutus/__snapshots__/aloitusKuulutusHandler.test.ts.snap @@ -75,11 +75,13 @@ Object { "muokkaaja": "A000111", "siirtyySuunnitteluVaiheeseen": "2022-01-01", "suunnitteluSopimus": Object { - "email": "Joku.Jossain@vayla.fi", - "etunimi": "Joku", + "__typename": "SuunnitteluSopimusJulkaisu", + "email": "Kunta.Kuntalainen@vayla.fi", + "etunimi": "Kunta", "kunta": "Nokia", - "puhelinnumero": "123", - "sukunimi": "Jossain", + "logo": "logo.gif", + "puhelinnumero": "123456789", + "sukunimi": "Kuntalainen", }, "tila": "ODOTTAA_HYVAKSYNTAA", "velho": Object { @@ -199,11 +201,13 @@ Object { "muokkaaja": "A000111", "siirtyySuunnitteluVaiheeseen": "2022-01-01", "suunnitteluSopimus": Object { - "email": "Joku.Jossain@vayla.fi", - "etunimi": "Joku", + "__typename": "SuunnitteluSopimusJulkaisu", + "email": "Kunta.Kuntalainen@vayla.fi", + "etunimi": "Kunta", "kunta": "Nokia", - "puhelinnumero": "123", - "sukunimi": "Jossain", + "logo": "logo.gif", + "puhelinnumero": "123456789", + "sukunimi": "Kuntalainen", }, "tila": "ODOTTAA_HYVAKSYNTAA", "velho": Object { @@ -297,11 +301,13 @@ Object { "muokkaaja": "A000111", "siirtyySuunnitteluVaiheeseen": "2022-01-01", "suunnitteluSopimus": Object { - "email": "Joku.Jossain@vayla.fi", - "etunimi": "Joku", + "__typename": "SuunnitteluSopimusJulkaisu", + "email": "Kunta.Kuntalainen@vayla.fi", + "etunimi": "Kunta", "kunta": "Nokia", - "puhelinnumero": "123", - "sukunimi": "Jossain", + "logo": "logo.gif", + "puhelinnumero": "123456789", + "sukunimi": "Kuntalainen", }, "tila": "HYVAKSYTTY", "velho": Object { diff --git a/backend/integrationtest/api/__snapshots__/api.test.ts.snap b/backend/integrationtest/api/__snapshots__/api.test.ts.snap index fbeb6abc6..448836d93 100644 --- a/backend/integrationtest/api/__snapshots__/api.test.ts.snap +++ b/backend/integrationtest/api/__snapshots__/api.test.ts.snap @@ -1198,13 +1198,13 @@ Object { "kuulutusPaiva": "2022-01-02", "siirtyySuunnitteluVaiheeseen": "2022-01-01", "suunnitteluSopimus": Object { - "__typename": "SuunnitteluSopimus", - "email": "Joku.Jossain@vayla.fi", - "etunimi": "Joku", + "__typename": "SuunnitteluSopimusJulkaisu", + "email": "mikko.haapamaki@cgi.com", + "etunimi": "Testi1", "kunta": "Nokia", "logo": "/tiedostot/suunnitelma/1.2.246.578.5.1.2978288874.2711575506/suunnittelusopimus/logo.png", "puhelinnumero": "123", - "sukunimi": "Jossain", + "sukunimi": "Hassu", }, "tila": "HYVAKSYTTY", "velho": Object { diff --git a/backend/integrationtest/api/apiTestFixture.ts b/backend/integrationtest/api/apiTestFixture.ts index 1b89cbc4a..9422acb65 100644 --- a/backend/integrationtest/api/apiTestFixture.ts +++ b/backend/integrationtest/api/apiTestFixture.ts @@ -19,23 +19,17 @@ import { class ApiTestFixture { newNote = "uusi muistiinpano"; - createSuunnitteluSopimusInput = (uploadedFile: string): SuunnitteluSopimusInput => ({ - email: "Joku.Jossain@vayla.fi", - puhelinnumero: "123", - etunimi: "Joku", - sukunimi: "Jossain", + createSuunnitteluSopimusInput = (uploadedFile: string, yhteysHenkilo:string): SuunnitteluSopimusInput => ({ + yhteysHenkilo, kunta: "Nokia", logo: uploadedFile, }); - suunnitteluSopimus: SuunnitteluSopimus = { + suunnitteluSopimus = (yhteysHenkilo:string): SuunnitteluSopimus => ({ __typename: "SuunnitteluSopimus", - email: "Joku.Jossain@vayla.fi", - puhelinnumero: "123", - etunimi: "Joku", - sukunimi: "Jossain", + yhteysHenkilo, kunta: "Nokia", - }; + }); yhteystietoLista: Yhteystieto[] = [ { @@ -48,7 +42,7 @@ class ApiTestFixture { }, ]; - yhteytietoInputLista2: YhteystietoInput[] = [ + yhteystietoInputLista2: YhteystietoInput[] = [ { etunimi: "Marko", sukunimi: "Koi", diff --git a/backend/integrationtest/api/records/HYVAKSYMISPAATOS_APPROVED.json b/backend/integrationtest/api/records/HYVAKSYMISPAATOS_APPROVED.json index 4db4110f9..ef092fc4b 100644 --- a/backend/integrationtest/api/records/HYVAKSYMISPAATOS_APPROVED.json +++ b/backend/integrationtest/api/records/HYVAKSYMISPAATOS_APPROVED.json @@ -32,12 +32,13 @@ "linkki": null }, "suunnitteluSopimus": { - "sukunimi": "Jossain", + "etunimi": "Testi1", + "__typename": "SuunnitteluSopimusJulkaisu", + "sukunimi": "Hassu", "logo": "/suunnittelusopimus/logo.png", "kunta": "Nokia", "puhelinnumero": "123", - "email": "Joku.Jossain@vayla.fi", - "etunimi": "Joku" + "email": "mikko.haapamaki@cgi.com" }, "siirtyySuunnitteluVaiheeseen": "2022-01-01", "kielitiedot": { @@ -97,12 +98,9 @@ "salt": "salt123", "tyyppi": "TIE", "suunnitteluSopimus": { - "sukunimi": "Jossain", + "yhteysHenkilo": "LX581241", "logo": "/suunnittelusopimus/logo.png", - "kunta": "Nokia", - "puhelinnumero": "123", - "email": "Joku.Jossain@vayla.fi", - "etunimi": "Joku" + "kunta": "Nokia" }, "velho": { "suunnittelustaVastaavaViranomainen": "VAYLAVIRASTO", diff --git a/backend/integrationtest/api/records/NAHTAVILLAOLO.json b/backend/integrationtest/api/records/NAHTAVILLAOLO.json index bbf31cc3a..56b896097 100644 --- a/backend/integrationtest/api/records/NAHTAVILLAOLO.json +++ b/backend/integrationtest/api/records/NAHTAVILLAOLO.json @@ -32,12 +32,13 @@ "linkki": null }, "suunnitteluSopimus": { - "sukunimi": "Jossain", + "etunimi": "Testi1", + "__typename": "SuunnitteluSopimusJulkaisu", + "sukunimi": "Hassu", "logo": "/suunnittelusopimus/logo.png", "kunta": "Nokia", "puhelinnumero": "123", - "email": "Joku.Jossain@vayla.fi", - "etunimi": "Joku" + "email": "mikko.haapamaki@cgi.com" }, "siirtyySuunnitteluVaiheeseen": "2022-01-01", "kielitiedot": { @@ -97,12 +98,9 @@ "salt": "salt123", "tyyppi": "TIE", "suunnitteluSopimus": { - "sukunimi": "Jossain", + "yhteysHenkilo": "LX581241", "logo": "/suunnittelusopimus/logo.png", - "kunta": "Nokia", - "puhelinnumero": "123", - "email": "Joku.Jossain@vayla.fi", - "etunimi": "Joku" + "kunta": "Nokia" }, "velho": { "suunnittelustaVastaavaViranomainen": "VAYLAVIRASTO", diff --git a/backend/integrationtest/api/testUtil/tests.ts b/backend/integrationtest/api/testUtil/tests.ts index fd08f403d..44f4e9c9a 100644 --- a/backend/integrationtest/api/testUtil/tests.ts +++ b/backend/integrationtest/api/testUtil/tests.ts @@ -140,7 +140,7 @@ export async function testProjektinTiedot(oid: string): Promise { oid, muistiinpano: apiTestFixture.newNote, aloitusKuulutus: apiTestFixture.aloitusKuulutus, - suunnitteluSopimus: apiTestFixture.createSuunnitteluSopimusInput(uploadedFile), + suunnitteluSopimus: apiTestFixture.createSuunnitteluSopimusInput(uploadedFile, UserFixture.testi1Kayttaja.uid), kielitiedot: apiTestFixture.kielitiedotInput, euRahoitus: false, }); diff --git a/backend/integrationtest/email/email.test.ts b/backend/integrationtest/email/email.test.ts index 67832a9c7..1304caa68 100644 --- a/backend/integrationtest/email/email.test.ts +++ b/backend/integrationtest/email/email.test.ts @@ -29,6 +29,7 @@ describe.skip("Email", () => { asiakirjaTyyppi: AsiakirjaTyyppi.ALOITUSKUULUTUS, kieli: Kieli.SUOMI, luonnos: false, + kayttoOikeudet: projekti.kayttoOikeudet, }); await emailClient.sendEmail({ diff --git a/backend/src/asiakirja/asiakirjaService.ts b/backend/src/asiakirja/asiakirjaService.ts index 231d1f30a..0702c7438 100644 --- a/backend/src/asiakirja/asiakirjaService.ts +++ b/backend/src/asiakirja/asiakirjaService.ts @@ -1,5 +1,11 @@ import { AsiakirjaTyyppi, Kieli, PDF, ProjektiTyyppi } from "../../../common/graphql/apiModel"; -import { AloitusKuulutusJulkaisu, DBProjekti, HyvaksymisPaatosVaiheJulkaisu, NahtavillaoloVaiheJulkaisu } from "../database/model"; +import { + AloitusKuulutusJulkaisu, + DBProjekti, + DBVaylaUser, + HyvaksymisPaatosVaiheJulkaisu, + NahtavillaoloVaiheJulkaisu, +} from "../database/model"; import { AloitusKuulutus10T } from "./suunnittelunAloitus/aloitusKuulutus10T"; import { AloitusKuulutus10R } from "./suunnittelunAloitus/aloitusKuulutus10R"; import { Ilmoitus12T } from "./suunnittelunAloitus/ilmoitus12T"; @@ -32,19 +38,20 @@ interface CreateNahtavillaoloKuulutusPdfOptions { asiakirjaTyyppi: NahtavillaoloKuulutusAsiakirjaTyyppi; } -interface YleisotilaisuusKutsuPdfOptions { +export type YleisotilaisuusKutsuPdfOptions = { projekti: DBProjekti; vuorovaikutus: Vuorovaikutus; kieli: Kieli; luonnos: boolean; -} +}; -interface AloituskuulutusPdfOptions { +export type AloituskuulutusPdfOptions = { aloitusKuulutusJulkaisu: AloitusKuulutusJulkaisu; asiakirjaTyyppi: AsiakirjaTyyppi; kieli: Kieli; luonnos: boolean; -} + kayttoOikeudet: DBVaylaUser[]; +}; export type EnhancedPDF = PDF & { textContent: string }; @@ -57,13 +64,13 @@ export type HyvaksymisPaatosKuulutusAsiakirjaTyyppi = Extract< | AsiakirjaTyyppi.ILMOITUS_HYVAKSYMISPAATOSKUULUTUKSESTA_MUISTUTTAJILLE >; -interface CreateHyvaksymisPaatosKuulutusPdfOptions { +type CreateHyvaksymisPaatosKuulutusPdfOptions = { projekti: DBProjekti; hyvaksymisPaatosVaihe: HyvaksymisPaatosVaiheJulkaisu; kieli: Kieli; luonnos: boolean; asiakirjaTyyppi: HyvaksymisPaatosKuulutusAsiakirjaTyyppi; -} +}; export enum AsiakirjanMuoto { TIE = "TIE", @@ -80,7 +87,13 @@ export function determineAsiakirjaMuoto(tyyppi: ProjektiTyyppi, vaylamuoto: stri } export class AsiakirjaService { - createAloituskuulutusPdf({ asiakirjaTyyppi, aloitusKuulutusJulkaisu, kieli, luonnos }: AloituskuulutusPdfOptions): Promise { + createAloituskuulutusPdf({ + asiakirjaTyyppi, + aloitusKuulutusJulkaisu, + kieli, + luonnos, + kayttoOikeudet, + }: AloituskuulutusPdfOptions): Promise { let pdf: Promise; if (!aloitusKuulutusJulkaisu.velho.tyyppi) { throw new Error("aloitusKuulutusJulkaisu.velho.tyyppi puuttuu"); @@ -109,6 +122,7 @@ export class AsiakirjaService { velho: aloitusKuulutusJulkaisu.velho, yhteystiedot: aloitusKuulutusJulkaisu.yhteystiedot, suunnitteluSopimus: aloitusKuulutusJulkaisu.suunnitteluSopimus, + kayttoOikeudet, }; switch (asiakirjaTyyppi) { diff --git a/backend/src/asiakirja/suunnittelunAloitus/Kutsu20.ts b/backend/src/asiakirja/suunnittelunAloitus/Kutsu20.ts index e3b943181..09e7859d0 100644 --- a/backend/src/asiakirja/suunnittelunAloitus/Kutsu20.ts +++ b/backend/src/asiakirja/suunnittelunAloitus/Kutsu20.ts @@ -1,4 +1,11 @@ -import { DBProjekti, DBVaylaUser, SuunnitteluSopimus, SuunnitteluVaihe, Vuorovaikutus, VuorovaikutusTilaisuus } from "../../database/model"; +import { + DBProjekti, + DBVaylaUser, + SuunnitteluSopimusJulkaisu, + SuunnitteluVaihe, + Vuorovaikutus, + VuorovaikutusTilaisuus, +} from "../../database/model"; import { KayttajaTyyppi, Kieli, ProjektiTyyppi, VuorovaikutusTilaisuusTyyppi } from "../../../../common/graphql/apiModel"; import { formatProperNoun } from "../../../../common/util/formatProperNoun"; import dayjs from "dayjs"; @@ -7,6 +14,8 @@ import { CommonPdf } from "./commonPdf"; import { AsiakirjanMuoto } from "../asiakirjaService"; import { translate } from "../../util/localization"; import { formatList, KutsuAdapter } from "./KutsuAdapter"; +import { adaptSuunnitteluSopimusToSuunnitteluSopimusJulkaisu } from "../../projekti/adapter/adaptToAPI"; +import { findUserByKayttajatunnus } from "../../projekti/projektiUtil"; import PDFStructureElement = PDFKit.PDFStructureElement; const headers: Record = { @@ -42,7 +51,7 @@ export class Kutsu20 extends CommonPdf { protected header: string; private projekti: DBProjekti; protected kieli: Kieli; - private suunnitteluSopimus: SuunnitteluSopimus; + private suunnitteluSopimus: SuunnitteluSopimusJulkaisu; constructor(projekti: DBProjekti, vuorovaikutus: Vuorovaikutus, kieli: Kieli, asiakirjanMuoto: AsiakirjanMuoto) { if (!(projekti.velho && projekti.velho.tyyppi && projekti.kielitiedot && projekti.suunnitteluSopimus && projekti.suunnitteluVaihe)) { @@ -65,7 +74,15 @@ export class Kutsu20 extends CommonPdf { this.kieli = kieli; this.kayttoOikeudet = projekti.kayttoOikeudet; - this.suunnitteluSopimus = projekti.suunnitteluSopimus; + const suunnitteluSopimus = adaptSuunnitteluSopimusToSuunnitteluSopimusJulkaisu( + projekti.oid, + projekti.suunnitteluSopimus, + findUserByKayttajatunnus(projekti.kayttoOikeudet, projekti.suunnitteluSopimus?.yhteysHenkilo) + ); + if (!suunnitteluSopimus) { + throw new Error("Suunnittelusopimus puuttuu"); + } + this.suunnitteluSopimus = suunnitteluSopimus; this.oid = projekti.oid; this.suunnitteluVaihe = projekti.suunnitteluVaihe; this.vuorovaikutus = vuorovaikutus; @@ -329,7 +346,7 @@ export class Kutsu20 extends CommonPdf { tilaisuus.esitettavatYhteystiedot?.yhteysHenkilot.forEach((kayttajatunnus) => { const user = this.kayttoOikeudet.filter((kayttaja) => kayttaja.kayttajatunnus == kayttajatunnus).pop(); if (user) { - const role = user.tyyppi == KayttajaTyyppi.PROJEKTIPAALLIKKO ? translate("rooli.PROJEKTIPAALLIKKO", this.kieli) : undefined; + const role = user.tyyppi == KayttajaTyyppi.PROJEKTIPAALLIKKO ? translate("rooli.PROJEKTIPAALLIKKO", this.kieli) : undefined; this.doc.text(safeConcatStrings(", ", [user.nimi, role, user.puhelinnumero])); } }); diff --git a/backend/src/asiakirja/suunnittelunAloitus/KutsuAdapter.ts b/backend/src/asiakirja/suunnittelunAloitus/KutsuAdapter.ts index b1d477bb7..6de2bf68b 100644 --- a/backend/src/asiakirja/suunnittelunAloitus/KutsuAdapter.ts +++ b/backend/src/asiakirja/suunnittelunAloitus/KutsuAdapter.ts @@ -1,5 +1,5 @@ import { KayttajaTyyppi, Kieli, ProjektiTyyppi, Viranomainen } from "../../../../common/graphql/apiModel"; -import { DBVaylaUser, Kielitiedot, SuunnitteluSopimus, Velho, Vuorovaikutus, Yhteystieto } from "../../database/model"; +import { DBVaylaUser, Kielitiedot, SuunnitteluSopimusJulkaisu, Velho, Vuorovaikutus, Yhteystieto } from "../../database/model"; import { AsiakirjanMuoto } from "../asiakirjaService"; import { translate } from "../../util/localization"; import { linkHyvaksymisPaatos, linkSuunnitteluVaihe } from "../../../../common/links"; @@ -236,7 +236,7 @@ export class KutsuAdapter { yhteystiedot( yhteystiedot: Yhteystieto[] | null | undefined, - suunnitteluSopimus?: SuunnitteluSopimus, + suunnitteluSopimus?: SuunnitteluSopimusJulkaisu, yhteysHenkilot?: string[] | null ): Yhteystieto[] { let yt: Yhteystieto[] = []; @@ -317,14 +317,15 @@ export class KutsuAdapter { } private getUsersForUsernames(usernames: string[]): DBVaylaUser[] { + const kayttoOikeudet = this.kayttoOikeudet; + if (!kayttoOikeudet) { + throw new Error("this.kayttooikeudet puuttuu"); + } // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return usernames .map((kayttajatunnus) => - // kayttoOikeudet on oltava - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - this.kayttoOikeudet + kayttoOikeudet .filter((kayttaja) => kayttaja.kayttajatunnus == kayttajatunnus || kayttaja.tyyppi == KayttajaTyyppi.PROJEKTIPAALLIKKO) .pop() ) diff --git a/backend/src/asiakirja/suunnittelunAloitus/aloitusKuulutus10T.ts b/backend/src/asiakirja/suunnittelunAloitus/aloitusKuulutus10T.ts index 5f23cac18..28e0368f1 100644 --- a/backend/src/asiakirja/suunnittelunAloitus/aloitusKuulutus10T.ts +++ b/backend/src/asiakirja/suunnittelunAloitus/aloitusKuulutus10T.ts @@ -79,9 +79,9 @@ export class AloitusKuulutus10T extends SuunnittelunAloitusPdf { let phrase: string; const suunnitteluSopimus = this.params.suunnitteluSopimus; if (suunnitteluSopimus) { - phrase = `${formatProperNoun(suunnitteluSopimus?.kunta || "Kunta")}, sovittuaan asiasta ${ - this.tilaajaGenetiivi - } kanssa, käynnistää ${this.projektiTyyppi}n laatimisen tarpeellisine tutkimuksineen. `; + phrase = `${formatProperNoun(suunnitteluSopimus?.kunta || "Kunta")}, sovittuaan asiasta ${this.tilaajaGenetiivi} kanssa, käynnistää ${ + this.projektiTyyppi + }n laatimisen tarpeellisine tutkimuksineen. `; } else { const tilaajaOrganisaatio = this.tilaajaOrganisaatio(); const kunnat = this.params.velho?.kunnat; diff --git a/backend/src/asiakirja/suunnittelunAloitus/commonPdf.ts b/backend/src/asiakirja/suunnittelunAloitus/commonPdf.ts index 1c0dc2ae7..fefc1c0f0 100644 --- a/backend/src/asiakirja/suunnittelunAloitus/commonPdf.ts +++ b/backend/src/asiakirja/suunnittelunAloitus/commonPdf.ts @@ -1,6 +1,6 @@ import { AbstractPdf } from "../abstractPdf"; import { Kieli, Viranomainen } from "../../../../common/graphql/apiModel"; -import { SuunnitteluSopimus, Velho, Yhteystieto } from "../../database/model"; +import { SuunnitteluSopimusJulkaisu, Velho, Yhteystieto } from "../../database/model"; import { KutsuAdapter } from "./KutsuAdapter"; import { log } from "../../logger"; import PDFStructureElement = PDFKit.PDFStructureElement; @@ -91,7 +91,7 @@ export abstract class CommonPdf extends AbstractPdf { protected moreInfoElements( yhteystiedot: Yhteystieto[] | null | undefined, - suunnitteluSopimus?: SuunnitteluSopimus, + suunnitteluSopimus?: SuunnitteluSopimusJulkaisu, yhteysHenkilot?: string[] | undefined | null, showOrganization = true ): PDFKit.PDFStructureElementChild[] { diff --git a/backend/src/asiakirja/suunnittelunAloitus/suunnittelunAloitusPdf.ts b/backend/src/asiakirja/suunnittelunAloitus/suunnittelunAloitusPdf.ts index fa49e00d0..09f668fa6 100644 --- a/backend/src/asiakirja/suunnittelunAloitus/suunnittelunAloitusPdf.ts +++ b/backend/src/asiakirja/suunnittelunAloitus/suunnittelunAloitusPdf.ts @@ -1,5 +1,5 @@ import { AsiakirjaTyyppi, Kieli, ProjektiTyyppi } from "../../../../common/graphql/apiModel"; -import { DBVaylaUser, Kielitiedot, LocalizedMap, SuunnitteluSopimus, Velho, Yhteystieto } from "../../database/model"; +import { DBVaylaUser, Kielitiedot, LocalizedMap, SuunnitteluSopimusJulkaisu, Velho, Yhteystieto } from "../../database/model"; import { CommonPdf } from "./commonPdf"; import { KutsuAdapter } from "./KutsuAdapter"; import { AsiakirjanMuoto } from "../asiakirjaService"; @@ -20,7 +20,7 @@ export type IlmoitusParams = { hankkeenKuvaus: LocalizedMap; kuulutusPaiva: string; yhteystiedot?: Yhteystieto[]; - suunnitteluSopimus?: SuunnitteluSopimus; + suunnitteluSopimus?: SuunnitteluSopimusJulkaisu; // kayttoOikeudet must be set if yhteysHenkilot is set yhteysHenkilot?: string[]; diff --git a/backend/src/database/model/projekti.ts b/backend/src/database/model/projekti.ts index a0451c02b..cbe89f62a 100644 --- a/backend/src/database/model/projekti.ts +++ b/backend/src/database/model/projekti.ts @@ -37,7 +37,7 @@ export type AloitusKuulutusJulkaisu = { elyKeskus?: string | null; yhteystiedot: Yhteystieto[]; velho: Velho; - suunnitteluSopimus?: SuunnitteluSopimus | null; + suunnitteluSopimus?: SuunnitteluSopimusJulkaisu | null; kielitiedot?: Kielitiedot | null; aloituskuulutusPDFt?: LocalizedMap; tila?: AloitusKuulutusTila | null; @@ -49,10 +49,16 @@ export type AloitusKuulutusJulkaisu = { export type SuunnitteluSopimus = { kunta: string; logo?: string; - etunimi: string; - sukunimi: string; - puhelinnumero: string; - email: string; + yhteysHenkilo: string; +}; + +export type SuunnitteluSopimusJulkaisu = { + kunta: string, + logo?: string | null, + etunimi: string, + sukunimi: string, + puhelinnumero: string, + email: string, }; export type Suunnitelma = { diff --git a/backend/src/handler/asiakirjaAdapter.ts b/backend/src/handler/asiakirjaAdapter.ts index 8097e24af..a74f915b8 100644 --- a/backend/src/handler/asiakirjaAdapter.ts +++ b/backend/src/handler/asiakirjaAdapter.ts @@ -3,7 +3,8 @@ import cloneDeep from "lodash/cloneDeep"; import { AloitusKuulutusTila, HyvaksymisPaatosVaiheTila, NahtavillaoloVaiheTila } from "../../../common/graphql/apiModel"; import { deepClone } from "aws-cdk/lib/util"; import adaptStandardiYhteystiedot from "../util/adaptStandardiYhteystiedot"; -import { findJulkaisuWithTila } from "../projekti/projektiUtil"; +import { findJulkaisuWithTila, findUserByKayttajatunnus } from "../projekti/projektiUtil"; +import { adaptSuunnitteluSopimusToSuunnitteluSopimusJulkaisu } from "../projekti/adapter/adaptToAPI"; function createNextAloitusKuulutusJulkaisuID(dbProjekti: DBProjekti) { if (!dbProjekti.aloitusKuulutusJulkaisut) { @@ -24,7 +25,11 @@ export class AsiakirjaAdapter { // @ts-ignore yhteystiedot: adaptStandardiYhteystiedot(dbProjekti, kuulutusYhteystiedot), velho: adaptVelho(dbProjekti), - suunnitteluSopimus: cloneDeep(dbProjekti.suunnitteluSopimus), + suunnitteluSopimus: adaptSuunnitteluSopimusToSuunnitteluSopimusJulkaisu( + dbProjekti.oid, + dbProjekti.suunnitteluSopimus, + findUserByKayttajatunnus(dbProjekti.kayttoOikeudet, dbProjekti.suunnitteluSopimus?.yhteysHenkilo) + ), kielitiedot: cloneDeep(dbProjekti.kielitiedot), }; } diff --git a/backend/src/handler/asiakirjaHandler.ts b/backend/src/handler/asiakirjaHandler.ts index 160aa1433..8cc86e57a 100644 --- a/backend/src/handler/asiakirjaHandler.ts +++ b/backend/src/handler/asiakirjaHandler.ts @@ -26,6 +26,7 @@ async function handleAloitusKuulutus( asiakirjaTyyppi, kieli, luonnos: true, + kayttoOikeudet: projekti.kayttoOikeudet }); } else { // Previewing projekti with unsaved changes. adaptProjektiToPreview combines database content with the user provided changes @@ -38,6 +39,7 @@ async function handleAloitusKuulutus( asiakirjaTyyppi, kieli, luonnos: true, + kayttoOikeudet: projekti.kayttoOikeudet }); } } diff --git a/backend/src/handler/tila/aloitusKuulutusTilaManager.ts b/backend/src/handler/tila/aloitusKuulutusTilaManager.ts index f3a776ca3..6f38686a6 100644 --- a/backend/src/handler/tila/aloitusKuulutusTilaManager.ts +++ b/backend/src/handler/tila/aloitusKuulutusTilaManager.ts @@ -1,7 +1,7 @@ import { AloitusKuulutusTila, AsiakirjaTyyppi, Kieli, NykyinenKayttaja } from "../../../../common/graphql/apiModel"; import { projektiDatabase } from "../../database/projektiDatabase"; import { asiakirjaAdapter } from "../asiakirjaAdapter"; -import { AloitusKuulutus, AloitusKuulutusJulkaisu, AloitusKuulutusPDF, DBProjekti, LocalizedMap, Kielitiedot } from "../../database/model"; +import { AloitusKuulutus, AloitusKuulutusJulkaisu, AloitusKuulutusPDF, DBProjekti, Kielitiedot, LocalizedMap } from "../../database/model"; import { asiakirjaService } from "../../asiakirja/asiakirjaService"; import { fileService } from "../../files/fileService"; import { parseDate } from "../../util/dateUtil"; @@ -21,6 +21,7 @@ async function createAloituskuulutusPDF( aloitusKuulutusJulkaisu: julkaisuWaitingForApproval, kieli, luonnos: false, + kayttoOikeudet: projekti.kayttoOikeudet, }); return fileService.createFileToProjekti({ oid: projekti.oid, diff --git a/backend/src/projekti/adapter/adaptToAPI/adaptAloitusKuulutus.ts b/backend/src/projekti/adapter/adaptToAPI/adaptAloitusKuulutus.ts index 0396207f7..d033f53e4 100644 --- a/backend/src/projekti/adapter/adaptToAPI/adaptAloitusKuulutus.ts +++ b/backend/src/projekti/adapter/adaptToAPI/adaptAloitusKuulutus.ts @@ -8,7 +8,7 @@ import { adaptStandardiYhteystiedotByAddingTypename, adaptVelhoByAddingTypename, } from "../common"; -import { adaptSuunnitteluSopimus } from "./adaptSuunitteluSopimus"; +import { adaptSuunnitteluSopimusJulkaisu } from "./adaptSuunitteluSopimus"; import { fileService } from "../../../files/fileService"; export function adaptAloitusKuulutus(kuulutus?: AloitusKuulutus | null): API.AloitusKuulutus | undefined { @@ -57,7 +57,7 @@ export function adaptAloitusKuulutusJulkaisut( hankkeenKuvaus: adaptHankkeenKuvaus(julkaisu.hankkeenKuvaus), yhteystiedot: adaptMandatoryYhteystiedotByAddingTypename(yhteystiedot), velho: adaptVelhoByAddingTypename(velho), - suunnitteluSopimus: adaptSuunnitteluSopimus(oid, suunnitteluSopimus), + suunnitteluSopimus: adaptSuunnitteluSopimusJulkaisu(oid, suunnitteluSopimus), kielitiedot: adaptKielitiedotByAddingTypename(kielitiedot), aloituskuulutusPDFt: adaptJulkaisuPDFPaths(oid, julkaisu.aloituskuulutusPDFt), }; diff --git a/backend/src/projekti/adapter/adaptToAPI/adaptSuunitteluSopimus.ts b/backend/src/projekti/adapter/adaptToAPI/adaptSuunitteluSopimus.ts index 5fdce8039..3e455c232 100644 --- a/backend/src/projekti/adapter/adaptToAPI/adaptSuunitteluSopimus.ts +++ b/backend/src/projekti/adapter/adaptToAPI/adaptSuunitteluSopimus.ts @@ -1,20 +1,89 @@ -import { SuunnitteluSopimus } from "../../../database/model"; +import { DBVaylaUser, SuunnitteluSopimus, SuunnitteluSopimusJulkaisu } from "../../../database/model"; import * as API from "../../../../../common/graphql/apiModel"; import { fileService } from "../../../files/fileService"; export function adaptSuunnitteluSopimus( oid: string, - suunnitteluSopimus?: SuunnitteluSopimus | null + suunnitteluSopimus: SuunnitteluSopimus | null | undefined ): API.SuunnitteluSopimus | undefined | null { if (suunnitteluSopimus) { if (!suunnitteluSopimus.logo) { throw new Error("adaptSuunnitteluSopimus: suunnitteluSopimus.logo määrittelemättä"); } + return { __typename: "SuunnitteluSopimus", - ...suunnitteluSopimus, + kunta: suunnitteluSopimus.kunta, + yhteysHenkilo: suunnitteluSopimus.yhteysHenkilo || "", // "" here to not break old test data because of missing value in mandatory field + logo: fileService.getYllapitoPathForProjektiFile(oid, suunnitteluSopimus.logo), + }; + } + return suunnitteluSopimus; +} + +export function adaptSuunnitteluSopimusJulkaisu( + oid: string, + suunnitteluSopimus: SuunnitteluSopimusJulkaisu | null | undefined +): API.SuunnitteluSopimusJulkaisu | undefined | null { + if (suunnitteluSopimus) { + if (!suunnitteluSopimus.logo) { + throw new Error("adaptSuunnitteluSopimus: suunnitteluSopimus.logo määrittelemättä"); + } + + return { + __typename: "SuunnitteluSopimusJulkaisu", + kunta: suunnitteluSopimus.kunta, logo: fileService.getYllapitoPathForProjektiFile(oid, suunnitteluSopimus.logo), + email: suunnitteluSopimus.email, + etunimi: suunnitteluSopimus.etunimi, + sukunimi: suunnitteluSopimus.sukunimi, + puhelinnumero: suunnitteluSopimus.puhelinnumero, + }; + } + return suunnitteluSopimus; +} + +export function adaptSuunnitteluSopimusJulkaisuJulkinen( + oid: string, + suunnitteluSopimus: SuunnitteluSopimusJulkaisu | null | undefined +): API.SuunnitteluSopimusJulkaisu | undefined | null { + if (suunnitteluSopimus) { + if (!suunnitteluSopimus.logo) { + throw new Error("adaptSuunnitteluSopimus: suunnitteluSopimus.logo määrittelemättä"); + } + + return { + __typename: "SuunnitteluSopimusJulkaisu", + kunta: suunnitteluSopimus.kunta, + logo: fileService.getPublicPathForProjektiFile(oid, suunnitteluSopimus.logo), + email: suunnitteluSopimus.email, + etunimi: suunnitteluSopimus.etunimi, + sukunimi: suunnitteluSopimus.sukunimi, + puhelinnumero: suunnitteluSopimus.puhelinnumero, + }; + } + return suunnitteluSopimus; +} + +export function adaptSuunnitteluSopimusToSuunnitteluSopimusJulkaisu( + oid: string, + suunnitteluSopimus: SuunnitteluSopimus | null | undefined, + yhteysHenkilo: DBVaylaUser | undefined +): API.SuunnitteluSopimusJulkaisu | undefined | null { + if (suunnitteluSopimus) { + if (!suunnitteluSopimus.logo) { + throw new Error("adaptSuunnitteluSopimus: suunnitteluSopimus.logo määrittelemättä"); + } + + return { + __typename: "SuunnitteluSopimusJulkaisu", + kunta: suunnitteluSopimus.kunta, + logo: suunnitteluSopimus.logo, + etunimi: yhteysHenkilo?.nimi.split(/, /g)[1] || "", + sukunimi: yhteysHenkilo?.nimi.split(/, /g)[0] || "", + email: yhteysHenkilo?.email || "", + puhelinnumero: yhteysHenkilo?.puhelinnumero || "", }; } - return suunnitteluSopimus as undefined | null; + return suunnitteluSopimus; } diff --git a/backend/src/projekti/adapter/projektiAdapterJulkinen.ts b/backend/src/projekti/adapter/projektiAdapterJulkinen.ts index 5cd4f0fe4..4ff251939 100644 --- a/backend/src/projekti/adapter/projektiAdapterJulkinen.ts +++ b/backend/src/projekti/adapter/projektiAdapterJulkinen.ts @@ -8,7 +8,6 @@ import { LocalizedMap, NahtavillaoloVaiheJulkaisu, StandardiYhteystiedot, - SuunnitteluSopimus, Velho, Vuorovaikutus, VuorovaikutusPDF, @@ -34,6 +33,7 @@ import { import { findJulkaisuWithTila } from "../projektiUtil"; import { applyProjektiJulkinenStatus } from "../status/projektiJulkinenStatusHandler"; import adaptStandardiYhteystiedot, { adaptStandardiYhteystiedotLisaamattaProjaria } from "../../util/adaptStandardiYhteystiedot"; +import { adaptSuunnitteluSopimusJulkaisuJulkinen } from "./adaptToAPI"; class ProjektiAdapterJulkinen { public adaptProjekti(dbProjekti: DBProjekti): API.ProjektiJulkinen | undefined { @@ -118,7 +118,7 @@ class ProjektiAdapterJulkinen { hankkeenKuvaus: adaptHankkeenKuvaus(julkaisu.hankkeenKuvaus), yhteystiedot: adaptMandatoryYhteystiedotByAddingTypename(yhteystiedot), velho: adaptVelho(velho), - suunnitteluSopimus: this.adaptSuunnitteluSopimus(oid, suunnitteluSopimus), + suunnitteluSopimus: adaptSuunnitteluSopimusJulkaisuJulkinen(oid, suunnitteluSopimus), kielitiedot: adaptKielitiedotByAddingTypename(kielitiedot), aloituskuulutusPDFt: this.adaptJulkaisuPDFPaths(oid, julkaisu.aloituskuulutusPDFt), tila: julkaisu.tila, @@ -128,20 +128,6 @@ class ProjektiAdapterJulkinen { return undefined; } - adaptSuunnitteluSopimus(oid: string, suunnitteluSopimus?: SuunnitteluSopimus | null): API.SuunnitteluSopimus | undefined | null { - if (suunnitteluSopimus) { - if (!suunnitteluSopimus.logo) { - throw new Error("adaptSuunnitteluSopimus: suunnittelusopimus.logo määrittelemättä"); - } - return { - __typename: "SuunnitteluSopimus", - ...suunnitteluSopimus, - logo: fileService.getPublicPathForProjektiFile(oid, suunnitteluSopimus.logo), - }; - } - return suunnitteluSopimus; - } - adaptJulkaisuPDFPaths(oid: string, aloitusKuulutusPDFS: LocalizedMap): API.AloitusKuulutusPDFt | undefined { if (!aloitusKuulutusPDFS) { return undefined; diff --git a/backend/src/projekti/projektiUtil.ts b/backend/src/projekti/projektiUtil.ts index c5d40e7e3..f7f5c4aa1 100644 --- a/backend/src/projekti/projektiUtil.ts +++ b/backend/src/projekti/projektiUtil.ts @@ -1,3 +1,5 @@ +import { DBVaylaUser } from "../database/model"; + export function findJulkaisutWithTila(julkaisut: (J & { tila?: T })[] | undefined | null, tila: T): J[] | undefined { return julkaisut?.filter((julkaisu) => julkaisu.tila == tila); } @@ -5,3 +7,10 @@ export function findJulkaisutWithTila(julkaisut: (J & { tila?: T })[] | un export function findJulkaisuWithTila(julkaisut: (J & { tila?: T })[] | undefined | null, tila: T): J | undefined { return findJulkaisutWithTila(julkaisut, tila)?.pop(); } + +export function findUserByKayttajatunnus(kayttoOikeudet: DBVaylaUser[], kayttajatunnus: string | undefined): DBVaylaUser | undefined { + if (!kayttajatunnus) { + return undefined; + } + return kayttoOikeudet.find((value) => value.kayttajatunnus == kayttajatunnus); +} diff --git a/backend/test/__snapshots__/apiHandler.test.ts.snap b/backend/test/__snapshots__/apiHandler.test.ts.snap index 7ab0ed25f..4785e0055 100644 --- a/backend/test/__snapshots__/apiHandler.test.ts.snap +++ b/backend/test/__snapshots__/apiHandler.test.ts.snap @@ -381,12 +381,9 @@ Array [ "oid": "1", "salt": "***unittest***", "suunnitteluSopimus": Object { - "email": "a@b.com", - "etunimi": "Etunimi", "kunta": "Nokia", "logo": "/suunnittelusopimus/logo.gif", - "puhelinnumero": "0291111", - "sukunimi": "Sukunimi", + "yhteysHenkilo": "A2", }, "suunnitteluVaihe": undefined, "vuorovaikutukset": undefined, @@ -499,12 +496,9 @@ Array [ "status": "ALOITUSKUULUTUS", "suunnitteluSopimus": Object { "__typename": "SuunnitteluSopimus", - "email": "a@b.com", - "etunimi": "Etunimi", "kunta": "Nokia", "logo": "/yllapito/tiedostot/projekti/1/suunnittelusopimus/logo.gif", - "puhelinnumero": "0291111", - "sukunimi": "Sukunimi", + "yhteysHenkilo": "A2", }, "tallennettu": true, "tyyppi": "TIE", @@ -796,13 +790,13 @@ Object { "muokkaaja": "A123", "siirtyySuunnitteluVaiheeseen": "2999-01-01", "suunnitteluSopimus": Object { - "__typename": "SuunnitteluSopimus", - "email": "a@b.com", - "etunimi": "Etunimi", + "__typename": "SuunnitteluSopimusJulkaisu", + "email": "a2@vayla.fi", + "etunimi": "EtunimiA2", "kunta": "Nokia", "logo": "/yllapito/tiedostot/projekti/1/suunnittelusopimus/logo.gif", - "puhelinnumero": "0291111", - "sukunimi": "Sukunimi", + "puhelinnumero": "123456789", + "sukunimi": "SukunimiA2", }, "tila": "HYVAKSYTTY", "velho": Object { @@ -875,12 +869,9 @@ Object { "status": "SUUNNITTELU", "suunnitteluSopimus": Object { "__typename": "SuunnitteluSopimus", - "email": "a@b.com", - "etunimi": "Etunimi", "kunta": "Nokia", "logo": "/yllapito/tiedostot/projekti/1/suunnittelusopimus/logo.gif", - "puhelinnumero": "0291111", - "sukunimi": "Sukunimi", + "yhteysHenkilo": "A2", }, "tallennettu": true, "tyyppi": "TIE", @@ -924,13 +915,13 @@ Object { "kuulutusPaiva": "2022-01-02", "siirtyySuunnitteluVaiheeseen": "2999-01-01", "suunnitteluSopimus": Object { - "__typename": "SuunnitteluSopimus", - "email": "a@b.com", - "etunimi": "Etunimi", + "__typename": "SuunnitteluSopimusJulkaisu", + "email": "a2@vayla.fi", + "etunimi": "EtunimiA2", "kunta": "Nokia", "logo": "/tiedostot/suunnitelma/1/suunnittelusopimus/logo.gif", - "puhelinnumero": "0291111", - "sukunimi": "Sukunimi", + "puhelinnumero": "123456789", + "sukunimi": "SukunimiA2", }, "tila": "HYVAKSYTTY", "velho": Object { diff --git a/backend/test/apiHandler.test.ts b/backend/test/apiHandler.test.ts index 1120d8065..5e6dd7d95 100644 --- a/backend/test/apiHandler.test.ts +++ b/backend/test/apiHandler.test.ts @@ -303,12 +303,9 @@ describe("apiHandler", () => { }, ], suunnitteluSopimus: { - email: "a@b.com", - puhelinnumero: "0291111", kunta: "Nokia", logo: "/suunnittelusopimus/logo.gif", - etunimi: "Etunimi", - sukunimi: "Sukunimi", + yhteysHenkilo: "A2", }, euRahoitus: false, // mandatory field for perustiedot aloitusKuulutus: fixture.aloitusKuulutusInput, diff --git a/backend/test/asiakirja/__snapshots__/asiakirjaService.test.ts.snap b/backend/test/asiakirja/__snapshots__/asiakirjaService.test.ts.snap index ecbe62485..5424dea52 100644 --- a/backend/test/asiakirja/__snapshots__/asiakirjaService.test.ts.snap +++ b/backend/test/asiakirja/__snapshots__/asiakirjaService.test.ts.snap @@ -32,7 +32,7 @@ Lisätietoja antavat Marko Koi, puh. 0293121213, markku.koi(at)koi.com Pekka Projari, puh. 123456789, pekka.projari(at)vayla.fi Matti Meikalainen, puh. 123456789, Matti.Meikalainen(at)vayla.fi -Joku Jossain, puh. 123, Joku.Jossain(at)vayla.fi +Kunta Kuntalainen, puh. 123456789, Kunta.Kuntalainen(at)vayla.fi Tervetuloa! Uudenmaan ELY-keskus LUONNOSLUONNOS", @@ -95,7 +95,7 @@ Mer information om planen Marko Koi, tel. 0293121213, markku.koi(at)koi.com Pekka Projari, tel. 123456789, pekka.projari(at)vayla.fi Matti Meikalainen, tel. 123456789, Matti.Meikalainen(at)vayla.fi -Joku Jossain, tel. 123, Joku.Jossain(at)vayla.fi +Kunta Kuntalainen, tel. 123456789, Kunta.Kuntalainen(at)vayla.fi Tervetuloa! RUOTSIKSI Uudenmaan ELY-keskus LUONNOSLUONNOS", @@ -158,7 +158,7 @@ Lisätietoja antavat Marko Koi, puh. 0293121213, markku.koi(at)koi.com Pekka Projari, puh. 123456789, pekka.projari(at)vayla.fi Matti Meikalainen, puh. 123456789, Matti.Meikalainen(at)vayla.fi -Joku Jossain, puh. 123, Joku.Jossain(at)vayla.fi +Kunta Kuntalainen, puh. 123456789, Kunta.Kuntalainen(at)vayla.fi Väylävirasto LUONNOSLUONNOS", } @@ -220,7 +220,7 @@ Mer information om planen Marko Koi, tel. 0293121213, markku.koi(at)koi.com Pekka Projari, tel. 123456789, pekka.projari(at)vayla.fi Matti Meikalainen, tel. 123456789, Matti.Meikalainen(at)vayla.fi -Joku Jossain, tel. 123, Joku.Jossain(at)vayla.fi +Kunta Kuntalainen, tel. 123456789, Kunta.Kuntalainen(at)vayla.fi Trafikledsverket LUONNOSLUONNOS", } @@ -1180,11 +1180,13 @@ Object { "kuulutusPaiva": "2022-01-02", "siirtyySuunnitteluVaiheeseen": "2022-01-01", "suunnitteluSopimus": Object { - "email": "Joku.Jossain@vayla.fi", - "etunimi": "Joku", + "__typename": "SuunnitteluSopimusJulkaisu", + "email": "Kunta.Kuntalainen@vayla.fi", + "etunimi": "Kunta", "kunta": "Nokia", - "puhelinnumero": "123", - "sukunimi": "Jossain", + "logo": "logo.gif", + "puhelinnumero": "123456789", + "sukunimi": "Kuntalainen", }, "velho": Object { "asiatunnusVayla": "A1", @@ -1245,7 +1247,7 @@ Väylävirasto käsittelee suunnitelman laatimiseen liittyen tarpeellisia henkil Lisätietoja antavat Väylävirasto, Pekka Projari, puh. 123456789, pekka.projari(at)vayla.fi Kajaani, Marko Koi, puh. 0293121213, markku.koi(at)koi.com -Nokia, Joku Jossain, puh. 123, Joku.Jossain(at)vayla.fi +Nokia, Kunta Kuntalainen, puh. 123456789, Kunta.Kuntalainen(at)vayla.fi Nokia LUONNOS", } @@ -1262,7 +1264,7 @@ Kuulutus julkaistaan 2.1.2022, Uudenmaan ELY-keskuksen tietoverkossa osoitteessa Lisätietoja antavat Väylävirasto, Pekka Projari, puh. 123456789, pekka.projari(at)vayla.fi Kajaani, Marko Koi, puh. 0293121213, markku.koi(at)koi.com -Nokia, Joku Jossain, puh. 123, Joku.Jossain(at)vayla.fi +Nokia, Kunta Kuntalainen, puh. 123456789, Kunta.Kuntalainen(at)vayla.fi LUONNOS", } `; @@ -1288,7 +1290,7 @@ RUOTSIKSI Väylävirasto behandlar personuppgifter som är nödvändiga för uta Mer information om planen Väylävirasto, Pekka Projari, tel. 123456789, pekka.projari(at)vayla.fi Kajaani, Marko Koi, tel. 0293121213, markku.koi(at)koi.com -Nokia, Joku Jossain, tel. 123, Joku.Jossain(at)vayla.fi +Nokia, Kunta Kuntalainen, tel. 123456789, Kunta.Kuntalainen(at)vayla.fi Nokia LUONNOS", } @@ -1305,7 +1307,7 @@ RUOTSIKSI Kuulutus julkaistaan 2.1.2022, RUOTSIKSI Uudenmaan ELY-keskuksen tieto Mer information om planen Väylävirasto, Pekka Projari, tel. 123456789, pekka.projari(at)vayla.fi Kajaani, Marko Koi, tel. 0293121213, markku.koi(at)koi.com -Nokia, Joku Jossain, tel. 123, Joku.Jossain(at)vayla.fi +Nokia, Kunta Kuntalainen, tel. 123456789, Kunta.Kuntalainen(at)vayla.fi LUONNOS", } `; diff --git a/backend/test/asiakirja/asiakirjaService.test.ts b/backend/test/asiakirja/asiakirjaService.test.ts index b655ca736..a43fc5d1f 100644 --- a/backend/test/asiakirja/asiakirjaService.test.ts +++ b/backend/test/asiakirja/asiakirjaService.test.ts @@ -2,6 +2,7 @@ /* tslint:disable:only-arrow-functions */ import { describe, it } from "mocha"; import { + AloituskuulutusPdfOptions, AsiakirjaService, HyvaksymisPaatosKuulutusAsiakirjaTyyppi, NahtavillaoloKuulutusAsiakirjaTyyppi, @@ -21,6 +22,7 @@ import { ProjektiFixture } from "../fixture/projektiFixture"; import { AloitusKuulutusJulkaisu, DBProjekti, + DBVaylaUser, HyvaksymisPaatosVaihe, NahtavillaoloVaihe, SuunnitteluVaihe, @@ -60,14 +62,17 @@ describe("asiakirjaService", async () => { async function testKuulutusWithLanguage( aloitusKuulutusJulkaisu: AloitusKuulutusJulkaisu, kieli: Kieli, + kayttoOikeudet: DBVaylaUser[], asiakirjaTyyppi: AsiakirjaTyyppi ) { - const pdf = await new AsiakirjaService().createAloituskuulutusPdf({ + let aloituskuulutusPdfOptions: AloituskuulutusPdfOptions = { aloitusKuulutusJulkaisu, asiakirjaTyyppi, kieli, luonnos: true, - }); + kayttoOikeudet, + }; + const pdf = await new AsiakirjaService().createAloituskuulutusPdf(aloituskuulutusPdfOptions); expect(pdf.sisalto.length).to.be.greaterThan(50000); expectPDF("esikatselu_aloituskuulutus_", pdf); } @@ -80,15 +85,17 @@ describe("asiakirjaService", async () => { await runTestWithTypes( aloitusKuulutusTypes, - async (type) => await testKuulutusWithLanguage(aloitusKuulutusJulkaisu, Kieli.SUOMI, type) + async (type) => await testKuulutusWithLanguage(aloitusKuulutusJulkaisu, Kieli.SUOMI, projekti.kayttoOikeudet, type) ); await runTestWithTypes( aloitusKuulutusTypes, - async (type) => await testKuulutusWithLanguage(aloitusKuulutusJulkaisu, Kieli.RUOTSI, type) + async (type) => await testKuulutusWithLanguage(aloitusKuulutusJulkaisu, Kieli.RUOTSI, projekti.kayttoOikeudet, type) ); - await assert.isRejected(testKuulutusWithLanguage(aloitusKuulutusJulkaisu, Kieli.SAAME, AsiakirjaTyyppi.ALOITUSKUULUTUS)); + await assert.isRejected( + testKuulutusWithLanguage(aloitusKuulutusJulkaisu, Kieli.SAAME, projekti.kayttoOikeudet, AsiakirjaTyyppi.ALOITUSKUULUTUS) + ); }); async function testKutsuWithLanguage( diff --git a/backend/test/database/__snapshots__/projektiDatabase.test.ts.snap b/backend/test/database/__snapshots__/projektiDatabase.test.ts.snap index 9def04d70..beeae9dbf 100644 --- a/backend/test/database/__snapshots__/projektiDatabase.test.ts.snap +++ b/backend/test/database/__snapshots__/projektiDatabase.test.ts.snap @@ -52,6 +52,20 @@ Object { "organisaatio": "Väylävirasto", "puhelinnumero": "123456789", }, + Object { + "email": "Matti.Meikalainen@vayla.fi", + "kayttajatunnus": "A000111", + "nimi": "Meikalainen, Matti", + "organisaatio": "Väylävirasto", + "puhelinnumero": "123456789", + }, + Object { + "email": "Kunta.Kuntalainen@vayla.fi", + "kayttajatunnus": "A000123", + "nimi": "Kuntalainen, Kunta", + "organisaatio": "Nokia", + "puhelinnumero": "123456789", + }, ], ":kielitiedot": Object { "ensisijainenKieli": "SUOMI", @@ -67,11 +81,9 @@ Object { ":muistiinpano": "Testiprojekti 1:n muistiinpano", ":paivitetty": "2022-03-15T14:29:48.845Z", ":suunnitteluSopimus": Object { - "email": "Joku.Jossain@vayla.fi", - "etunimi": "Joku", "kunta": "Nokia", - "puhelinnumero": "123", - "sukunimi": "Jossain", + "logo": "logo.gif", + "yhteysHenkilo": "A000123", }, ":velho": Object { "asiatunnusVayla": "A1", diff --git a/backend/test/fixture/projektiFixture.ts b/backend/test/fixture/projektiFixture.ts index 09c4bb583..33a5e29ff 100644 --- a/backend/test/fixture/projektiFixture.ts +++ b/backend/test/fixture/projektiFixture.ts @@ -117,6 +117,16 @@ export class ProjektiFixture { puhelinnumero: "123456789", }; + private static kunnanYhteysHenkiloProjektiKayttaja: ProjektiKayttaja = { + __typename: "ProjektiKayttaja", + kayttajatunnus: "A000123", + muokattavissa: true, + nimi: "Kuntalainen, Kunta", + email: "Kunta.Kuntalainen@vayla.fi", + organisaatio: "Nokia", + puhelinnumero: "123456789", + }; + tallennaProjektiInput: TallennaProjektiInput = { oid: this.PROJEKTI1_OID, }; @@ -203,6 +213,20 @@ export class ProjektiFixture { puhelinnumero: ProjektiFixture.mattiMeikalainenProjektiKayttaja.puhelinnumero || "", organisaatio: ProjektiFixture.mattiMeikalainenProjektiKayttaja.organisaatio, }, + { + email: ProjektiFixture.mattiMeikalainenProjektiKayttaja.email, + kayttajatunnus: ProjektiFixture.mattiMeikalainenProjektiKayttaja.kayttajatunnus, + nimi: ProjektiFixture.mattiMeikalainenProjektiKayttaja.nimi, + puhelinnumero: ProjektiFixture.mattiMeikalainenProjektiKayttaja.puhelinnumero || "", + organisaatio: ProjektiFixture.mattiMeikalainenProjektiKayttaja.organisaatio, + }, + { + email: ProjektiFixture.kunnanYhteysHenkiloProjektiKayttaja.email, + kayttajatunnus: ProjektiFixture.kunnanYhteysHenkiloProjektiKayttaja.kayttajatunnus, + nimi: ProjektiFixture.kunnanYhteysHenkiloProjektiKayttaja.nimi, + puhelinnumero: ProjektiFixture.kunnanYhteysHenkiloProjektiKayttaja.puhelinnumero || "", + organisaatio: ProjektiFixture.kunnanYhteysHenkiloProjektiKayttaja.organisaatio, + }, ], oid: this.PROJEKTI1_OID, velho: { @@ -216,11 +240,9 @@ export class ProjektiFixture { }, muistiinpano: this.PROJEKTI1_MUISTIINPANO_1, suunnitteluSopimus: { - email: "Joku.Jossain@vayla.fi", - puhelinnumero: "123", - etunimi: "Joku", - sukunimi: "Jossain", kunta: "Nokia", + yhteysHenkilo: ProjektiFixture.kunnanYhteysHenkiloProjektiKayttaja.kayttajatunnus, + logo: "logo.gif", }, aloitusKuulutus: { kuulutusPaiva: "2022-01-02", diff --git a/backend/test/projekti/__snapshots__/projektiHandler.test.ts.snap b/backend/test/projekti/__snapshots__/projektiHandler.test.ts.snap index f8cf2f882..992bac6ba 100644 --- a/backend/test/projekti/__snapshots__/projektiHandler.test.ts.snap +++ b/backend/test/projekti/__snapshots__/projektiHandler.test.ts.snap @@ -22,6 +22,20 @@ Object { "organisaatio": "Väylävirasto", "puhelinnumero": "123456789", }, + Object { + "email": "Matti.Meikalainen@vayla.fi", + "kayttajatunnus": "A000111", + "nimi": "Meikalainen, Matti", + "organisaatio": "Väylävirasto", + "puhelinnumero": "123456789", + }, + Object { + "email": "Kunta.Kuntalainen@vayla.fi", + "kayttajatunnus": "A000123", + "nimi": "Kuntalainen, Kunta", + "organisaatio": "Nokia", + "puhelinnumero": "123456789", + }, Object { "email": "a1@vayla.fi", "kayttajatunnus": "A1", diff --git a/cypress/integration/2-perusta-projekti/3-perustiedot.spec.js b/cypress/integration/2-perusta-projekti/3-perustiedot.spec.js index 9d9813f71..7e10c4439 100644 --- a/cypress/integration/2-perusta-projekti/3-perustiedot.spec.js +++ b/cypress/integration/2-perusta-projekti/3-perustiedot.spec.js @@ -37,10 +37,7 @@ describe("Projektin perustiedot", () => { cy.get('input[name="suunnittelusopimusprojekti"][value="true"]').check(); cy.get("#suunnittelusopimus_kunta").select("ALAJÄRVI"); - cy.get("#suunnittelusopimus_etunimi").clear().type("Etunimialajärvi"); - cy.get("#suunnittelusopimus_sukunimi").clear().type("Sukunimialajärvi"); - cy.get("#suunnittelusopimus_puhelinnumero").clear().type("029222222222222"); - cy.get("#suunnittelusopimus_sahkoposti").clear().type("test@vayla.fi"); + cy.get("#suunnittelusopimus_yhteyshenkilo").select(1); cy.get("main").then((elem) => { let htmlElements = elem.find('[name="suunnittelusopimus_logo_trash_button"]'); diff --git a/graphql/inputs.graphql b/graphql/inputs.graphql index bfca34683..b4d8a072f 100644 --- a/graphql/inputs.graphql +++ b/graphql/inputs.graphql @@ -72,10 +72,7 @@ input KuntaVastaanottajaInput { input SuunnitteluSopimusInput { kunta: String! logo: String - etunimi: String! - sukunimi: String! - puhelinnumero: String! - email: String! + yhteysHenkilo: String! } input SuunnitteluVaiheInput { diff --git a/graphql/types.graphql b/graphql/types.graphql index 1cce50e36..d0654afca 100644 --- a/graphql/types.graphql +++ b/graphql/types.graphql @@ -564,7 +564,7 @@ type AloitusKuulutusJulkaisu { hankkeenKuvaus: HankkeenKuvaukset yhteystiedot: [Yhteystieto!]! velho: Velho! - suunnitteluSopimus: SuunnitteluSopimus + suunnitteluSopimus: SuunnitteluSopimusJulkaisu kielitiedot: Kielitiedot aloituskuulutusPDFt: AloitusKuulutusPDFt tila: AloitusKuulutusTila @@ -579,7 +579,7 @@ type AloitusKuulutusJulkaisuJulkinen { hankkeenKuvaus: HankkeenKuvaukset yhteystiedot: [Yhteystieto!]! velho: VelhoJulkinen! - suunnitteluSopimus: SuunnitteluSopimus + suunnitteluSopimus: SuunnitteluSopimusJulkaisu kielitiedot: Kielitiedot aloituskuulutusPDFt: AloitusKuulutusPDFt tila: AloitusKuulutusTila @@ -608,6 +608,12 @@ type KuntaVastaanottaja { } type SuunnitteluSopimus { + kunta: String! + logo: String + yhteysHenkilo: String! +} + +type SuunnitteluSopimusJulkaisu { kunta: String! logo: String etunimi: String! diff --git a/renovate.json b/renovate.json index 9a46ee1c7..8c7b25a7f 100644 --- a/renovate.json +++ b/renovate.json @@ -8,7 +8,7 @@ "workarounds:all" ], "timezone": "Europe/Helsinki", - "schedule": "after 6am and before 7am", + "schedule": "after 9pm on sunday", "updateNotScheduled": false, "branchConcurrentLimit": 5, "prConcurrentLimit": 5, diff --git a/src/components/projekti/ProjektiSunnittelusopimusTiedot.tsx b/src/components/projekti/ProjektiSunnittelusopimusTiedot.tsx index 628699e4f..011bc39bd 100644 --- a/src/components/projekti/ProjektiSunnittelusopimusTiedot.tsx +++ b/src/components/projekti/ProjektiSunnittelusopimusTiedot.tsx @@ -1,14 +1,12 @@ -import React, { ReactElement, useEffect, useState, useCallback } from "react"; +import React, { ReactElement, useCallback, useEffect, useState } from "react"; import { Projekti } from "@services/api"; import RadioButton from "@components/form/RadioButton"; -import TextInput from "@components/form/TextInput"; import Select from "@components/form/Select"; import { Controller, useFormContext } from "react-hook-form"; import { FormValues } from "@pages/yllapito/projekti/[oid]"; import FileInput from "@components/form/FileInput"; import IconButton from "@components/button/IconButton"; import FormGroup from "@components/form/FormGroup"; -import { maxPhoneLength } from "src/schemas/puhelinNumero"; import Section from "@components/layout/Section"; import HassuGrid from "@components/HassuGrid"; import SectionContent from "@components/layout/SectionContent"; @@ -27,7 +25,7 @@ export default function ProjektiPerustiedot({ projekti }: Props): ReactElement { setValue, } = useFormContext(); - const [hasSuunnittaluSopimus, setHasSuunnitteluSopimus] = useState(false); + const [hasSuunnitteluSopimus, setHasSuunnitteluSopimus] = useState(false); const [logoUrl, setLogoUrl] = useState(undefined); const [kuntaOptions, setKuntaOptions] = useState([]); @@ -45,6 +43,10 @@ export default function ProjektiPerustiedot({ projekti }: Props): ReactElement { setLogoUrl(projekti?.suunnitteluSopimus?.logo || undefined); }, [projekti, setHasSuunnitteluSopimus, setLogoUrl]); + if (!kuntaOptions || kuntaOptions.length == 0) { + return <>; + } + return (

Suunnittelusopimus

@@ -70,11 +72,24 @@ export default function ProjektiPerustiedot({ projekti }: Props): ReactElement { }} /> - {hasSuunnittaluSopimus && ( + {hasSuunnitteluSopimus && (

Kunnan projektipäällikön tiedot

+ - - - -
logoUrl ? ( - + - Suunnittelu sopimus logo + Suunnittelu sopimus logo ( - {projekti?.suunnitteluSopimus && ( - - )} {projekti.kayttoOikeudet?.map(({ nimi, tyyppi, kayttajatunnus }, index) => { const tunnuslista: string[] = value || []; return ( diff --git a/src/components/projekti/hyvaksyminen/kuulutuksenTiedot/KuulutuksessaEsitettavatYhteystiedot.tsx b/src/components/projekti/hyvaksyminen/kuulutuksenTiedot/KuulutuksessaEsitettavatYhteystiedot.tsx index ae72889e3..eb1ccdfa0 100644 --- a/src/components/projekti/hyvaksyminen/kuulutuksenTiedot/KuulutuksessaEsitettavatYhteystiedot.tsx +++ b/src/components/projekti/hyvaksyminen/kuulutuksenTiedot/KuulutuksessaEsitettavatYhteystiedot.tsx @@ -104,13 +104,6 @@ export default function EsitettavatYhteystiedot({}: Props): ReactElement { name={`hyvaksymisPaatosVaihe.kuulutusYhteysHenkilot`} render={({ field: { onChange, value, ...field } }) => ( - {projekti?.suunnitteluSopimus && ( - - )} {projekti.kayttoOikeudet?.map(({ nimi, tyyppi, kayttajatunnus }, index) => { const tunnuslista: string[] = value || []; return ( diff --git a/src/components/projekti/nahtavillaolo/kuulutuksentiedot/KuulutuksessaEsitettavatYhteystiedot.tsx b/src/components/projekti/nahtavillaolo/kuulutuksentiedot/KuulutuksessaEsitettavatYhteystiedot.tsx index d125e27d5..c8e305461 100644 --- a/src/components/projekti/nahtavillaolo/kuulutuksentiedot/KuulutuksessaEsitettavatYhteystiedot.tsx +++ b/src/components/projekti/nahtavillaolo/kuulutuksentiedot/KuulutuksessaEsitettavatYhteystiedot.tsx @@ -99,13 +99,6 @@ export default function EsitettavatYhteystiedot({}: Props): ReactElement { name={`nahtavillaoloVaihe.kuulutusYhteysHenkilot`} render={({ field: { onChange, value, ...field } }) => ( - {projekti?.suunnitteluSopimus && ( - - )} {projekti.kayttoOikeudet?.map(({ nimi, tyyppi, kayttajatunnus }, index) => { const tunnuslista: string[] = value || []; return ( diff --git a/src/components/projekti/suunnitteluvaihe/EsitettavatYhteystiedot.tsx b/src/components/projekti/suunnitteluvaihe/EsitettavatYhteystiedot.tsx index 96cd04aa9..5fce075b7 100644 --- a/src/components/projekti/suunnitteluvaihe/EsitettavatYhteystiedot.tsx +++ b/src/components/projekti/suunnitteluvaihe/EsitettavatYhteystiedot.tsx @@ -2,7 +2,7 @@ import { Controller, useFieldArray, useFormContext } from "react-hook-form"; import SectionContent from "@components/layout/SectionContent"; import { KayttajaTyyppi, YhteystietoInput } from "@services/api"; import Section from "@components/layout/Section"; -import { ReactElement, useMemo, Fragment } from "react"; +import { Fragment, ReactElement, useMemo } from "react"; import Button from "@components/button/Button"; import HassuStack from "@components/layout/HassuStack"; import CheckBox from "@components/form/CheckBox"; @@ -98,13 +98,6 @@ export default function EsitettavatYhteystiedot({ vuorovaikutusnro }: Props): Re ); })} - {projekti?.suunnitteluSopimus && ( - - )} )} /> diff --git a/src/pages/suunnitelma/[oid]/suunnittelu.tsx b/src/pages/suunnitelma/[oid]/suunnittelu.tsx index 8ad47d21f..8d0119995 100644 --- a/src/pages/suunnitelma/[oid]/suunnittelu.tsx +++ b/src/pages/suunnitelma/[oid]/suunnittelu.tsx @@ -11,7 +11,7 @@ import LocationCityIcon from "@mui/icons-material/LocationCity"; import LocalPhoneIcon from "@mui/icons-material/LocalPhone"; import { ProjektiJulkinen, - SuunnitteluSopimus, + SuunnitteluSopimusJulkaisu, SuunnitteluVaiheJulkinen, VuorovaikutusJulkinen, VuorovaikutusTilaisuusJulkinen, @@ -81,7 +81,7 @@ const VuorovaikutusTiedot: FC<{ vuorovaikutus: VuorovaikutusJulkinen | undefined; projekti: ProjektiJulkinen; suunnitteluVaihe: SuunnitteluVaiheJulkinen; - suunnittelusopimus: SuunnitteluSopimus | null | undefined; + suunnittelusopimus: SuunnitteluSopimusJulkaisu | null | undefined; projektiOid: string; }> = ({ suunnittelusopimus, vuorovaikutus, projektiOid }) => { const [palauteLomakeOpen, setPalauteLomakeOpen] = useState(false); diff --git a/src/pages/yllapito/projekti/[oid]/index.tsx b/src/pages/yllapito/projekti/[oid]/index.tsx index 0aca11f29..22fa54f5a 100644 --- a/src/pages/yllapito/projekti/[oid]/index.tsx +++ b/src/pages/yllapito/projekti/[oid]/index.tsx @@ -89,8 +89,8 @@ function ProjektiSivuLomake({ projekti, projektiLoadError, reloadProjekti }: Pro const { __typename, ...suunnitelmaInput } = suunnitelma; return suunnitelmaInput; }) || [], - suunnittelusopimusprojekti: projekti.status === Status.EI_JULKAISTU ? null : projekti.suunnitteluSopimus ? "true" : "false", - liittyviasuunnitelmia: projekti.status === Status.EI_JULKAISTU ? null : projekti.liittyvatSuunnitelmat?.length ? "true" : "false", + suunnittelusopimusprojekti: projekti.status === Status.EI_JULKAISTU_PROJEKTIN_HENKILOT ? null : projekti.suunnitteluSopimus ? "true" : "false", + liittyviasuunnitelmia: projekti.status === Status.EI_JULKAISTU_PROJEKTIN_HENKILOT ? null : projekti.liittyvatSuunnitelmat?.length ? "true" : "false", }; if (projekti.kielitiedot) { const { __typename, ...kielitiedotInput } = projekti.kielitiedot; diff --git a/src/schemas/perustiedot.ts b/src/schemas/perustiedot.ts index ad84aa39f..6e688991e 100644 --- a/src/schemas/perustiedot.ts +++ b/src/schemas/perustiedot.ts @@ -1,5 +1,4 @@ import * as Yup from "yup"; -import { puhelinNumeroSchema } from "./puhelinNumero"; export const maxNoteLength = 2000; @@ -30,17 +29,11 @@ export const perustiedotValidationSchema = Yup.object().shape({ .nullable() .default(null), euRahoitus: Yup.boolean().nullable().required("EU-rahoitustieto on pakollinen"), - muistiinpano: Yup.string().max( - maxNoteLength, - `Muistiinpanoon voidaan kirjoittaa maksimissaan ${maxNoteLength} merkkiä.` - ), + muistiinpano: Yup.string().max(maxNoteLength, `Muistiinpanoon voidaan kirjoittaa maksimissaan ${maxNoteLength} merkkiä.`), suunnitteluSopimus: Yup.object() .shape({ kunta: Yup.string().required("Kunta on pakollinen"), - etunimi: Yup.string().required("Etunimi on pakollinen"), - sukunimi: Yup.string().required("Sukunimi on pakollinen"), - puhelinnumero: puhelinNumeroSchema, - email: Yup.string().email("Virheellinen sähköpostiosoite").required("Sähköpostiosoite on pakollinen"), + yhteysHenkilo: Yup.string().required("Yhteyshenkilö on pakollinen").min(1), logo: Yup.mixed().required("Logo on pakollinen."), }) .notRequired() diff --git a/src/services/api/fragmentTypes.json b/src/services/api/fragmentTypes.json index 0c1d1696b..f9c880ae1 100644 --- a/src/services/api/fragmentTypes.json +++ b/src/services/api/fragmentTypes.json @@ -595,6 +595,12 @@ "possibleTypes": null, "__typename": "__Type" }, + { + "kind": "OBJECT", + "name": "SuunnitteluSopimusJulkaisu", + "possibleTypes": null, + "__typename": "__Type" + }, { "kind": "OBJECT", "name": "SuunnitteluVaihe",