.
This commit is contained in:
parent
05f4b1337b
commit
a464f9b14e
@ -1,8 +1,9 @@
|
||||
import { type StartParams } from "@erp/core/api";
|
||||
import type { StartParams } from "@erp/core/api";
|
||||
import { requireIdentityTenant } from "@erp/identity/api";
|
||||
import { type NextFunction, type Request, type Response, Router } from "express";
|
||||
|
||||
import type { InvoiceSeriesInternalDeps } from "../di/invoice-series.di";
|
||||
|
||||
import { ListInvoiceSeriesController } from "./controllers";
|
||||
|
||||
export const invoiceSeriesRouter = (params: StartParams) => {
|
||||
@ -20,5 +21,5 @@ export const invoiceSeriesRouter = (params: StartParams) => {
|
||||
return controller.execute(req, res, next);
|
||||
});
|
||||
|
||||
app.use(`${config.server.apiBasePath}/invoice-series`, router);
|
||||
app.use(`${config.server.apiBasePath}/catalogs/invoice-series`, router);
|
||||
};
|
||||
|
||||
@ -1,7 +1,4 @@
|
||||
import {
|
||||
SequelizeRepository,
|
||||
translateSequelizeError,
|
||||
} from "@erp/core/api";
|
||||
import { SequelizeRepository, translateSequelizeError } from "@erp/core/api";
|
||||
import type { UniqueID } from "@repo/rdx-ddd";
|
||||
import { Collection, Result } from "@repo/rdx-utils";
|
||||
import type { Sequelize, Transaction } from "sequelize";
|
||||
@ -11,7 +8,7 @@ import {
|
||||
InvoiceSeriesConcurrencyError,
|
||||
InvoiceSeriesLockRequiredError,
|
||||
InvoiceSeriesTransactionRequiredError,
|
||||
} from "../../../../../application/invoice-series";
|
||||
} from "../../../../../application";
|
||||
import type { InvoiceSeries, InvoiceSeriesCode } from "../../../../../domain";
|
||||
import { CustomerInvoiceSeriesModel } from "../../../../common";
|
||||
import type { InvoiceSeriesDomainMapper } from "../mappers";
|
||||
@ -27,10 +24,7 @@ export class SequelizeInvoiceSeriesRepository
|
||||
super({ database });
|
||||
}
|
||||
|
||||
public async findActiveByCompany(params: {
|
||||
companyId: UniqueID;
|
||||
transaction?: unknown;
|
||||
}) {
|
||||
public async findActiveByCompany(params: { companyId: UniqueID; transaction?: unknown }) {
|
||||
try {
|
||||
const rows = await CustomerInvoiceSeriesModel.findAll({
|
||||
where: {
|
||||
|
||||
@ -16,10 +16,14 @@ import { useEffect, useId, useMemo, useState } from "react";
|
||||
import type { FieldErrors } from "react-hook-form";
|
||||
|
||||
import type { Proforma } from "../../shared";
|
||||
import { useProformaCreateMutation, useProformasListQuery } from "../../shared/hooks";
|
||||
import {
|
||||
buildInvoiceSeriesSelectItems,
|
||||
useInvoiceSeriesQuery,
|
||||
useProformaCreateMutation,
|
||||
} from "../../shared";
|
||||
import { buildCreateProformaParams } from "../adapters";
|
||||
import { type ProformaCreateForm, ProformaCreateFormSchema } from "../entities";
|
||||
import { buildProformaCreateDefault, buildProformaSeriesOptions } from "../utils";
|
||||
import { buildProformaCreateDefault } from "../utils";
|
||||
|
||||
export interface UseCreateProformaControllerOptions {
|
||||
onCreated?(proforma: Proforma): void;
|
||||
@ -48,12 +52,7 @@ export const useCreateProformaController = (options?: UseCreateProformaControlle
|
||||
error: createError,
|
||||
} = useProformaCreateMutation();
|
||||
|
||||
const seriesQuery = useProformasListQuery({
|
||||
criteria: {
|
||||
pageNumber: 1,
|
||||
pageSize: 100,
|
||||
},
|
||||
});
|
||||
const seriesQuery = useInvoiceSeriesQuery();
|
||||
|
||||
const initialValues = useMemo<ProformaCreateForm>(() => buildProformaCreateDefault(), []);
|
||||
|
||||
@ -64,20 +63,28 @@ export const useCreateProformaController = (options?: UseCreateProformaControlle
|
||||
});
|
||||
|
||||
const seriesOptions = useMemo(
|
||||
() => buildProformaSeriesOptions(seriesQuery.data),
|
||||
() => buildInvoiceSeriesSelectItems(seriesQuery.data ?? []),
|
||||
[seriesQuery.data]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (seriesOptions.length !== 1) return;
|
||||
if (form.getValues("series")) return;
|
||||
const defaultSeries = useMemo(() => {
|
||||
const invoiceSeries = seriesQuery.data ?? [];
|
||||
|
||||
form.setValue("series", seriesOptions[0].value, {
|
||||
return (
|
||||
invoiceSeries.find((series) => series.isDefault)?.code ?? invoiceSeries[0]?.code ?? ""
|
||||
);
|
||||
}, [seriesQuery.data]);
|
||||
|
||||
useEffect(() => {
|
||||
if (form.getValues("series")) return;
|
||||
if (!defaultSeries) return;
|
||||
|
||||
form.setValue("series", defaultSeries, {
|
||||
shouldDirty: false,
|
||||
shouldTouch: false,
|
||||
shouldValidate: true,
|
||||
});
|
||||
}, [form, seriesOptions]);
|
||||
}, [defaultSeries, form]);
|
||||
|
||||
const setCustomer = (customer: CustomerSelectionOption) => {
|
||||
setSelectedCustomer(customer);
|
||||
@ -163,8 +170,8 @@ export const useCreateProformaController = (options?: UseCreateProformaControlle
|
||||
setCustomer,
|
||||
clearCustomer,
|
||||
seriesOptions,
|
||||
isLoading: seriesQuery.isLoading,
|
||||
isLoadError: seriesQuery.isError,
|
||||
loadError: seriesQuery.error,
|
||||
isSeriesLoading: seriesQuery.isLoading,
|
||||
isSeriesLoadError: seriesQuery.isError,
|
||||
seriesLoadError: seriesQuery.error,
|
||||
};
|
||||
};
|
||||
|
||||
@ -9,6 +9,7 @@ import { ProformaCreateInitialInfoCard } from "./proforma-create-initial-info-ca
|
||||
interface ProformaCreateFormProps {
|
||||
formId: string;
|
||||
isSubmitting: boolean;
|
||||
isSeriesLoading?: boolean;
|
||||
onSubmit: React.SubmitEventHandler<HTMLFormElement>;
|
||||
selectedCustomer?: CustomerSelectionOption | null;
|
||||
onSelectCustomer: () => void;
|
||||
@ -20,6 +21,7 @@ interface ProformaCreateFormProps {
|
||||
export const ProformaCreateForm = ({
|
||||
formId,
|
||||
isSubmitting,
|
||||
isSeriesLoading = false,
|
||||
onSubmit,
|
||||
selectedCustomer,
|
||||
onSelectCustomer,
|
||||
@ -33,6 +35,7 @@ export const ProformaCreateForm = ({
|
||||
<div className="space-y-6">
|
||||
<ProformaCreateInitialInfoCard
|
||||
disabled={isSubmitting}
|
||||
isSeriesLoading={isSeriesLoading}
|
||||
onClearCustomer={onClearCustomer}
|
||||
onSelectCustomer={onSelectCustomer}
|
||||
selectedCustomer={selectedCustomer}
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
import { DatePickerField, FormSectionCard, FormSectionGrid, SelectField } from "@repo/rdx-ui/components";
|
||||
import {
|
||||
DatePickerField,
|
||||
FormSectionCard,
|
||||
FormSectionGrid,
|
||||
SelectField,
|
||||
type SelectFieldItem,
|
||||
} from "@repo/rdx-ui/components";
|
||||
import { FileTextIcon } from "lucide-react";
|
||||
|
||||
import type { CustomerSelectionOption } from "@erp/customers";
|
||||
@ -8,14 +14,16 @@ import { ProformaCreateCustomerField } from "./proforma-create-customer-field";
|
||||
|
||||
interface ProformaCreateInitialInfoCardProps {
|
||||
disabled?: boolean;
|
||||
isSeriesLoading?: boolean;
|
||||
selectedCustomer?: CustomerSelectionOption | null;
|
||||
onSelectCustomer: () => void;
|
||||
onClearCustomer: () => void;
|
||||
seriesOptions: { value: string; label: string }[];
|
||||
seriesOptions: SelectFieldItem[];
|
||||
}
|
||||
|
||||
export const ProformaCreateInitialInfoCard = ({
|
||||
disabled = false,
|
||||
isSeriesLoading = false,
|
||||
selectedCustomer,
|
||||
onSelectCustomer,
|
||||
onClearCustomer,
|
||||
@ -44,11 +52,17 @@ export const ProformaCreateInitialInfoCard = ({
|
||||
|
||||
<SelectField<ProformaCreateForm>
|
||||
className="md:col-span-4"
|
||||
disabled={disabled}
|
||||
disabled={disabled || isSeriesLoading}
|
||||
items={seriesOptions}
|
||||
label="Serie"
|
||||
name="series"
|
||||
placeholder={seriesOptions.length > 0 ? "Selecciona una serie" : "Sin serie"}
|
||||
placeholder={
|
||||
isSeriesLoading
|
||||
? "Cargando series..."
|
||||
: seriesOptions.length > 0
|
||||
? "Selecciona una serie"
|
||||
: "Sin serie"
|
||||
}
|
||||
/>
|
||||
</FormSectionGrid>
|
||||
</FormSectionCard>
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
import { ErrorAlert } from "@erp/core/components";
|
||||
import { UnsavedChangesProvider, useReturnToNavigation } from "@erp/core/hooks";
|
||||
import { SelectCustomerDialog } from "@erp/customers";
|
||||
import { AppContent, BackHistoryButton } from "@repo/rdx-ui/components";
|
||||
import { FormProvider } from "react-hook-form";
|
||||
|
||||
import { ProformaInfoAlert } from "../../../update/ui/components";
|
||||
import { useCreateProformaPageController } from "../../controllers";
|
||||
import { ProformaCreateForm, ProformaCreateHeader } from "../blocks";
|
||||
import { ProformaCreateSkeleton } from "../components";
|
||||
|
||||
export const ProformaCreatePage = () => {
|
||||
const { createCtrl, selectCustomerCtrl, returnTo } = useCreateProformaPageController();
|
||||
@ -16,29 +14,6 @@ export const ProformaCreatePage = () => {
|
||||
fallbackPath: returnTo,
|
||||
});
|
||||
|
||||
if (createCtrl.isLoading) {
|
||||
return <ProformaCreateSkeleton />;
|
||||
}
|
||||
|
||||
if (createCtrl.isLoadError) {
|
||||
return (
|
||||
<AppContent>
|
||||
<ErrorAlert
|
||||
message={
|
||||
createCtrl.loadError instanceof Error
|
||||
? createCtrl.loadError.message
|
||||
: "Inténtalo de nuevo más tarde."
|
||||
}
|
||||
title="No se pudo preparar la creación de la proforma"
|
||||
/>
|
||||
|
||||
<div className="flex items-center justify-end">
|
||||
<BackHistoryButton onClick={() => navigateBack()} />
|
||||
</div>
|
||||
</AppContent>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 flex flex-col overflow-hidden">
|
||||
<FormProvider {...createCtrl.form}>
|
||||
@ -65,9 +40,21 @@ export const ProformaCreatePage = () => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{createCtrl.isSeriesLoadError && (
|
||||
<ErrorAlert
|
||||
message={
|
||||
createCtrl.seriesLoadError instanceof Error
|
||||
? createCtrl.seriesLoadError.message
|
||||
: "Inténtalo de nuevo más tarde."
|
||||
}
|
||||
title="No se pudieron cargar las series de facturación"
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
<ProformaCreateForm
|
||||
formId={createCtrl.formId}
|
||||
isSeriesLoading={createCtrl.isSeriesLoading}
|
||||
isSubmitting={createCtrl.isCreating}
|
||||
onClearCustomer={createCtrl.clearCustomer}
|
||||
onSelectCustomer={selectCustomerCtrl.selectCtrl.openDialog}
|
||||
|
||||
@ -6,7 +6,7 @@ export const buildProformaCreateDefault = (): ProformaCreateForm => {
|
||||
return {
|
||||
customerId: "",
|
||||
invoiceDate: DateHelper.buildTodayIsoDate(),
|
||||
series: "F26",
|
||||
series: "",
|
||||
languageCode: "es",
|
||||
currencyCode: "EUR",
|
||||
};
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
import type { SelectFieldItem } from "@repo/rdx-ui/components";
|
||||
|
||||
import type { ProformaList } from "../../shared";
|
||||
|
||||
export const buildProformaSeriesOptions = (proformas?: ProformaList): SelectFieldItem[] => {
|
||||
const uniqueSeries = new Set<string>();
|
||||
|
||||
for (const item of proformas?.items ?? []) {
|
||||
const value = item.series?.trim();
|
||||
if (!value) continue;
|
||||
uniqueSeries.add(value);
|
||||
}
|
||||
|
||||
return [...uniqueSeries]
|
||||
.sort((left, right) => left.localeCompare(right))
|
||||
.map((value) => ({ value, label: value }));
|
||||
};
|
||||
@ -1,2 +1 @@
|
||||
export * from "./build-proforma-create-default";
|
||||
export * from "./build-proforma-series-options";
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
export * from "./get-proforma-by-id.adapter";
|
||||
export * from "./list-invoice-series.adapter";
|
||||
export * from "./list-proformas.adapter";
|
||||
export * from "./proforma-to-list-row-patch.adapter";
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
import type { ListInvoiceSeriesResponseDTO } from "../../../../common";
|
||||
import type { InvoiceSeriesSummary } from "../entities";
|
||||
|
||||
export const mapInvoiceSeriesSummaryDTOToInvoiceSeriesSummary = (
|
||||
dto: ListInvoiceSeriesResponseDTO["items"][number]
|
||||
): InvoiceSeriesSummary => ({
|
||||
id: dto.id,
|
||||
code: dto.code,
|
||||
nextNumber: dto.next_number,
|
||||
paddingLength: dto.padding_length,
|
||||
isDefault: dto.is_default,
|
||||
});
|
||||
|
||||
export const ListInvoiceSeriesAdapter = {
|
||||
fromDto(dto: ListInvoiceSeriesResponseDTO): InvoiceSeriesSummary[] {
|
||||
return dto.items.map(mapInvoiceSeriesSummaryDTOToInvoiceSeriesSummary);
|
||||
},
|
||||
};
|
||||
@ -3,5 +3,6 @@ export * from "./create-proforma.api";
|
||||
export * from "./delete-proforma-by-id.api";
|
||||
export * from "./get-proforma-by-id.api";
|
||||
export * from "./issue-proforma-by-id.api";
|
||||
export * from "./list-invoice-series.api";
|
||||
export * from "./list-proformas-by-criteria.api";
|
||||
export * from "./update-proforma-by-id.api";
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
import type { IDataSource } from "@erp/core/client";
|
||||
|
||||
import type { ListInvoiceSeriesResponseDTO } from "../../../../common";
|
||||
|
||||
export const listInvoiceSeries = (
|
||||
dataSource: IDataSource,
|
||||
signal?: AbortSignal
|
||||
): Promise<ListInvoiceSeriesResponseDTO> => {
|
||||
return dataSource.getList<ListInvoiceSeriesResponseDTO>("catalogs/invoice-series", {
|
||||
signal,
|
||||
});
|
||||
};
|
||||
@ -1,4 +1,5 @@
|
||||
export * from "./forms/proforma-item-form.entity";
|
||||
export * from "./invoice-series-summary.entity";
|
||||
export * from "./proforma.entity";
|
||||
export * from "./proforma-item.entity";
|
||||
export * from "./proforma-list.entity";
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
export interface InvoiceSeriesSummary {
|
||||
id: string;
|
||||
code: string;
|
||||
nextNumber: number;
|
||||
paddingLength: number;
|
||||
isDefault: boolean;
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
export * from "./keys";
|
||||
export * from "./use-invoice-series-query";
|
||||
export * from "./use-proforma-change-status-mutation";
|
||||
export * from "./use-proforma-create-mutation";
|
||||
export * from "./use-proforma-delete-mutation";
|
||||
|
||||
@ -6,6 +6,7 @@ import type { ProformasListRequestDTO } from "../../../../common";
|
||||
* Prefijo base para listados
|
||||
*/
|
||||
export const LIST_PROFORMAS_QUERY_KEY_PREFIX = ["proformas"] as const;
|
||||
export const INVOICE_SERIES_QUERY_KEY = ["customer-invoices", "invoice-series"] as const;
|
||||
|
||||
/**
|
||||
* Query key para listado de proformas
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
import { useDataSource } from "@erp/core/hooks";
|
||||
import { type DefaultError, type UseQueryResult, useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { ListInvoiceSeriesAdapter } from "../adapters";
|
||||
import { listInvoiceSeries } from "../api";
|
||||
import type { InvoiceSeriesSummary } from "../entities";
|
||||
|
||||
import { INVOICE_SERIES_QUERY_KEY } from "./keys";
|
||||
|
||||
export const useInvoiceSeriesQuery = (): UseQueryResult<InvoiceSeriesSummary[], DefaultError> => {
|
||||
const dataSource = useDataSource();
|
||||
|
||||
return useQuery<InvoiceSeriesSummary[], DefaultError>({
|
||||
queryKey: INVOICE_SERIES_QUERY_KEY,
|
||||
queryFn: async ({ signal }) => {
|
||||
const dto = await listInvoiceSeries(dataSource, signal);
|
||||
return ListInvoiceSeriesAdapter.fromDto(dto);
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,12 @@
|
||||
import type { SelectFieldItem } from "@repo/rdx-ui/components";
|
||||
|
||||
import type { InvoiceSeriesSummary } from "../entities";
|
||||
|
||||
export const buildInvoiceSeriesSelectItems = (
|
||||
invoiceSeries: InvoiceSeriesSummary[]
|
||||
): SelectFieldItem[] => {
|
||||
return invoiceSeries.map((series) => ({
|
||||
value: series.code,
|
||||
label: series.code,
|
||||
}));
|
||||
};
|
||||
@ -0,0 +1,19 @@
|
||||
import type { SelectFieldItem } from "@repo/rdx-ui/components";
|
||||
|
||||
export const ensureCurrentValueInSelectItems = (
|
||||
items: SelectFieldItem[],
|
||||
currentValue?: string | null
|
||||
): SelectFieldItem[] => {
|
||||
if (!currentValue) return items;
|
||||
|
||||
const exists = items.some((item) => item.value === currentValue);
|
||||
if (exists) return items;
|
||||
|
||||
return [
|
||||
{
|
||||
value: currentValue,
|
||||
label: currentValue,
|
||||
},
|
||||
...items,
|
||||
];
|
||||
};
|
||||
@ -1,2 +1,4 @@
|
||||
export * from "./build-invoice-series-select-items";
|
||||
export * from "./calculate-proforma-due-dates";
|
||||
export * from "./ensure-current-value-in-select-items";
|
||||
export * from "./proforma-fiscal-options.utils";
|
||||
|
||||
@ -15,7 +15,13 @@ import type { FieldErrors } from "react-hook-form";
|
||||
import { useTranslation } from "../../../i18n";
|
||||
import type { UpdateProformaByIdParams } from "../../shared";
|
||||
import type { Proforma } from "../../shared/entities";
|
||||
import { useProformaGetQuery, useProformaUpdateMutation } from "../../shared/hooks";
|
||||
import {
|
||||
buildInvoiceSeriesSelectItems,
|
||||
ensureCurrentValueInSelectItems,
|
||||
useInvoiceSeriesQuery,
|
||||
useProformaGetQuery,
|
||||
useProformaUpdateMutation,
|
||||
} from "../../shared";
|
||||
import { mapProformaToProformaUpdateForm, mapProformaToSelectedCustomer } from "../adapters";
|
||||
import { type ProformaUpdateForm, ProformaUpdateFormSchema } from "../entities";
|
||||
import {
|
||||
@ -72,6 +78,8 @@ export const useUpdateProformaController = (
|
||||
error: updateError,
|
||||
} = useProformaUpdateMutation();
|
||||
|
||||
const invoiceSeriesQuery = useInvoiceSeriesQuery();
|
||||
|
||||
const initialValues = useMemo<ProformaUpdateForm>(() => {
|
||||
if (!proformaData) return buildProformaUpdateDefault();
|
||||
|
||||
@ -221,7 +229,7 @@ export const useUpdateProformaController = (
|
||||
options?.onError?.(normalizedError, params);
|
||||
}
|
||||
},
|
||||
(errors: FieldErrors<ProformaUpdateForm>) => {
|
||||
(_errors: FieldErrors<ProformaUpdateForm>) => {
|
||||
focusFirstInputFormError(form);
|
||||
|
||||
showWarningToast(
|
||||
@ -239,6 +247,12 @@ export const useUpdateProformaController = (
|
||||
|
||||
const currencyCode = form.watch("currencyCode");
|
||||
const languageCode = form.watch("languageCode");
|
||||
const currentSeries = form.watch("series");
|
||||
|
||||
const seriesOptions = useMemo(() => {
|
||||
const activeSeriesItems = buildInvoiceSeriesSelectItems(invoiceSeriesQuery.data ?? []);
|
||||
return ensureCurrentValueInSelectItems(activeSeriesItems, currentSeries);
|
||||
}, [currentSeries, invoiceSeriesQuery.data]);
|
||||
|
||||
const taxCtrl = useUpdateProformaTaxController({
|
||||
form,
|
||||
@ -263,6 +277,10 @@ export const useUpdateProformaController = (
|
||||
taxCtrl,
|
||||
totalsCtrl,
|
||||
paymentCtrl,
|
||||
seriesOptions,
|
||||
isSeriesLoading: invoiceSeriesQuery.isLoading,
|
||||
isSeriesLoadError: invoiceSeriesQuery.isError,
|
||||
seriesLoadError: invoiceSeriesQuery.error,
|
||||
|
||||
//
|
||||
currencyCode,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
// modules/customer-invoices/src/web/proformas/update/ui/blocks/proforma-update-editor.tsx
|
||||
|
||||
import type { CustomerSelectionOption } from "@erp/customers";
|
||||
import type { SelectFieldItem } from "@repo/rdx-ui/components";
|
||||
import { preventEnterKeySubmitForm } from "@repo/rdx-ui/helpers";
|
||||
import { cn } from "@repo/shadcn-ui/lib/utils";
|
||||
|
||||
@ -27,6 +28,7 @@ type ProformaUpdateEditorProps = {
|
||||
selectedCustomer?: CustomerSelectionOption | null;
|
||||
onChangeCustomerClick: () => void;
|
||||
onCreateCustomerClick: () => void;
|
||||
seriesOptions: SelectFieldItem[];
|
||||
|
||||
itemsCtrl: UseUpdateProformaItemsControllerResult;
|
||||
taxCtrl: UseUpdateProformaTaxControllerResult;
|
||||
@ -44,6 +46,7 @@ export const ProformaUpdateEditorForm = ({
|
||||
selectedCustomer,
|
||||
onChangeCustomerClick,
|
||||
onCreateCustomerClick,
|
||||
seriesOptions,
|
||||
itemsCtrl,
|
||||
taxCtrl,
|
||||
totalsCtrl,
|
||||
@ -58,7 +61,11 @@ export const ProformaUpdateEditorForm = ({
|
||||
<div className="grid grid-cols-1 2xl:grid-cols-4 gap-6 2xl:gap-12">
|
||||
<div className="2xl:col-span-3 space-y-6 gap-6 2xl:gap-12 2xl:space-y-12">
|
||||
<div className="grid 2xl:grid-cols-3 gap-6 2xl:gap-6 space-y-12 2xl:space-y-12">
|
||||
<ProformaUpdateHeaderEditor className="2xl:col-span-full" disabled={isSubmitting} />
|
||||
<ProformaUpdateHeaderEditor
|
||||
className="2xl:col-span-full"
|
||||
disabled={isSubmitting}
|
||||
seriesOptions={seriesOptions}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ProformaUpdateItemsEditor
|
||||
|
||||
@ -3,6 +3,7 @@ import {
|
||||
FormSectionCard,
|
||||
FormSectionGrid,
|
||||
SelectField,
|
||||
type SelectFieldItem,
|
||||
TextAreaField,
|
||||
TextField,
|
||||
} from "@repo/rdx-ui/components";
|
||||
@ -12,6 +13,7 @@ import { FileTextIcon } from "lucide-react";
|
||||
import { useTranslation } from "../../../../i18n";
|
||||
|
||||
interface ProformaUpdateHeaderEditorProps {
|
||||
seriesOptions: SelectFieldItem[];
|
||||
disabled?: boolean;
|
||||
readOnly?: boolean;
|
||||
|
||||
@ -19,6 +21,7 @@ interface ProformaUpdateHeaderEditorProps {
|
||||
}
|
||||
|
||||
export const ProformaUpdateHeaderEditor = ({
|
||||
seriesOptions,
|
||||
disabled = false,
|
||||
readOnly = false,
|
||||
className,
|
||||
@ -33,15 +36,6 @@ export const ProformaUpdateHeaderEditor = ({
|
||||
title={t("form_groups.proformas.basic_info.title")}
|
||||
>
|
||||
<FormSectionGrid>
|
||||
<SelectField
|
||||
className="md:col-span-1"
|
||||
disabled={disabled}
|
||||
label={t("form_fields.proformas.series.label")}
|
||||
name="series"
|
||||
placeholder={t("form_fields.proformas.series.placeholder")}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
className="md:col-span-2"
|
||||
disabled={disabled}
|
||||
@ -66,6 +60,16 @@ export const ProformaUpdateHeaderEditor = ({
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
|
||||
<SelectField
|
||||
className="md:col-span-1"
|
||||
disabled={disabled}
|
||||
items={seriesOptions}
|
||||
label={t("form_fields.proformas.series.label")}
|
||||
name="series"
|
||||
placeholder={t("form_fields.proformas.series.placeholder")}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
|
||||
<DatePickerField
|
||||
className="md:col-span-2"
|
||||
disabled={disabled}
|
||||
|
||||
@ -99,6 +99,23 @@ export const ProformaUpdatePage = () => {
|
||||
title={t("pages.proformas.update.error_title", "No se pudo guardar los cambios")}
|
||||
/>
|
||||
)}
|
||||
|
||||
{updateCtrl.isSeriesLoadError && (
|
||||
<ErrorAlert
|
||||
message={
|
||||
updateCtrl.seriesLoadError instanceof Error
|
||||
? updateCtrl.seriesLoadError.message
|
||||
: t(
|
||||
"pages.proformas.update.series_load_error.message",
|
||||
"Inténtalo de nuevo más tarde."
|
||||
)
|
||||
}
|
||||
title={t(
|
||||
"pages.proformas.update.series_load_error.title",
|
||||
"No se pudieron cargar las series de facturación"
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
<ProformaUpdateEditorForm
|
||||
formId={updateCtrl.formId}
|
||||
@ -110,6 +127,7 @@ export const ProformaUpdatePage = () => {
|
||||
onSubmit={updateCtrl.onSubmit}
|
||||
paymentCtrl={updateCtrl.paymentCtrl}
|
||||
selectedCustomer={updateCtrl.selectedCustomer}
|
||||
seriesOptions={updateCtrl.seriesOptions}
|
||||
taxCtrl={updateCtrl.taxCtrl}
|
||||
totalsCtrl={updateCtrl.totalsCtrl}
|
||||
/>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user