diff --git a/apps/infoalloggi/src/components/area-riservata/ordini.tsx b/apps/infoalloggi/src/components/area-riservata/ordini.tsx index b90a69c..3e580ac 100644 --- a/apps/infoalloggi/src/components/area-riservata/ordini.tsx +++ b/apps/infoalloggi/src/components/area-riservata/ordini.tsx @@ -1,6 +1,7 @@ import { CircleCheck, CircleSlash, ReceiptText } from "lucide-react"; import Link from "next/link"; import type { Dispatch, SetStateAction } from "react"; +import toast from "react-hot-toast"; import { Credenza, CredenzaBody, @@ -48,6 +49,16 @@ const AdminOrdiniModal = ({ ordineId, }); + const { mutate: sendReceipt } = + api.comunicazioni.sendRicevutaECondizioniEmail.useMutation({ + onSuccess: () => { + toast.success("Email inviata con successo!"); + }, + onError: (error) => { + toast.error(`Errore durante l'invio dell'email: ${error.message}`); + }, + }); + if (!data) return null; return ( @@ -66,18 +77,27 @@ const AdminOrdiniModal = ({

Id Ordine: {data.ordine_id}

- {data.isActive && ( -
- - - -
- )} +
+ {data.isActive && ( +
+ + + +
+ )} + +
setSelected(null)} data={data} diff --git a/apps/infoalloggi/src/server/api/routers/comunicazioni.ts b/apps/infoalloggi/src/server/api/routers/comunicazioni.ts index 78ec7e1..6c2b819 100644 --- a/apps/infoalloggi/src/server/api/routers/comunicazioni.ts +++ b/apps/infoalloggi/src/server/api/routers/comunicazioni.ts @@ -1,11 +1,13 @@ import { z } from "zod/v4"; import type { EmailsIdEmail } from "~/schemas/public/Emails"; +import type { TestiEStringheStingaId } from "~/schemas/public/TestiEStringhe"; import { adminProcedure, createTRPCRouter, protectedProcedure, publicProcedure, } from "~/server/api/trpc"; +import { addEventToQueue } from "~/server/controllers/event_queue.controller"; import { SendContattoAnnuncioEmail } from "~/server/controllers/servizio.controller"; import { db } from "~/server/db"; import { @@ -15,7 +17,7 @@ import { } from "~/server/services/email.service"; import { NewMail } from "~/server/services/mailer"; import { genPdfSchedaAnnuncioBase64 } from "~/server/services/puppeteer.service"; -import { zAnnuncioId, zUserId } from "~/server/utils/zod_types"; +import { zAnnuncioId, zOrdineId, zUserId } from "~/server/utils/zod_types"; export const comunicazioniRouter = createTRPCRouter({ getEmails: protectedProcedure @@ -208,4 +210,68 @@ export const comunicazioniRouter = createTRPCRouter({ ...input, }); }), + sendRicevutaECondizioniEmail: adminProcedure + .input( + z.object({ + ordineId: zOrdineId, + }), + ) + .mutation(async ({ input }) => { + try { + const ordine = await db + .selectFrom("ordini") + .selectAll() + .innerJoin("users", "users.id", "ordini.userid") + .select(["users.email"]) + .innerJoin("prezziario", "prezziario.idprezziario", "ordini.packid") + .select(["prezziario.testo_condizioni"]) + .where("ordine_id", "=", input.ordineId) + .executeTakeFirstOrThrow(() => { + throw new Error(`Ordine not found - ordineId: ${input.ordineId}`); + }); + + await addEventToQueue({ + data: { + tipo: "email", + data: { + template: { + mailType: "servizioAttivato", + }, + mail: { + subject: "Pagamento Confermato - Acconto Infoalloggi.it", + to: ordine.email, + attachments: [ + { + filename: `condizioni_contrattuali_${ordine.created_at.toISOString()}.pdf`, + generate: { + type: "condizioni", + stringId: (ordine.testo_condizioni || + "CONDIZIONI_CERCHI") as TestiEStringheStingaId, + }, + encoding: "base64", + contentType: "application/pdf", + }, + { + filename: `ricevuta_cortesia_${ordine.ordine_id}.pdf`, + + generate: { + type: "ricevuta_cortesia", + ordineId: ordine.ordine_id, + }, + encoding: "base64", + contentType: "application/pdf", + }, + ], + }, + userId: ordine.userid, + }, + }, + lock_expires: new Date(), // Lock expires in 1 + }); + } catch (e) { + throw new Error( + `Errore nell'invio dell'email: ${(e as Error).message}`, + ); + } + }), }); diff --git a/apps/infoalloggi/src/server/controllers/stripe.controller.ts b/apps/infoalloggi/src/server/controllers/stripe.controller.ts index 962ff8d..9dd9ade 100644 --- a/apps/infoalloggi/src/server/controllers/stripe.controller.ts +++ b/apps/infoalloggi/src/server/controllers/stripe.controller.ts @@ -80,7 +80,14 @@ export const whIntentSucceededHandler = async ({ }) .where("intent_id", "=", pIntentId) .where("ordine_id", "=", ordineId) - .returning(["servizio_id", "ordine_id", "userid", "type", "created_at"]) + .returning([ + "servizio_id", + "ordine_id", + "userid", + "type", + "created_at", + "packid", + ]) .executeTakeFirstOrThrow(() => { throw new Error( `Payment not found - intent_id: ${pIntentId}, ordineId: ${ordineId}`, @@ -97,6 +104,12 @@ export const whIntentSucceededHandler = async ({ ); }); + const condizioni = await trx + .selectFrom("prezziario") + .select("testo_condizioni") + .where("idprezziario", "=", ordine.packid) + .executeTakeFirst(); + const utente = await getUser({ db: trx, userId: ordine.userid, @@ -131,7 +144,8 @@ export const whIntentSucceededHandler = async ({ generate: { type: "condizioni", - stringId: "CONDIZIONI_CERCHI" as TestiEStringheStingaId, + stringId: (condizioni?.testo_condizioni || + "CONDIZIONI_CERCHI") as TestiEStringheStingaId, }, encoding: "base64", contentType: "application/pdf", diff --git a/apps/infoalloggi/src/server/services/puppeteer.service.ts b/apps/infoalloggi/src/server/services/puppeteer.service.ts index 50ff826..6667dc3 100644 --- a/apps/infoalloggi/src/server/services/puppeteer.service.ts +++ b/apps/infoalloggi/src/server/services/puppeteer.service.ts @@ -171,7 +171,7 @@ const puppeteerGenPdf = async ({ try { browser = await puppeteer.connect({ - browserWSEndpoint: `${env.BROWSER_WS_URL}?--user-data-dir=/tmp/session-0`, + browserWSEndpoint: `${env.BROWSER_WS_URL}`, }); const page = await browser.newPage();