2025-08-04 17:45:44 +02:00
|
|
|
import { TRPCError } from "@trpc/server";
|
2025-08-28 18:27:07 +02:00
|
|
|
import { jsonArrayFrom } from "kysely/helpers/postgres";
|
2026-02-24 10:40:32 +01:00
|
|
|
import type {
|
|
|
|
|
NewOrdini,
|
|
|
|
|
OrdiniOrdineId,
|
|
|
|
|
OrdiniUpdate,
|
|
|
|
|
} from "~/schemas/public/Ordini";
|
2026-03-04 19:12:01 +01:00
|
|
|
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum";
|
2025-08-28 18:27:07 +02:00
|
|
|
import type { UsersId } from "~/schemas/public/Users";
|
|
|
|
|
import { db, type Querier } from "~/server/db";
|
2025-08-04 17:45:44 +02:00
|
|
|
|
|
|
|
|
export type OrdiniWPagamenti = Awaited<ReturnType<typeof getOrdini>>[number];
|
|
|
|
|
export const getOrdini = async (userId: UsersId | undefined) => {
|
2025-08-28 18:27:07 +02:00
|
|
|
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"),
|
|
|
|
|
]);
|
2025-08-04 17:45:44 +02:00
|
|
|
|
2025-08-28 18:27:07 +02:00
|
|
|
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}`,
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-08-04 17:45:44 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getOrdineById = async (ordineId: OrdiniOrdineId) => {
|
2025-08-28 18:27:07 +02:00
|
|
|
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")
|
2026-03-05 10:29:08 +01:00
|
|
|
.executeTakeFirstOrThrow(
|
|
|
|
|
() => new Error(`Ordine not found - ordineId: ${ordineId}`),
|
|
|
|
|
);
|
2025-08-28 18:27:07 +02:00
|
|
|
} catch (e) {
|
|
|
|
|
throw new TRPCError({
|
|
|
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
|
|
|
message: `Error fetching ordini by user ID: ${(e as Error).message}`,
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-08-04 17:45:44 +02:00
|
|
|
};
|
|
|
|
|
|
2026-02-24 10:40:32 +01:00
|
|
|
export const createOrdine = async (data: NewOrdini) => {
|
|
|
|
|
try {
|
2026-03-04 19:12:01 +01:00
|
|
|
return await db.transaction().execute(async (tx) => {
|
|
|
|
|
const prezzo = await tx
|
|
|
|
|
.selectFrom("prezziario")
|
|
|
|
|
.select(["prezzo_cent", "nome_it"])
|
|
|
|
|
.where("prezziario.idprezziario", "=", data.packid)
|
2026-03-05 10:29:08 +01:00
|
|
|
.executeTakeFirstOrThrow(
|
|
|
|
|
() => new Error(`Prezziario not found - packid: ${data.packid}`),
|
|
|
|
|
);
|
2026-03-04 19:12:01 +01:00
|
|
|
|
|
|
|
|
const order = await tx
|
|
|
|
|
.insertInto("ordini")
|
|
|
|
|
.values(data)
|
|
|
|
|
.returningAll()
|
2026-03-05 10:29:08 +01:00
|
|
|
.executeTakeFirstOrThrow(() => new Error("Failed to create ordine"));
|
2026-03-04 19:12:01 +01:00
|
|
|
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;
|
|
|
|
|
});
|
2026-02-24 10:40:32 +01:00
|
|
|
} catch (e) {
|
|
|
|
|
throw new TRPCError({
|
|
|
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
|
|
|
message: `Error creating ordine: ${(e as Error).message}`,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-08-04 17:45:44 +02:00
|
|
|
export const removeOrder = async (ordineId: OrdiniOrdineId) => {
|
2025-08-28 18:27:07 +02:00
|
|
|
try {
|
2026-03-05 10:29:08 +01:00
|
|
|
await db.deleteFrom("ordini").where("ordine_id", "=", ordineId).execute();
|
2025-08-28 18:27:07 +02:00
|
|
|
return true;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
throw new TRPCError({
|
|
|
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
|
|
|
message: `Error removing order: ${(e as Error).message}`,
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-08-04 17:45:44 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const updateOrder = async ({
|
2025-08-28 18:27:07 +02:00
|
|
|
ordineId,
|
|
|
|
|
data,
|
2025-08-04 17:45:44 +02:00
|
|
|
}: {
|
2025-08-28 18:27:07 +02:00
|
|
|
ordineId: OrdiniOrdineId;
|
|
|
|
|
data: OrdiniUpdate;
|
2025-08-04 17:45:44 +02:00
|
|
|
}) => {
|
2025-08-28 18:27:07 +02:00
|
|
|
try {
|
|
|
|
|
const updated = await db
|
|
|
|
|
.updateTable("ordini")
|
|
|
|
|
.set(data)
|
|
|
|
|
.where("ordine_id", "=", ordineId)
|
|
|
|
|
.returningAll()
|
2026-03-05 10:29:08 +01:00
|
|
|
.executeTakeFirstOrThrow(
|
|
|
|
|
() => new Error(`Failed to update ordine - ordineId: ${ordineId}`),
|
|
|
|
|
);
|
2025-08-28 18:27:07 +02:00
|
|
|
return updated;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
throw new TRPCError({
|
|
|
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
|
|
|
message: `Error updating order: ${(e as Error).message}`,
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-08-04 17:45:44 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const cleanupUnusedOrders = async ({ db }: { db: Querier }) => {
|
2025-08-28 18:27:07 +02:00
|
|
|
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();
|
2025-08-04 17:45:44 +02:00
|
|
|
|
2025-08-28 18:27:07 +02:00
|
|
|
if (orders.length === 0) {
|
|
|
|
|
return "ok";
|
|
|
|
|
}
|
|
|
|
|
const ordineIds = orders.map((o) => o.ordine_id);
|
|
|
|
|
await db.deleteFrom("ordini").where("ordine_id", "in", ordineIds).execute();
|
2025-08-04 17:45:44 +02:00
|
|
|
|
2025-08-28 18:27:07 +02:00
|
|
|
return "ok";
|
|
|
|
|
} catch (e) {
|
|
|
|
|
throw new TRPCError({
|
|
|
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
|
|
|
message: `Error cleaning up old orders: ${(e as Error).message}`,
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-08-04 17:45:44 +02:00
|
|
|
};
|