infoalloggi-monorepo/apps/infoalloggi/src/server/services/prezziario.service.ts

217 lines
5.3 KiB
TypeScript
Raw Normal View History

2025-08-28 18:27:07 +02:00
import { TRPCError } from "@trpc/server";
import { sql } from "kysely";
2025-08-04 17:45:44 +02:00
import type {
2025-08-28 18:27:07 +02:00
NewPrezziario,
Prezziario,
PrezziarioIdprezziario,
PrezziarioUpdate,
2025-08-04 17:45:44 +02:00
} from "~/schemas/public/Prezziario";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
2025-08-28 18:27:07 +02:00
import { db, type Querier } from "~/server/db";
2025-08-04 17:45:44 +02:00
export const getPrezziario = async () => {
2025-08-28 18:27:07 +02:00
try {
return await db
.selectFrom("prezziario")
.selectAll()
.where("isActive", "=", true)
.orderBy("idprezziario", "asc")
.execute();
} catch (error) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error getting prezziario: ${(error as Error).message}`,
});
}
2025-08-04 17:45:44 +02:00
};
export const getPrezziarioByIdHandler = async ({
2025-08-28 18:27:07 +02:00
db,
input,
}: {
2025-08-28 18:27:07 +02:00
db: Querier;
input: {
idprezziario: PrezziarioIdprezziario;
};
}) => {
2025-08-28 18:27:07 +02:00
return await db
.selectFrom("prezziario")
.selectAll()
.where("prezziario.idprezziario", "=", input.idprezziario)
.executeTakeFirst();
};
2025-08-04 17:45:44 +02:00
export const addPrezziario = async ({
2025-08-28 18:27:07 +02:00
db,
input,
2025-08-04 17:45:44 +02:00
}: {
2025-08-28 18:27:07 +02:00
db: Querier;
input: NewPrezziario;
2025-08-04 17:45:44 +02:00
}): Promise<Prezziario> => {
2025-08-28 18:27:07 +02:00
try {
return await db
.insertInto("prezziario")
.values(input)
.returningAll()
.executeTakeFirstOrThrow();
} catch (error) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error adding prezziario: ${(error as Error).message}`,
});
}
2025-08-04 17:45:44 +02:00
};
export const updatePrezziario = async ({
2025-08-28 18:27:07 +02:00
db,
prezziarioId,
input,
2025-08-04 17:45:44 +02:00
}: {
2025-08-28 18:27:07 +02:00
db: Querier;
prezziarioId: PrezziarioIdprezziario;
input: PrezziarioUpdate;
2025-08-04 17:45:44 +02:00
}): Promise<Prezziario> => {
2025-08-28 18:27:07 +02:00
try {
return await db
.updateTable("prezziario")
.set(input)
.where("prezziario.idprezziario", "=", prezziarioId)
.returningAll()
.executeTakeFirstOrThrow();
} catch (error) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error updating prezziario: ${(error as Error).message}`,
});
}
2025-08-04 17:45:44 +02:00
};
export const deletePrezziario = async ({
2025-08-28 18:27:07 +02:00
db,
prezziarioId,
2025-08-04 17:45:44 +02:00
}: {
2025-08-28 18:27:07 +02:00
db: Querier;
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
prezziarioId: PrezziarioIdprezziario;
2025-08-04 17:45:44 +02:00
}): Promise<void> => {
2025-08-28 18:27:07 +02:00
try {
await db
.deleteFrom("prezziario")
.where("prezziario.idprezziario", "=", prezziarioId)
.execute();
} catch (error) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error deleting prezziario: ${(error as Error).message}`,
});
}
2025-08-04 17:45:44 +02:00
};
type MinimalPrezziario = Pick<
2025-08-28 18:27:07 +02:00
Prezziario,
"idprezziario" | "prezzo_cent" | "nome_it" | "nome_en" | "sconto"
2025-08-04 17:45:44 +02:00
>;
type PrezziarioByTipologia = {
2025-08-28 18:27:07 +02:00
acconto: MinimalPrezziario;
saldi: MinimalPrezziario[];
2025-08-04 17:45:44 +02:00
};
export const getPrezziarioByTipologia = async ({
2025-08-28 18:27:07 +02:00
db,
tipologia,
2025-08-04 17:45:44 +02:00
}: {
2025-08-28 18:27:07 +02:00
db: Querier;
tipologia: TipologiaPosizioneEnum;
2025-08-04 17:45:44 +02:00
}): Promise<PrezziarioByTipologia> => {
2025-08-28 18:27:07 +02:00
try {
const { acconto, saldi } = await db.transaction().execute(async (trx) => {
let qry = trx
.selectFrom("prezziario")
.select(["idprezziario", "prezzo_cent", "nome_it", "nome_en", "sconto"])
.where("isAcconto", "=", true)
.where("isSaldo", "=", false)
.where("isActive", "=", true);
if (tipologia === TipologiaPosizioneEnum.Transitorio) {
qry = qry.where("isTransitorio", "=", true);
} else if (tipologia === TipologiaPosizioneEnum.Stabile) {
qry = qry.where("isStabile", "=", true);
}
const acconto = await qry.executeTakeFirst();
if (!acconto) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Acconto not found",
});
}
let qry2 = trx
.selectFrom("prezziario")
.select(["idprezziario", "prezzo_cent", "nome_it", "nome_en", "sconto"])
.where("isAcconto", "=", false)
.where("isSaldo", "=", true)
.where("isActive", "=", true);
if (tipologia === TipologiaPosizioneEnum.Transitorio) {
qry2 = qry2.where("isTransitorio", "=", true);
} else if (tipologia === TipologiaPosizioneEnum.Stabile) {
qry2 = qry2.where("isStabile", "=", true);
}
// query with order by numeric part of idprezziario, handling '+' at the end
const saldi = await qry2
.orderBy(
sql`CAST(REGEXP_REPLACE(idprezziario, '[^0-9]+', '', 'g') AS INTEGER),
CASE WHEN idprezziario LIKE '%+%' THEN 1 ELSE 0 END`,
2025-08-28 18:27:07 +02:00
)
.execute();
//const saldi = await qry2.orderBy("prezzo_cent", "asc").execute();
if (!saldi) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Saldi not found",
});
}
return { acconto, saldi };
});
return { acconto, saldi };
} catch (error) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error getting prezziario by tipologia: ${(error as Error).message}`,
});
}
2025-08-04 17:45:44 +02:00
};
export const getPrezziarioConsulenza = async ({ db }: { db: Querier }) => {
2025-08-28 18:27:07 +02:00
try {
return await db.transaction().execute(async (trx) => {
const prezzi = await trx
.selectFrom("prezziario")
.select(["idprezziario", "prezzo_cent", "nome_it", "nome_en", "sconto"])
.where("isConsulenza", "=", true)
.where("isAcconto", "=", false)
.where("isSaldo", "=", false)
.where("isActive", "=", true)
.where("isStabile", "=", true)
.orderBy("prezzo_cent", "asc")
.execute();
if (!prezzi || prezzi.length !== 3) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Consulenza prezzi not found",
});
}
return prezzi;
});
} catch (error) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error getting prezziario by tipologia: ${(error as Error).message}`,
});
}
2025-08-04 17:45:44 +02:00
};