diff --git a/.env.production b/.env.production index 1afdc9f9..f75e9c7d 100644 --- a/.env.production +++ b/.env.production @@ -19,6 +19,7 @@ MAIL_TLS=true MAIL_ENABLED=true SUPPORT_MAIL=monpsysante@fabrique.social.gouv.fr +REPORTING_MAIL_RECIPIENTS= API_ADRESSE_URL=https://api-adresse.data.gouv.fr/search GITGUARDIAN_API_KEY= diff --git a/.env.staging b/.env.staging index 629fb97f..0f788bcf 100644 --- a/.env.staging +++ b/.env.staging @@ -17,6 +17,7 @@ MAIL_TLS=true MAIL_ENABLED=true SUPPORT_MAIL=monpsysante@fabrique.social.gouv.fr +REPORTING_MAIL_RECIPIENTS= API_ADRESSE_URL=https://api-adresse.data.gouv.fr/search GITGUARDIAN_API_KEY= diff --git a/.kube-workflow/preprod/templates/app.sealed-secret.yaml b/.kube-workflow/preprod/templates/app.sealed-secret.yaml index a07827df..f9a24afe 100644 --- a/.kube-workflow/preprod/templates/app.sealed-secret.yaml +++ b/.kube-workflow/preprod/templates/app.sealed-secret.yaml @@ -11,6 +11,7 @@ spec: MAIL_AUTH_PASS: AgA3hpm2/2wz7P0scY8ka7LBjFZIaUF/8HCnzUZDdd1JcpQKOqPtaRYAQga8AKh38kwi1Nhy4ObM/V5gvV6uVIs3DyqihMpvy/n2DgG+4vSGhy+Hu8jdpwvuMcsOSmSJqFwrq/t0aQxX0IeRWGt2i4whOk23nrCmmVNlAc5ONVnA0/k2+EGl45bajDuX8a7usRUzcXP4g53b631t3Nrop2XiK9OGEjC+58Q6Q2lWOQLmJeVQ1vfjNQ47P0ErRKAtkF8Qve60wPmACH5YJ2rlMdWO+Ciu+Ay8YqUvfwMO0CRv+2UqSE6nBPuQh7SWalR18ox4fNp+phdKMoGlp0ps8PpSz+jhEexuUrQ2del8p5eHzM3YlNBVfd08/O3VCSzqQm5vWUqmtyP0q2UUj61cv+09ESwP4/4xp9GcyNzsfeYbhkVSqNtgcYcI/+VMr24InO3qoJQvQilgkqDFQ3EAm1YOGA5wwCjp5A585ciDDlYMhpKX/Xm9r4pRl0RIPSICkf5p27XLIA8Q50Ek3ilkgk2YSgSgHSSK7bBTI1uZ1sDocu9KeP1nuT3PXnvQgBvDiPRwzszKljkaHxhggwEq5hJXQtc+HviK5OgPXMX8HaTLvZ/NbaHJbUXOzZmBOnBGmuamvZAQ3LM/5pytqQF6+vI72DMSYdGCCbG5aOBN97Ri7VMr2FGiBec6UBPz9h4FYIUEXkUe6wIWCZXvlAxXC2r69BFWxzix5/TiMREEjUdmzg== MAIL_AUTH_USER: AgABEMHUy32vYsbtGU7k3s2szsBl/0zFXCxf6k2bmqItz/6po6T9IPDDIzq43eGlU2d6bC+J3HWmis1LldXUI0/Z+Z0Nt0CE2N2kDKEeQ37bFNNN0jdOv7GUJcnxghTXV5qGrBVwuxIMKETpT0g4zTp2KTxHdnwR3J3+5CYKzWSMVIp0Lughj+PBtcoUwPCJIb+L/RF5t/Vv9JiiZnCAkNrMX2o4yNAV/mGf2UmRAorymAq1jbvab/L3d1X6LhgMtVrZdtHOAGXlschRP+0NZPiNRO+A/ge0lVREXEkexyiD4NlxqEvmXvXSqu08wfmW/2ZedL/2qouPN7PHQHjT7jzl/z1yGueplnxQty8iOUETev9qYh4Y4ilZ+h+DpPIaZ6yl82pmmtcmEssJZvc1dtmBrBFxKe9yqhHaSOjABIvrHEOGupxP952N7qF2ZI88iPqSsZuuJraGYldRbLcYOUGHOjd8Px3S7B+1CNuPYmaK2AaTKcN+cUIm2Y/c3UX7EpXRT7UCySSrZA3ch72qfzCpqw15TQTIHSLdXxpSlhKiP/H299Tny9Ukvxm0F3uihgaESL9YMOcDxomF2n70fUbB1SFVsbi7sW5u7U+9XJw7lZOaR8Tvx/dx0AMRhEcVJ995+j2B/8nqV+J5OQlyB1wMgT/f+LagvzEYip7Idmk5cRZm1cXvrLiWE5YTx1yzy4zELY7Dv/bLsHVz8nXvrlRnmckFfVE+G7DrjiT+GZU8uw== NEXTAUTH_SECRET: AgBNsWw2Zm70ZnPdTxr3i25v6/7YtZwc0mqqY5caGU7J6tQ+GZsv4lWHLjVCrDvKkP4uUlVS0MUzvnDdWxYJ+STnTzRDEOPCB8eqMFyUieATnezAuDn38r4uCDW5IJCGcgalg5zRtM+ge5gMA8VTH3tjmzIp7YlP5jIOE5x19YVSW+lkqWMydTJ+EaxsmWQHQNcso9OHzAiO/vOHGt+yZdzAX0VPkg0Ovth5y1d/BZA4gJIjI0wB9KMWd/xsPIhC1mK4cRghRk56DARYbJDEnb+yr85TtmrgQkMvFZ4c1jzou4NpqAiyIpwB3HlJP/Ftazke1RZrnprtmf5Zcr0Z1IO3+t76MMb6erCBQDu+SjQDoVlAxgNSg8HFOaTN70n1U64XQEOmTvCFUBcmRfgVfmadKwp384eeKd0Gql3Qhhr49U55DprAzQKCyxLqb+pOpjtzxkYg8ljdXkDy7G03apJE6MvpGLPBXKUl0A3xCfP66itYz3Obl6tnPNYJxRKMWPhaKi7V++a5CqH0WFKWn8tTg+1DvP9M/GR/1vUSLwJFIvN4fYP65kl/1HAAcbVxSe9ZFEqDbs0zfowbAPMjBPvPWeW339gLXLOUPv9AcIJsZgrySSOUl57XLhWRJyIR5ztXitNg0yESxIBW0VEyZWt4Bi/IlyyS2/obuYfUT4PlGuLCmaaOGgPMHn/OiIfmjXH5E045lLuWlp+J4+y+XoXs+ez0cA4eEGDPr1VvR5S0nam76dmOjsM88zYD2A== + REPORTING_MAIL_RECIPIENTS: AgDSnQabsaN2dpcGYRDJs7yNolxKVjZmA3v7ClEOVkb75eKLnlZDqEZWfGcp87XFOWbSNC4ewOBBvA7uER6F2ca7YBF1hHXt/Hf151ptpcklQ1sYvx7KneIclwcTIAN/QPK//su6PoFg1pV3eZnaiZk4SwdSgzG/trBdSq3D4tZar8mHQHdah9eaE5a9wZEiotrc6iCRFh95r9mPxT0Tn/AZ7PHk4kxfuhJKHC51kJOuSHuvx8mbN6/x97D66S5ZQcZx3huc2EKO90Uo68IwZvqDV4Nl5HA3HCZGrXv4IaDfqH4lENhA/vggzkAok4jh0WscINbyuwugF0T1Outzw7EJtDdn+TgoOdPqe47mz0xNo9JBkDZRVSbsw6+p5XuJi3AGC9Sa+lYW7uP9pTOMqGpdWIENu8ZV+3pMvACmScQUjHBCJPIh+9qsaGBIHnEWWpIRshA9w/UbFCZRIsodjGU0Ba/FhMsMJHEl/TIgv5c9S6yfg62gJxat/h3xpKK4yBgPhVcc3QW+iXOjHB/FBWjo66V8zRux7CE/uCocnmFB+AyIWmUWJHqk+HObYiG7lI4thi/idSglzF2gjc6JfKdmNZd1bPU0Mtx6kXuvIC2pMQkBdHNC8qrHUmEld644sT9FkCT27qS2ZZ+mCXjM8g2PbQ7rPF4SA5+I8XAUFcOKoCTjMduI6agjVOlfNBy5HYivkdgykNH1Irz9vO6/Jw== template: metadata: annotations: diff --git a/.kube-workflow/preprod/templates/sendReporting.yaml b/.kube-workflow/preprod/templates/sendReporting.yaml new file mode 100644 index 00000000..fa276043 --- /dev/null +++ b/.kube-workflow/preprod/templates/sendReporting.yaml @@ -0,0 +1,28 @@ +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + namespace: mon-psy-sante-preprod + name: send-reporting + labels: + app: mon-psy +spec: + schedule: "0 13 * * 5" + jobTemplate: + spec: + template: + spec: + containers: + - name: mon-psy + image: ghcr.io/socialgouv/mon-psy-sante/app:{{ .Values.global.imageTag }} + envFrom: + - secretRef: + name: app-sealed-secret + - secretRef: + name: pg-user + command: + - yarn + - run + - cron:launch + - sendReporting + restartPolicy: Never + concurrencyPolicy: Forbid diff --git a/.kube-workflow/prod/templates/app.sealed-secret.yaml b/.kube-workflow/prod/templates/app.sealed-secret.yaml index ee911f5e..ca00c4c4 100644 --- a/.kube-workflow/prod/templates/app.sealed-secret.yaml +++ b/.kube-workflow/prod/templates/app.sealed-secret.yaml @@ -10,6 +10,7 @@ spec: MAIL_AUTH_PASS: AgB3Ift75N0PZwHaaK0xR3Ax6Jg54THomlKq+6FbjHyZSwtPrjBsQOAZDX/K0IvYvRiTjiS/4YtlvaNDl+0o+B8RjUlUF4WnTkxzzd4reeHH552St6ZzrAsFuPVjI+Bo8AvCt5SsFR7yTQu8Xrz8xaas5+AR3eU/uGLFZ3HphG2BmnhPKi+lYbB5DBsWpF9f+uAIXkZnQeRq2OjMLUYCVKBi1oRBW3YLG+5w2agjArGIyuCBKGm3+HleMGlVQEjvEWkDhKjyDRexDyO/r/hdHEXvTN9fHjW+Rrv1i1R3onzf9Cvg9DEmKERWJhBUiv8/iEZTvC2Byf9c2jnPVw0FcURnc1+nrcu5gOpGkBPnFVQz0UiGRojskvmC0doneCvUqH/vKr9WktrwUtX9mfZ0Qz+2wkzPBlOioLTYrm4KrbKyq6JJT91jFrzLCY6M+SJBV9jTL5Vymo8wuVbJscvXd8S+Je8Oi+SBwIJd5AXVYhqGPLlL1IIzRJUNSgwdth6L71mfCjnRraJkEkc1PXyV6awfmVpd5tG/NU8uItMnfq+ROK2T7GwZcl5uiARP48pMTedp7T4EHmA2eks70fGga7CowqGv91htd/waSkiB/duhdmapeWuanaLbUW/hA56ARJULSMKSJdnKQ4QyTY16BmX5PO7cYrjq48Qf0QlYiDvM5s7C1VsvPx0bg/HsSEV0bD/QkL8WRZphLGeqIqbk2tdbExS6vI2jH9qu8RfFq9bD7Q== MAIL_AUTH_USER: AgCq28vVc0xCS94tOes8fEtxwq4jPzlYLNLXL5qCn1j172EGGfqITpDN7zr8dbuUpHRhTIbPmttLXD4hNnSdJwDM12fiK6D8bdzBEZFm/mc7zCJgS0ARyVUDKJZ01w7nB3MXcz5BTYjpsy3ul2Y2j3gTg5eONcHi2UZ2JMvVz8HHnMYcTHSGxb7lmOYftcO/sEZoerRSjfoGpI6MaKjLu5tSMYc7PSVYjiwNCoaxZmHJypOmEZSDZ3ggj5Oh77PI8OqWAih35gstbNXC8YOz4s7DhEZzdRo8dVyF2nWoMAh62uhQUK5LZqXP4A5dJubClQmpfzhZz8bjUQ8oVQlIvy4nqG4dD2GGyx713ObyuTBGXw+iiRKLhwDH5U+aYlUTFvFE9Ee81jJXKRq5//YI0lo8zUdJToylQcciwi/Qblw7/H0H/yGU8Hx9aFH2obNQHmdJeYzvmmV0jfMec5EoXYg9/bEF8a8HvZU2lHGNnUw4QPor9kpFE0OvUzmnB5VXarVAP/q7Ho82iRFIEZ7ynCB7MqTUOowtqLVGd9yebyiHIx2cUe2ytcPURNDJLwtF6nv3xvjQ4gMsXHuYUFU7PG1FAzL4XvCPspKcEK5xtr+JNAQx0usQB2deiaHqzYbMaeTugqXsif9J7E19lpMF4e0q6ghlvAMW9W04Mru+Lvi+ITts2zW/1Qiq5GifN+eiHkP2Lq5HP9xCj1OiX3gXLXl5tFqLKKr6wd62UQjqLK4/HA== NEXTAUTH_SECRET: AgBF1wRI4LP+Ayn5rjkP3oheH09KsdPU+deUQ9X6cbfVVj9xsCJwlkNwALAVEYbn8FWIuyAIyCMInRwDd5v4yro4ofKcZWnGV7HhaMjt82w/FM+VRg4XphJdq5V/plML/7wZFP7Fd4lMr1GrDrqHQRW25IAdqGCH6R5n5g65RudN26t1GhrCK9o2lySYWj8kSjkr8GwK0xeCwlhI4pzDm5sRRCBNmJ+qHiswhH1ArMGZ7LxMfHOlb7JdwRY+FkYvIcXUKL40OwBucyNt+Rwu450MVywtpNLoRUJVbT/gQkjxbMzFpQla/CDdUIl90tXnFF+FCUcF3DjVmnWx0lvcr1vQM7kkFkx6VWJUiFiMNz63APqQbgHFtJyA+ZMtFmC8Hp3lOf89WvC9y/U12vScvwGEBKnTwcD4vosq/DPneDniGFKcdljDovBvzBnRq4rasX+FRawnR4xSULtNu7ixufmVgVca7dtSslHNEP6TuE370yZXxBGqtoPx79Iz5bSv9JkCQlo7dIs1wHoB/vDc28AVwadynmMBYv4erKP6HyJeIdW9OEIRBvpR/4qAnPKdx3RfsWDzuZX/6mk11by72MzudFZ5B0hdhXHG5pzLAmNsUl3GV0wKy5SBOWDmIQ97hotECQYmhPAze5rPQxe3GqAczxJdh0UijCJXhtdWl8JGS9OXbTKOvIATdxtAetbj9Y4ZxopYFtWzv1nyONqmjlIjzoOH/LGtyAOUokM9B6x2eP5gCZPk9yXtdjnh0A== + REPORTING_MAIL_RECIPIENTS: AgDSnQabsaN2dpcGYRDJs7yNolxKVjZmA3v7ClEOVkb75eKLnlZDqEZWfGcp87XFOWbSNC4ewOBBvA7uER6F2ca7YBF1hHXt/Hf151ptpcklQ1sYvx7KneIclwcTIAN/QPK//su6PoFg1pV3eZnaiZk4SwdSgzG/trBdSq3D4tZar8mHQHdah9eaE5a9wZEiotrc6iCRFh95r9mPxT0Tn/AZ7PHk4kxfuhJKHC51kJOuSHuvx8mbN6/x97D66S5ZQcZx3huc2EKO90Uo68IwZvqDV4Nl5HA3HCZGrXv4IaDfqH4lENhA/vggzkAok4jh0WscINbyuwugF0T1Outzw7EJtDdn+TgoOdPqe47mz0xNo9JBkDZRVSbsw6+p5XuJi3AGC9Sa+lYW7uP9pTOMqGpdWIENu8ZV+3pMvACmScQUjHBCJPIh+9qsaGBIHnEWWpIRshA9w/UbFCZRIsodjGU0Ba/FhMsMJHEl/TIgv5c9S6yfg62gJxat/h3xpKK4yBgPhVcc3QW+iXOjHB/FBWjo66V8zRux7CE/uCocnmFB+AyIWmUWJHqk+HObYiG7lI4thi/idSglzF2gjc6JfKdmNZd1bPU0Mtx6kXuvIC2pMQkBdHNC8qrHUmEld644sT9FkCT27qS2ZZ+mCXjM8g2PbQ7rPF4SA5+I8XAUFcOKoCTjMduI6agjVOlfNBy5HYivkdgykNH1Irz9vO6/Jw== template: metadata: name: app-sealed-secret diff --git a/src/cron/launch.ts b/src/cron/launch.ts index 2f6f92da..e140d484 100644 --- a/src/cron/launch.ts +++ b/src/cron/launch.ts @@ -1,7 +1,7 @@ import * as Sentry from "@sentry/nextjs"; import * as demarchesSimplifiees from "./demarchesSimplifiees"; -import { sendMailToRaph } from "./sendMailToRaph"; +import { sendReporting } from "./sendReporting"; const runJob = async (job): Promise => { const SENTRY_DSN = process.env.NEXT_PUBLIC_SENTRY_DSN; @@ -26,7 +26,7 @@ if (process.argv.length < 3) { const cronJobs = { importFromDS: demarchesSimplifiees.importFromDS, verifFolders: demarchesSimplifiees.verifFolders, - sendMailToRaph, + sendReporting, }; const jobName = process.argv[2]; diff --git a/src/cron/sendMailToRaph.ts b/src/cron/sendMailToRaph.ts deleted file mode 100644 index 9a93443c..00000000 --- a/src/cron/sendMailToRaph.ts +++ /dev/null @@ -1,34 +0,0 @@ -import nodemailer from "nodemailer"; - -import config from "../services/config"; - -const mailTransport = nodemailer.createTransport({ - auth: { - pass: config.mail.auth.pass, - user: config.mail.auth.user, - }, - host: config.mail.host, - ignoreTLS: !config.mail.tls, - port: config.mail.port, - requireTLS: config.mail.tls, -}); - -export function sendMailToRaph() { - const mail = { - from: `MonPsy <${config.supportMail}>`, - html: "bonjour raph", - subject: "salut raph", - text: "bonjour raph", - to: "raph@selego.co", - }; - if (config.mail.enabled) { - return new Promise((resolve, reject) => { - mailTransport.sendMail(mail, (error, info) => { - console.log(error, info); - return error ? reject(error) : resolve(info); - }); - }); - } - console.log("Send email skipped"); - return Promise.resolve(); -} diff --git a/src/cron/sendReporting.ts b/src/cron/sendReporting.ts new file mode 100644 index 00000000..cf77ce5f --- /dev/null +++ b/src/cron/sendReporting.ts @@ -0,0 +1,127 @@ +import _ from "lodash"; +import nodemailer, { SendMailOptions } from "nodemailer"; + +import config from "../services/config"; +import { requestPsychologistsState } from "../services/demarchesSimplifiees/buildRequest"; +import { getAllPsychologistList } from "../services/demarchesSimplifiees/import"; +import { DEPARTMENTS } from "../types/enums/department"; + +export async function reporting() { + const data = []; + + const extractDepNumber = (dep) => dep.split(" - ")[0]; + const deps = DEPARTMENTS.map((dep) => { + return { + count: 0, + countAcceptes: 0, + name: dep, + department: extractDepNumber(dep), + }; + }); + function log(text, count, countAcceptes = "") { + console.log(text, ":", count, countAcceptes); + data.push(`"${text}";${count};${countAcceptes}\n`); + } + + log("Dep", "Total", "Acceptés"); + const requestPsychologistsStateWithDep = _.bind( + requestPsychologistsState, + null, + _, + `groupeInstructeur { + label + }` + ); + const result = await getAllPsychologistList( + requestPsychologistsStateWithDep + ).catch((e) => { + console.log(e); + process.exit(-1); + }); + + const psychologists = result.psychologists; + console.log(psychologists[0]); + const sansSuite = _.filter(psychologists, { state: "sans_suite" }); + const refuse = _.filter(psychologists, { state: "refuse" }); + + const valids = _.reject( + _.reject(_.reject(psychologists, { state: "refuse" }), { + state: "sans_suite", + }), + { archived: true } + ); + + valids.forEach((psy) => { + const dep = _.find(deps, { + department: extractDepNumber(psy.groupeInstructeur.label), + }); + if (!dep) console.log(">>>>>>>>>", psy.groupeInstructeur.label); + dep.count++; + if (psy.state === "accepte") dep.countAcceptes++; + }); + + const enInstruction = _.filter(valids, { state: "en_instruction" }); + const enConstruction = _.filter(valids, { state: "en_construction" }); + const accepte = _.filter(valids, { state: "accepte" }); + const noDossier = _.filter(deps, { count: 0 }); + const noDossierAcceptes = _.filter(deps, { countAcceptes: 0 }); + + deps.forEach((item) => { + log(item.name, item.count, String(item.countAcceptes)); + }); + + log("", ""); + log("Nombre total de dossier déposés", psychologists.length); + log("Nombre total de dossier sans suite", sansSuite.length); + log("Nombre total de dossier refusés", refuse.length); + log("Nombre total de dossier en instruction", enInstruction.length); + log("Nombre total de dossier en construction", enConstruction.length); + log("Nombre total de dossier acceptés", accepte.length); + log("Nombre de départements sans dossiers", noDossier.length); + log( + "Nombre de départements sans dossiers acceptés", + noDossierAcceptes.length + ); + + return Buffer.from(data.join("")); +} + +export async function sendReporting() { + const mailTransport = nodemailer.createTransport({ + auth: { + pass: config.mail.auth.pass, + user: config.mail.auth.user, + }, + host: config.mail.host, + ignoreTLS: !config.mail.tls, + port: config.mail.port, + requireTLS: config.mail.tls, + }); + + const text = ["Bonjour,", "Ci-joint les statistiques par département."]; + + const mail: SendMailOptions = { + from: `MonPsy <${config.supportMail}>`, + html: text.join("
"), + subject: "Statistiques par département", + text: text.join("\n"), + to: config.reportingMailRecipients, + attachments: [ + { + filename: "statistiques.csv", + content: await reporting(), + }, + ], + }; + + if (config.mail.enabled) { + return new Promise((resolve, reject) => { + mailTransport.sendMail(mail, (error, info) => { + console.log(error, info); + return error ? reject(error) : resolve(info); + }); + }); + } + console.log("Send email skipped"); + return Promise.resolve(); +} diff --git a/src/services/config.ts b/src/services/config.ts index 78abccd9..9b53a547 100644 --- a/src/services/config.ts +++ b/src/services/config.ts @@ -46,5 +46,6 @@ export default { url: process.env.DATABASE_URL || "postgres://localhost:5432/monpsysante", }, supportMail: process.env.SUPPORT_MAIL, + reportingMailRecipients: process.env.REPORTING_MAIL_RECIPIENTS, apiAdresseUrl: process.env.API_ADRESSE_URL, };