fix: update payment method type in PurchaseData and related components

This commit is contained in:
Marco Pedone 2026-03-09 18:14:22 +01:00
parent 50ba1d4c5d
commit a9a9104711
5 changed files with 185 additions and 118 deletions

View file

@ -77,7 +77,7 @@ export type PurchaseData = {
clienteNome: string;
clienteIndirizzo: string;
paymentMethod: string;
paymentMethod: PaymentType;
packName: string;
sconto: number;
@ -186,7 +186,7 @@ function Receipt({ data }: ReceiptProps) {
<div className="flex justify-between">
<div>
<h3 className="mb-1 font-semibold">Metodo di pagamento</h3>
<p>{PaymentMethodToString(data.paymentMethod as PaymentType)}</p>
<p>{PaymentMethodToString(data.paymentMethod)}</p>
</div>
<div className="text-right">
<h3 className="mb-1 font-semibold">Status pagamento</h3>

View file

@ -15,7 +15,6 @@ import { Button } from "~/components/ui/button";
import { FormEditOrder } from "~/forms/FormEditOrdine";
import { formatCurrency } from "~/lib/utils";
import type { OrdiniOrdineId } from "~/schemas/public/Ordini";
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum";
import type { Prezziario } from "~/schemas/public/Prezziario";
import { api } from "~/utils/api";
@ -68,14 +67,16 @@ const AdminOrdiniModal = ({
<CredenzaBody className="max-h-[80vh] space-y-2 overflow-auto pb-5">
<p>Id Ordine: {data.ordine_id}</p>
{data.isActive && (
<Link
href={`/servizio/ricevuta-cortesia/${data.ordine_id}`}
target="_blank"
>
<Button variant="outline">
Ricevuta di cortesia <ReceiptText />
</Button>
</Link>
<div>
<Link
href={`/servizio/ricevuta-cortesia/${data.ordine_id}`}
target="_blank"
>
<Button variant="outline">
Ricevuta di cortesia <ReceiptText />
</Button>
</Link>
</div>
)}
<FormEditOrder
close={() => setSelected(null)}
@ -139,19 +140,18 @@ export const UserOrdiniModal = ({
Importo: {formatCurrency(data.amount_cent / 100)}{" "}
{data.sconto > 0 && <span>({data.sconto}%)</span>}
</p>
{data.isActive &&
data.paymentstatus === PaymentStatusEnum.success && (
<div>
<Link
href={`/servizio/ricevuta-cortesia/${data.ordine_id}`}
target="_blank"
>
<Button variant="outline">
Ricevuta di cortesia <ReceiptText />
</Button>
</Link>
</div>
)}
{data.isActive && (
<div>
<Link
href={`/servizio/ricevuta-cortesia/${data.ordine_id}`}
target="_blank"
>
<Button variant="outline">
Ricevuta di cortesia <ReceiptText />
</Button>
</Link>
</div>
)}
</CredenzaBody>
<CredenzaFooter className="flex w-full sm:justify-end">
<CredenzaClose asChild>

View file

@ -35,7 +35,7 @@ function SelectTrigger({
return (
<SelectPrimitive.Trigger
className={cn(
"flex w-fit items-center justify-between gap-2 whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-hidden transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[size=default]:h-9 data-[size=sm]:h-8 data-placeholder:text-muted-foreground *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:aria-invalid:ring-destructive/40 dark:hover:bg-input/50 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0",
"flex w-fit items-center justify-between gap-2 whitespace-nowrap rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs outline-hidden transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[size=default]:h-9 data-[size=sm]:h-8 data-placeholder:text-muted-foreground *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:aria-invalid:ring-destructive/40 dark:hover:bg-input/50 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0",
className,
)}
data-size={size}

View file

@ -107,99 +107,101 @@ export const FormEditOrder = ({ prezziario, data, close }: FormProps) => {
<>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<CredenzaBody className="max-h-[80vh] w-full pb-5">
<div className="space-y-8 px-0.5">
<FormField
control={form.control}
name="packid"
render={({ field }) => {
const pack = prezziario.find(
(p) => p.idprezziario === field.value,
);
return (
<FormItem className="w-full">
<CredenzaBody className="max-h-[80vh] w-full px-0 py-4">
<div className="flex flex-col gap-4 sm:gap-6 sm:px-0.5">
<div className="grid grid-cols-1 items-center gap-4 sm:grid-cols-2 sm:gap-6">
<FormField
control={form.control}
name="packid"
render={({ field }) => {
const pack = prezziario.find(
(p) => p.idprezziario === field.value,
);
return (
<FormItem className="w-full">
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="select-pack">Servizio</FormLabel>
<FormMessage />
</div>
<FormControl>
<MultiSelect
defaultValue={
field.value
? {
label: pack?.nome_it || "",
value: field.value,
}
: undefined
}
elementId="select-pack"
elementName="packid"
isMulti={false}
onValueChange={(value) => {
const selected = zPrezziarioId.safeParse(
value.value,
);
if (selected.success) {
field.onChange(selected.data);
const selectedPrezzo = prezziario.find(
(p) => p.idprezziario === selected.data,
);
if (selectedPrezzo) {
form.setValue(
"amount_cent",
selectedPrezzo.prezzo_cent,
);
}
} else {
console.error(
"Invalid packid selected",
value.value,
);
}
}}
options={prezziario.map((p) => ({
label: `${p.idprezziario} - ${p.nome_it} (${formatCurrency(p.prezzo_cent / 100)})`,
value: p.idprezziario,
}))}
placeholder="Seleziona..."
/>
</FormControl>
</FormItem>
);
}}
/>
<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="select-pack">Servizio</FormLabel>
<FormLabel htmlFor="titolo">Tipologia</FormLabel>
<FormMessage />
</div>
<FormControl>
<MultiSelect
defaultValue={
field.value
? {
label: pack?.nome_it || "",
value: field.value,
}
: undefined
}
elementId="select-pack"
elementName="packid"
isMulti={false}
onValueChange={(value) => {
const selected = zPrezziarioId.safeParse(
value.value,
);
if (selected.success) {
field.onChange(selected.data);
const selectedPrezzo = prezziario.find(
(p) => p.idprezziario === selected.data,
);
if (selectedPrezzo) {
form.setValue(
"amount_cent",
selectedPrezzo.prezzo_cent,
);
}
} else {
console.error(
"Invalid packid selected",
value.value,
);
}
}}
options={prezziario.map((p) => ({
label: `${p.idprezziario} - ${p.nome_it} (${formatCurrency(p.prezzo_cent / 100)})`,
value: p.idprezziario,
}))}
placeholder="Seleziona..."
/>
<Select
defaultValue={field.value || ""}
onValueChange={field.onChange}
>
<FormControl>
<SelectTrigger className="w-full">
<SelectValue placeholder="Seleziona tipologia" />
</SelectTrigger>
</FormControl>
<SelectContent id="select-color">
{Object.values(OrderTypeEnum).map((option) => (
<SelectItem key={option} value={option}>
{option}
</SelectItem>
))}
</SelectContent>
</Select>
</FormControl>
</FormItem>
);
}}
/>
<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="titolo">Tipologia</FormLabel>
<FormMessage />
</div>
<FormControl>
<Select
defaultValue={field.value || ""}
onValueChange={field.onChange}
>
<FormControl>
<SelectTrigger className="w-full">
<SelectValue placeholder="Seleziona tipologia" />
</SelectTrigger>
</FormControl>
<SelectContent id="select-color">
{Object.values(OrderTypeEnum).map((option) => (
<SelectItem key={option} value={option}>
{option}
</SelectItem>
))}
</SelectContent>
</Select>
</FormControl>
</FormItem>
)}
/>
)}
/>
</div>
<FormField
control={form.control}
name="created_at"
@ -254,7 +256,7 @@ export const FormEditOrder = ({ prezziario, data, close }: FormProps) => {
render={({ field }) => (
<FormItem className="w-full">
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="isActive">Pagato</FormLabel>
<FormLabel htmlFor="isActive">Attivo</FormLabel>
<FormControl>
<Switch
className="data-[state=checked]:bg-neutral-700"
@ -272,6 +274,72 @@ export const FormEditOrder = ({ prezziario, data, close }: FormProps) => {
</FormItem>
)}
/>
<div className="grid grid-cols-1 items-center gap-4 sm:grid-cols-2 sm:gap-6">
<FormField
control={form.control}
name="paymentstatus"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="titolo">Stato Pagameto</FormLabel>
<FormMessage />
</div>
<FormControl>
<Select
defaultValue={field.value || ""}
onValueChange={field.onChange}
>
<FormControl>
<SelectTrigger className="w-full">
<SelectValue placeholder="Seleziona tipologia" />
</SelectTrigger>
</FormControl>
<SelectContent id="select-paymentstatus">
{Object.values(PaymentStatusEnum).map((option) => (
<SelectItem key={option} value={option}>
{option}
</SelectItem>
))}
</SelectContent>
</Select>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="paymentmethod"
render={({ field }) => (
<FormItem>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="titolo">
Metodo di Pagamento
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Select
defaultValue={field.value || ""}
onValueChange={field.onChange}
>
<FormControl>
<SelectTrigger className="w-full">
<SelectValue placeholder="Seleziona tipologia" />
</SelectTrigger>
</FormControl>
<SelectContent id="select-paymentmethod">
{Object.values(PAYMENT_TYPES).map((option) => (
<SelectItem key={option} value={option}>
{option}
</SelectItem>
))}
</SelectContent>
</Select>
</FormControl>
</FormItem>
)}
/>
</div>
<FormField
control={form.control}
name="sconto"

View file

@ -2,12 +2,11 @@ import { TRPCError } from "@trpc/server";
import { add } from "date-fns";
import { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/postgres";
import { z } from "zod/v4";
import type { PurchaseData } from "~/components/acquisto_receipt";
import { env } from "~/env";
import type { PaymentType } from "~/i18n/stripe";
import type { Annunci, AnnunciId } from "~/schemas/public/Annunci";
import OrderTypeEnum from "~/schemas/public/OrderTypeEnum";
import type { Ordini, OrdiniOrdineId } from "~/schemas/public/Ordini";
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum";
import type { Prezziario } from "~/schemas/public/Prezziario";
import type {
Servizio,
@ -1348,7 +1347,7 @@ export const getOrdineRicevutaData = async ({
.innerJoin("prezziario", "prezziario.idprezziario", "ordini.packid")
.select("prezziario.nome_it")
.where("ordini.ordine_id", "=", ordineId)
.where("ordini.paymentstatus", "=", PaymentStatusEnum.success)
//.where("ordini.paymentstatus", "=", PaymentStatusEnum.success)
.executeTakeFirstOrThrow(
() => new Error(`Ordine not found - ordineId: ${ordineId}`),
@ -1381,8 +1380,8 @@ export const getOrdineRicevutaData = async ({
amount_cent: data.amount_cent,
ordineId: data.ordine_id,
paymentMethod: data.paymentmethod,
} as PurchaseData;
paymentMethod: (data.paymentmethod || "manual") as PaymentType,
};
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",