import { TRPCError } from "@trpc/server"; import { jsonArrayFrom } from "kysely/helpers/postgres"; import type { NewOrdini, OrdiniOrdineId, OrdiniUpdate, } from "~/schemas/public/Ordini"; import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum"; import type { UsersId } from "~/schemas/public/Users"; import { db, type Querier } from "~/server/db"; export type OrdiniWPagamenti = Awaited>[number]; export const getOrdini = async (userId: UsersId | undefined) => { try { let qry = db .selectFrom("ordini") .selectAll("ordini") .innerJoin("users", "users.id", "ordini.userid") .select("users.username") .select((eb) => [ jsonArrayFrom( eb .selectFrom("payments") .selectAll("payments") .whereRef("payments.ordine_id", "=", "ordini.ordine_id") .orderBy("payments.created_at", "desc"), ).as("pagamenti"), ]); if (userId) { qry = qry.where("ordini.userid", "=", userId); } return await qry.orderBy("created_at", "desc").execute(); } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Error fetching ordini by user ID: ${(e as Error).message}`, }); } }; export const getOrdineById = async (ordineId: OrdiniOrdineId) => { try { return await db .selectFrom("ordini") .selectAll("ordini") .innerJoin("users", "users.id", "ordini.userid") .select("users.username") .select((eb) => [ jsonArrayFrom( eb .selectFrom("payments") .selectAll("payments") .whereRef("payments.ordine_id", "=", "ordini.ordine_id") .orderBy("payments.created_at", "desc"), ).as("pagamenti"), ]) .where("ordini.ordine_id", "=", ordineId) .orderBy("created_at", "desc") .executeTakeFirstOrThrow(); } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Error fetching ordini by user ID: ${(e as Error).message}`, }); } }; export const createOrdine = async (data: NewOrdini) => { try { return await db.transaction().execute(async (tx) => { const prezzo = await tx .selectFrom("prezziario") .select(["prezzo_cent", "nome_it"]) .where("prezziario.idprezziario", "=", data.packid) .executeTakeFirstOrThrow(); const order = await tx .insertInto("ordini") .values(data) .returningAll() .executeTakeFirstOrThrow(); await tx .insertInto("payments") .values({ ordine_id: order.ordine_id, servizio_id: order.servizio_id, userid: order.userid, amount_cent: prezzo.prezzo_cent, paymentname: prezzo.nome_it, paymentmethod: "manual", paymentstatus: data.isActive ? PaymentStatusEnum.success : PaymentStatusEnum.processing, paid_at: data.isActive ? new Date() : null, }) .execute(); return order; }); } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Error creating ordine: ${(e as Error).message}`, }); } }; export const removeOrder = async (ordineId: OrdiniOrdineId) => { try { await db .deleteFrom("ordini") .where("ordine_id", "=", ordineId) .executeTakeFirstOrThrow(); return true; } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Error removing order: ${(e as Error).message}`, }); } }; export const updateOrder = async ({ ordineId, data, }: { ordineId: OrdiniOrdineId; data: OrdiniUpdate; }) => { try { const updated = await db .updateTable("ordini") .set(data) .where("ordine_id", "=", ordineId) .returningAll() .executeTakeFirstOrThrow(); return updated; } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Error updating order: ${(e as Error).message}`, }); } }; export const cleanupUnusedOrders = async ({ db }: { db: Querier }) => { try { const orders = await db .selectFrom("ordini") .select("ordini.ordine_id") .leftJoin("payments", "payments.ordine_id", "ordini.ordine_id") .where("payments.paymentstatus", "is", null) .where("ordini.isActive", "=", false) .distinct() .execute(); if (orders.length === 0) { return "ok"; } const ordineIds = orders.map((o) => o.ordine_id); await db.deleteFrom("ordini").where("ordine_id", "in", ordineIds).execute(); return "ok"; } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Error cleaning up old orders: ${(e as Error).message}`, }); } };