This commit is contained in:
David Arranz 2026-06-29 12:47:03 +02:00
parent 4ebbb3b5c4
commit cc90f64cb4
9 changed files with 0 additions and 197 deletions

View File

@ -1,3 +0,0 @@
export * from "./proforma-create-form.entity";
export * from "./proforma-create-form.schema";
export * from "./proforma-create-form-default.entity";

View File

@ -1,49 +0,0 @@
/**
* Valor por defecto para el formulario de creación de proformas.
*
* Reglas:
* - debe ser un objeto que cumpla con la interfaz ProformaCreateForm
* - debe tener valores por defecto razonables para cada campo, evitando campos vacíos o nulos cuando sea posible
* - el shape del objeto debe coincidir exactamente con el de ProformaCreateForm, sin campos adicionales ni transformaciones
* - orientado a la UI, no a la API ni al dominio, es decir, debe ser un objeto que se pueda usar directamente para inicializar un formulario en la interfaz de usuario
*/
export const defaultProformaCreateForm: ProformaCreateForm = {
invoiceNumber: "",
series: "",
invoiceDate: "",
operationDate: "",
customerId: "",
reference: "",
isCompany: true,
name: "",
tradeName: "",
tin: "",
defaultTaxes: [],
street: "",
street2: "",
city: "",
province: "",
postalCode: "",
country: "es",
primaryEmail: "",
secondaryEmail: "",
primaryPhone: "",
secondaryPhone: "",
primaryMobile: "",
secondaryMobile: "",
fax: "",
website: "",
legalRecord: "",
languageCode: "es",
currencyCode: "EUR",
};

View File

@ -1,37 +0,0 @@
/**
* ProformaCreateForm representa el shape de datos del formulario de creación de proforma.
* Es decir, los campos que se muestran en el formulario y que el usuario puede editar.
*
* Este shape es específico para la UI y no tiene por qué coincidir
* con el shape del dominio ni con el de la API.
*
* Debe cumplir las siguientes reglas:
* - nombres en camelCase
* - tipos orientados a UI/form
* - sin campos de solo lectura que no se editen
* - sin shape DTO
* - sin detalles impuestos por el widget
*/
import type { ProformaItemForm } from "../../shared/entities";
export interface ProformaCreateForm {
series: string;
invoiceDate: string;
operationDate: string;
customerId: string;
reference: string;
notes: string;
languageCode: string;
currencyCode: string;
globalDiscountPercentage: number;
paymentMethod: string;
items: ProformaItemForm[];
}

View File

@ -1,48 +0,0 @@
import { z } from "zod/v4";
/**
* Este esquema es para validar los datos del formulario de creación de cliente.
* No tiene por qué coincidir con el shape de la entidad ni con el de la API.
* Solo define los campos que se muestran en el formulario y sus validaciones.
*
* Reglas:
* - no meter transformaciones silenciosas raras en el esquema (ej: .toUpperCase())
* - nombres en camelCase
* - tipos orientados a UI/form
* - sin campos de solo lectura que no se editen
* - sin shape DTO
* - sin detalles impuestos por el widget
*/
export const CustomerCreateFormSchema = z.object({
reference: z.string(),
isCompany: z.boolean(),
name: z.string().min(1, "El nombre es obligatorio"),
tradeName: z.string(),
tin: z.string(),
defaultTaxes: z.array(z.string()),
street: z.string(),
street2: z.string(),
city: z.string(),
province: z.string(),
postalCode: z.string(),
country: z.string().min(1, "El país es obligatorio"),
primaryEmail: z.email("Email inválido"),
secondaryEmail: z.email("Email inválido"),
primaryPhone: z.string(),
secondaryPhone: z.string(),
primaryMobile: z.string(),
secondaryMobile: z.string(),
fax: z.string(),
website: z.url("URL inválida"),
legalRecord: z.string(),
languageCode: z.string().min(1, "El idioma es obligatorio"),
currencyCode: z.string().min(1, "La moneda es obligatoria"),
});

View File

@ -1,9 +0,0 @@
export interface ProformaItemForm {
id: string;
position: string;
description: string;
quantity: number;
unitAmount: number;
discountPercentage: number;
taxes: string;
}

View File

@ -1 +0,0 @@
export * from "./ui";

View File

@ -1 +0,0 @@
export * from "./pages";

View File

@ -1 +0,0 @@
export * from "./proforma-create-page";

View File

@ -1,48 +0,0 @@
import { PageHeader } from "@erp/core/components";
import { UnsavedChangesProvider } from "@erp/core/hooks";
import { AppContent, AppHeader } from "@repo/rdx-ui/components";
import { Button } from "@repo/shadcn-ui/components";
import { PlusIcon } from "lucide-react";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "../../../../i18n";
export const ProformaCreatePage = () => {
const { t } = useTranslation();
const navigate = useNavigate();
return (
<UnsavedChangesProvider isDirty={true}>
<AppHeader>
<PageHeader
description={t("pages.proformas.list.description")}
rightSlot={
<Button
aria-label={t("pages.proformas.create.title")}
onClick={() => navigate("/proformas/create")}
>
<PlusIcon aria-hidden className="mr-2 size-4" />
{t("pages.proformas.create.title")}
</Button>
}
title={t("pages.proformas.list.title")}
/>
</AppHeader>
<AppContent>
<div className="flex items-center justify-between space-y-2">
<div>
<h2 className="text-2xl font-bold tracking-tight">{t("pages.create.title")}</h2>
<p className="text-muted-foreground">{t("pages.create.description")}</p>
</div>
<div className="flex items-center justify-end mb-4">
<Button className="cursor-pointer" onClick={() => navigate("/customer-invoices/list")}>
{t("pages.create.back_to_list")}
</Button>
</div>
</div>
<div className="flex flex-1 flex-col gap-4 p-4">hola</div>
</AppContent>
</UnsavedChangesProvider>
);
};