refactor: update servizio handling to include expiration logic and improve pack retrieval process
This commit is contained in:
parent
e692f9f1cb
commit
6f83ca3c34
4 changed files with 151 additions and 103 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { add } from "date-fns";
|
||||||
import { ArrowRight, Package, PackageCheck } from "lucide-react";
|
import { ArrowRight, Package, PackageCheck } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
@ -172,6 +173,36 @@ export const ServizioContent = () => {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
new Date() >
|
||||||
|
add(servizio.decorrenza, {
|
||||||
|
days: 60,
|
||||||
|
}) &&
|
||||||
|
!servizio.isOkSaldo
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<ServizioCard
|
||||||
|
content={
|
||||||
|
<>
|
||||||
|
<p className="font-medium text-lg">Servizio Scaduto</p>
|
||||||
|
<p>
|
||||||
|
Non è possibile riutilizzare questo servizio, poiché sono passati
|
||||||
|
più di 60 giorni dalla data di decorrenza senza che sia stato
|
||||||
|
effettuato il saldo.
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
header={
|
||||||
|
<>
|
||||||
|
<ServizioActions />
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
headerClassName="pb-0"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const annuncioConfermato = servizio.annunci.filter(
|
const annuncioConfermato = servizio.annunci.filter(
|
||||||
(a) => a.accettato_conferma_at !== null,
|
(a) => a.accettato_conferma_at !== null,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -184,39 +184,48 @@ const ServizioPacksInfos = () => {
|
||||||
});
|
});
|
||||||
if (!packs) return null;
|
if (!packs) return null;
|
||||||
return (
|
return (
|
||||||
<div className="space-y-2">
|
<div className="w-full space-y-2">
|
||||||
<h3 className="font-semibold text-lg">Prezzi:</h3>
|
<h3 className="font-semibold text-lg">Prezzi:</h3>
|
||||||
<div className="flex w-full flex-col gap-4 md:flex-row">
|
<div className="flex w-full flex-col gap-4 md:flex-row">
|
||||||
{packs.acconto && (
|
|
||||||
<div className="flex flex-1 flex-col gap-2 rounded-md bg-secondary/50 p-2">
|
<div className="flex flex-1 flex-col gap-2 rounded-md bg-secondary/50 p-2">
|
||||||
<span className="font-medium">{packs.acconto.nome_it}</span>
|
{packs.acconto.success ? (
|
||||||
|
<>
|
||||||
|
<span className="font-medium">{packs.acconto.pack.nome_it}</span>
|
||||||
<span className="text-muted-foreground text-sm">
|
<span className="text-muted-foreground text-sm">
|
||||||
{packs.acconto.desc_it}
|
{packs.acconto.pack.desc_it}
|
||||||
</span>
|
</span>
|
||||||
<span className="font-semibold text-lg">
|
<span className="font-semibold text-lg">
|
||||||
{formatCurrency(packs.acconto.prezzo_cent / 100)}
|
{formatCurrency(packs.acconto.pack.prezzo_cent / 100)}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-muted-foreground text-sm">
|
<span className="text-muted-foreground text-sm">
|
||||||
COD: {packs.acconto.idprezziario}
|
COD: {packs.acconto.pack.idprezziario}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</>
|
||||||
|
) : (
|
||||||
|
<span className="font-medium">{packs.acconto.message}</span>
|
||||||
)}
|
)}
|
||||||
{packs.saldo && (
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-1 flex-col gap-2 rounded-md bg-secondary/50 p-2">
|
<div className="flex flex-1 flex-col gap-2 rounded-md bg-secondary/50 p-2">
|
||||||
<span className="font-medium">{packs.saldo.nome_it}</span>
|
{packs.saldo.success ? (
|
||||||
|
<>
|
||||||
|
<span className="font-medium">{packs.saldo.pack.nome_it}</span>
|
||||||
<span className="text-muted-foreground text-sm">
|
<span className="text-muted-foreground text-sm">
|
||||||
{packs.saldo.desc_it}
|
{packs.saldo.pack.desc_it}
|
||||||
</span>
|
</span>
|
||||||
<span className="font-semibold text-lg">
|
<span className="font-semibold text-lg">
|
||||||
{formatCurrency(packs.saldo.prezzo_cent / 100)}
|
{formatCurrency(packs.saldo.pack.prezzo_cent / 100)}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-muted-foreground text-sm">
|
<span className="text-muted-foreground text-sm">
|
||||||
COD: {packs.saldo.idprezziario}
|
COD: {packs.saldo.pack.idprezziario}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</>
|
||||||
|
) : (
|
||||||
|
<span className="font-medium">{packs.saldo.message}</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export const AddAnnuncio = ({
|
export const AddAnnuncio = ({
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import {
|
||||||
getCompatibileAnnunci,
|
getCompatibileAnnunci,
|
||||||
getDataPerAcquisto,
|
getDataPerAcquisto,
|
||||||
getOrdineRicevutaData,
|
getOrdineRicevutaData,
|
||||||
getPackPerServizio,
|
getPacksPerServizio,
|
||||||
getPreOnboardData,
|
getPreOnboardData,
|
||||||
getServiziByUserId,
|
getServiziByUserId,
|
||||||
getServizioAnnuncio,
|
getServizioAnnuncio,
|
||||||
|
|
@ -51,7 +51,6 @@ import {
|
||||||
userAccettaConferma,
|
userAccettaConferma,
|
||||||
userSendConfermaIntent,
|
userSendConfermaIntent,
|
||||||
} from "~/server/controllers/servizio.controller";
|
} from "~/server/controllers/servizio.controller";
|
||||||
import { getPrezziarioByIdHandler } from "~/server/services/prezziario.service";
|
|
||||||
import {
|
import {
|
||||||
zAnnuncioId,
|
zAnnuncioId,
|
||||||
zOrdineId,
|
zOrdineId,
|
||||||
|
|
@ -349,25 +348,7 @@ export const servizioRouter = createTRPCRouter({
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.query(async ({ input }) => {
|
.query(async ({ input }) => {
|
||||||
const accontoId = await getPackPerServizio({
|
return await getPacksPerServizio(input.servizioId);
|
||||||
stage: "acconto",
|
|
||||||
servizioId: input.servizioId,
|
|
||||||
});
|
|
||||||
const saldoId = await getPackPerServizio({
|
|
||||||
stage: "saldo",
|
|
||||||
servizioId: input.servizioId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const acconto = accontoId.success
|
|
||||||
? await getPrezziarioByIdHandler({ id: accontoId.packId })
|
|
||||||
: null;
|
|
||||||
const saldo = saldoId.success
|
|
||||||
? await getPrezziarioByIdHandler({ id: saldoId.packId })
|
|
||||||
: null;
|
|
||||||
return {
|
|
||||||
acconto,
|
|
||||||
saldo,
|
|
||||||
};
|
|
||||||
}),
|
}),
|
||||||
unlockServizioContatti: protectedProcedure
|
unlockServizioContatti: protectedProcedure
|
||||||
.input(
|
.input(
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ import { NewMail, type NewMailProps } from "~/server/services/mailer";
|
||||||
import { getUser } from "~/server/services/user.service";
|
import { getUser } from "~/server/services/user.service";
|
||||||
import { withImages, withVideos } from "~/utils/kysely-helper";
|
import { withImages, withVideos } from "~/utils/kysely-helper";
|
||||||
import { GetUserInterests } from "../services/interests.service";
|
import { GetUserInterests } from "../services/interests.service";
|
||||||
|
import { getPrezziarioByIdHandler } from "../services/prezziario.service";
|
||||||
import type { AnnuncioRicerca } from "./annunci.controller";
|
import type { AnnuncioRicerca } from "./annunci.controller";
|
||||||
|
|
||||||
export const addServizio = async (data: NewServizio) => {
|
export const addServizio = async (data: NewServizio) => {
|
||||||
|
|
@ -507,40 +508,58 @@ const ConsulenzaPriceMapping = {
|
||||||
};
|
};
|
||||||
|
|
||||||
type GetPackError = { success: false; message: string };
|
type GetPackError = { success: false; message: string };
|
||||||
type GetPackResult = { success: true; packId: PrezziarioIdprezziario };
|
type GetPackResult = { success: true; pack: Prezziario };
|
||||||
|
|
||||||
export const getPackPerServizio = async ({
|
type ServizioPacks = {
|
||||||
stage,
|
acconto: GetPackResult | GetPackError;
|
||||||
servizioId,
|
saldo: GetPackResult | GetPackError;
|
||||||
}: {
|
};
|
||||||
stage: "acconto" | "saldo";
|
export const getPacksPerServizio = async (
|
||||||
servizioId: ServizioServizioId;
|
servizioId: ServizioServizioId,
|
||||||
}): Promise<GetPackResult | GetPackError> => {
|
): Promise<ServizioPacks> => {
|
||||||
const servizio = await getServizioById(servizioId);
|
const servizio = await getServizioById(servizioId);
|
||||||
if (!servizio) {
|
if (!servizio) {
|
||||||
return { success: false, message: "Servizio not found" };
|
throw new TRPCError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Servizio non trovato",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
switch (stage) {
|
|
||||||
case "acconto": {
|
const getAcconto = async (): Promise<GetPackResult | GetPackError> => {
|
||||||
switch (servizio.tipologia) {
|
switch (servizio.tipologia) {
|
||||||
case TipologiaPosizioneEnum.Transitorio: {
|
case TipologiaPosizioneEnum.Transitorio: {
|
||||||
|
const pack = await getPrezziarioByIdHandler({
|
||||||
|
id: "ACCONTO_BD" as PrezziarioIdprezziario,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!pack) {
|
||||||
|
return { success: false, message: "Pack non trovato" };
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
packId: "ACCONTO_BD" as PrezziarioIdprezziario,
|
pack,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case TipologiaPosizioneEnum.Stabile: {
|
case TipologiaPosizioneEnum.Stabile: {
|
||||||
|
const pack = await getPrezziarioByIdHandler({
|
||||||
|
id: "ACCONTO_CA" as PrezziarioIdprezziario,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!pack) {
|
||||||
|
return { success: false, message: "Pack non trovato" };
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
packId: "ACCONTO_CA" as PrezziarioIdprezziario,
|
pack,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return { success: false, message: "Invalid tipologia" };
|
return { success: false, message: "Seleziona tipologia" };
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
case "saldo": {
|
|
||||||
|
const getSaldo = async (): Promise<GetPackResult | GetPackError> => {
|
||||||
switch (servizio.tipologia) {
|
switch (servizio.tipologia) {
|
||||||
case TipologiaPosizioneEnum.Transitorio: {
|
case TipologiaPosizioneEnum.Transitorio: {
|
||||||
const mpp =
|
const mpp =
|
||||||
|
|
@ -548,31 +567,39 @@ export const getPackPerServizio = async ({
|
||||||
if (!servizio.permanenza || !mpp) {
|
if (!servizio.permanenza || !mpp) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: "Permanenza not set for transitorio servizio",
|
message: "Permanenza non selezionata",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return { success: true, packId: mpp };
|
const pack = await getPrezziarioByIdHandler({ id: mpp });
|
||||||
}
|
if (!pack) {
|
||||||
case TipologiaPosizioneEnum.Stabile: {
|
return { success: false, message: "Pack non trovato" };
|
||||||
if (servizio.budget >= 500) {
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
packId: "SALDOCA500+" as PrezziarioIdprezziario,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
packId: "SALDOCA500" as PrezziarioIdprezziario,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return { success: false, message: "Invalid tipologia" };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
return { success: true, pack };
|
||||||
return { success: false, message: "Invalid stage" };
|
|
||||||
}
|
}
|
||||||
|
case TipologiaPosizioneEnum.Stabile: {
|
||||||
|
const pack = await getPrezziarioByIdHandler({
|
||||||
|
id: (servizio.budget >= 500
|
||||||
|
? "SALDOCA500+"
|
||||||
|
: "SALDOCA500") as PrezziarioIdprezziario,
|
||||||
|
});
|
||||||
|
if (!pack) {
|
||||||
|
return { success: false, message: "Pack non trovato" };
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
pack,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return { success: false, message: "Seleziona tipologia" };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
acconto: await getAcconto(),
|
||||||
|
saldo: await getSaldo(),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
type TipoEnum = keyof typeof ConsulenzaPriceMapping;
|
type TipoEnum = keyof typeof ConsulenzaPriceMapping;
|
||||||
export const setupSaldoConsulenzaServizio = async ({
|
export const setupSaldoConsulenzaServizio = async ({
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue