PROFORMAS ISSUE
This commit is contained in:
parent
994417e48f
commit
b2dee4ae8b
@ -96,14 +96,30 @@
|
||||
}
|
||||
},
|
||||
"proformas": {
|
||||
"issue_proforma_dialog": {
|
||||
"title": "Issue to invoice",
|
||||
"description": "Are you sure you want to issue an invoice from proforma {{reference}}?",
|
||||
"warning": "This action will create a final invoice and the proforma will be marked as \"Issued\". It will no longer be editable or deletable.",
|
||||
"confirm": "Issue invoice",
|
||||
"submitting": "Issuing...",
|
||||
"success_title": "Proforma successfully issued",
|
||||
"success_description": "Proforma {{reference}} has been successfully issued to an invoice.",
|
||||
"error_title": "Error issuing proforma",
|
||||
"not_allowed_title": "Action not allowed",
|
||||
"not_allowed_description": "Only proformas in \"Approved\" status can be issued.",
|
||||
"unknown_error": "An unexpected error occurred"
|
||||
},
|
||||
"delete_proforma_dialog": {
|
||||
"title": "Delete proforma",
|
||||
"description": "Are you sure you want to delete proforma <strong>{{proformaRef}}</strong>? This action cannot be undone.",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"single_title": "Delete proforma {{reference}}",
|
||||
"single_description": "Are you sure you want to delete this proforma? This action cannot be undone.",
|
||||
"second_confirm_single_title": "Additional confirmation",
|
||||
"second_confirm_single_description": "You are about to delete the proforma. This action cannot be undone. Are you sure you want to continue?",
|
||||
"multiple_description": "Are you sure you want to delete the {{total}} selected proformas? This action cannot be undone.",
|
||||
"confirm_delete": "Confirm deletion",
|
||||
"deleting": "Deleting...",
|
||||
"success_title": "Proforma deleted",
|
||||
"error_title": "Error deleting proforma"
|
||||
"cancel": "Cancel",
|
||||
"continue": "Delete",
|
||||
"list_item": "Proforma {{reference}}"
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
|
||||
@ -96,20 +96,30 @@
|
||||
}
|
||||
},
|
||||
"proformas": {
|
||||
"issue_proforma_dialog": {
|
||||
"title": "Emitir a factura",
|
||||
"description": "¿Seguro que quieres emitir la factura desde la proforma {{reference}}?",
|
||||
"warning": "Esta acción creará una nueva factura definitiva y la proforma pasará al estado \"Emitida\", no pudiendo modificarse ni eliminarse posteriormente.",
|
||||
"confirm": "Emitir factura",
|
||||
"submitting": "Emitiendo...",
|
||||
"success_title": "Proforma emitida correctamente",
|
||||
"success_description": "La proforma {{reference}} se ha emitido a factura correctamente.",
|
||||
"error_title": "Error al emitir la proforma",
|
||||
"not_allowed_title": "Acción no permitida",
|
||||
"not_allowed_description": "Solo se pueden emitir proformas en estado \"Aprobada\".",
|
||||
"unknown_error": "Ha ocurrido un error inesperado",
|
||||
"cancel": "Cancelar"
|
||||
},
|
||||
"delete_proforma_dialog": {
|
||||
"title": "Eliminar proforma",
|
||||
"description": "¿Seguro que deseas eliminar la proforma <strong>{{proformaRef}}</strong>? Esta acción no se puede deshacer.",
|
||||
"cancel": "Cancelar",
|
||||
"delete": "Eliminar",
|
||||
"deleting": "Eliminando...",
|
||||
"success_title": "Proforma eliminada",
|
||||
"error_title": "Error al eliminar la proforma",
|
||||
"single_title": "Eliminar proforma {{reference}}",
|
||||
"second_confirm_title": "Confirmación adicional",
|
||||
"multiple_title": "Eliminar {{count}} proformas",
|
||||
"second_confirm_description": "Estás a punto de borrar {{total}} proformas. Esta acción masiva no se puede deshacer. ¿Seguro que quieres continuar?",
|
||||
"single_description": "¿Seguro que deseas eliminar esta proforma? Esta acción no se puede deshacer.",
|
||||
"second_confirm_single_title": "Confirmación adicional",
|
||||
"second_confirm_single_description": "Estás a punto de borrar la proforma. Esta acción masiva no se puede deshacer. ¿Seguro que quieres continuar?",
|
||||
"multiple_description": "¿Seguro que deseas eliminar las {{total}} proformas seleccionadas? Esta acción no se puede deshacer.",
|
||||
"confirm_delete": "Confirmar eliminación",
|
||||
"deleting": "Eliminando...",
|
||||
"cancel": "Cancelar",
|
||||
"continue": "Eliminar",
|
||||
"list_item": "Proforma {{reference}}"
|
||||
}
|
||||
},
|
||||
|
||||
@ -59,8 +59,8 @@ export const useDeleteProformaDialogController = () => {
|
||||
(targets: DeleteProformaTarget[]) => {
|
||||
if (targets.length === 1) {
|
||||
showSuccessToast(
|
||||
t("pages.proformas.delete.successTitle"),
|
||||
t("pages.proformas.delete.successSingleMessage", {
|
||||
t("proformas.delete_proforma_dialog.success_title"),
|
||||
t("proformas.delete_proforma_dialog.success_single_message", {
|
||||
reference: getProformaLabel(targets[0]),
|
||||
})
|
||||
);
|
||||
@ -68,8 +68,8 @@ export const useDeleteProformaDialogController = () => {
|
||||
}
|
||||
|
||||
showSuccessToast(
|
||||
t("pages.proformas.delete.successTitle"),
|
||||
t("pages.proformas.delete.successMultipleMessage", {
|
||||
t("proformas.delete_proforma_dialog.success_title"),
|
||||
t("proformas.delete_proforma_dialog.success_multiple_message", {
|
||||
count: targets.length,
|
||||
})
|
||||
);
|
||||
@ -81,15 +81,15 @@ export const useDeleteProformaDialogController = () => {
|
||||
(targets: DeleteProformaTarget[], errorCount: number) => {
|
||||
if (targets.length === 1) {
|
||||
showErrorToast(
|
||||
t("pages.proformas.delete.errorTitle"),
|
||||
t("pages.proformas.delete.errorSingleMessage")
|
||||
t("proformas.delete_proforma_dialog.error_title"),
|
||||
t("proformas.delete_proforma_dialog.error_single_message")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
showErrorToast(
|
||||
t("pages.proformas.delete.errorTitle"),
|
||||
t("pages.proformas.delete.errorMultipleMessage", {
|
||||
t("proformas.delete_proforma_dialog.error_title"),
|
||||
t("proformas.delete_proforma_dialog.error_multiple_message", {
|
||||
count: errorCount,
|
||||
})
|
||||
);
|
||||
@ -143,8 +143,8 @@ export const useDeleteProformaDialogController = () => {
|
||||
await submitDelete();
|
||||
} catch {
|
||||
showErrorToast(
|
||||
t("pages.proformas.delete.errorTitle"),
|
||||
t("pages.proformas.delete.errorUnexpectedMessage")
|
||||
t("proformas.delete.error_title"),
|
||||
t("proformas.delete.error_unexpected_message")
|
||||
);
|
||||
}
|
||||
}, [deleteMutation.isPending, moveToSecondConfirmStep, state, submitDelete, t]);
|
||||
|
||||
@ -39,29 +39,29 @@ export const DeleteProformaDialog = ({
|
||||
|
||||
const title = isSecondConfirmStep
|
||||
? isSingle
|
||||
? t("components.delete_proforma_dialog.second_confirm_single_title", {
|
||||
? t("proformas.delete_proforma_dialog.second_confirm_single_title", {
|
||||
reference: getTargetLabel(firstTarget),
|
||||
})
|
||||
: t("components.delete_proforma_dialog.second_confirm_multiple_title", {
|
||||
: t("proformas.delete_proforma_dialog.second_confirm_multiple_title", {
|
||||
count: total,
|
||||
})
|
||||
: isSingle
|
||||
? t("components.delete_proforma_dialog.single_title", {
|
||||
? t("proformas.delete_proforma_dialog.single_title", {
|
||||
reference: getTargetLabel(firstTarget),
|
||||
})
|
||||
: t("components.delete_proforma_dialog.multiple_title", {
|
||||
: t("proformas.delete_proforma_dialog.multiple_title", {
|
||||
count: total,
|
||||
});
|
||||
|
||||
const description = isSecondConfirmStep
|
||||
? isSingle
|
||||
? t("components.delete_proforma_dialog.second_confirm_single_description")
|
||||
: t("components.delete_proforma_dialog.second_confirm_multiple_description", {
|
||||
? t("proformas.delete_proforma_dialog.second_confirm_single_description")
|
||||
: t("proformas.delete_proforma_dialog.second_confirm_multiple_description", {
|
||||
count: total,
|
||||
})
|
||||
: isSingle
|
||||
? t("components.delete_proforma_dialog.single_description")
|
||||
: t("components.delete_proforma_dialog.multiple_description", {
|
||||
? t("proformas.delete_proforma_dialog.single_description")
|
||||
: t("proformas.delete_proforma_dialog.multiple_description", {
|
||||
count: total,
|
||||
});
|
||||
|
||||
@ -84,7 +84,7 @@ export const DeleteProformaDialog = ({
|
||||
<ul className="space-y-1">
|
||||
{targets.map((target) => (
|
||||
<li className="text-muted-foreground" key={target.id}>
|
||||
{t("components.delete_proforma_dialog.list_item", {
|
||||
{t("proformas.delete_proforma_dialog.list_item", {
|
||||
reference: getTargetLabel(target),
|
||||
})}
|
||||
</li>
|
||||
@ -95,19 +95,19 @@ export const DeleteProformaDialog = ({
|
||||
|
||||
<AlertDialogFooter className="sm:justify-between">
|
||||
<Button disabled={isSubmitting} onClick={() => onOpenChange(false)} variant="outline">
|
||||
{t("components.delete_proforma_dialog.cancel")}
|
||||
{t("proformas.delete_proforma_dialog.cancel")}
|
||||
</Button>
|
||||
|
||||
<Button disabled={isSubmitting || total === 0} onClick={onConfirm} variant="destructive">
|
||||
{isSubmitting ? (
|
||||
<>
|
||||
<Spinner className="mr-2 size-4" />
|
||||
{t("components.delete_proforma_dialog.deleting")}
|
||||
{t("proformas.delete_proforma_dialog.deleting")}
|
||||
</>
|
||||
) : isSecondConfirmStep ? (
|
||||
t("components.delete_proforma_dialog.confirm_delete")
|
||||
t("proformas.delete_proforma_dialog.confirm_delete")
|
||||
) : (
|
||||
t("components.delete_proforma_dialog.continue")
|
||||
t("proformas.delete_proforma_dialog.continue")
|
||||
)}
|
||||
</Button>
|
||||
</AlertDialogFooter>
|
||||
|
||||
@ -1,61 +1,91 @@
|
||||
import { showErrorToast, showSuccessToast } from "@repo/rdx-ui/helpers";
|
||||
import * as React from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
import type { ProformaSummaryData } from "../../types";
|
||||
import { useIssueProformaMutation } from "../hooks/use-issue-proforma-mutation";
|
||||
import { useTranslation } from "../../../i18n";
|
||||
import { useProformaIssueMutation } from "../../shared";
|
||||
import type { IssueProformaTarget } from "../entities";
|
||||
|
||||
interface State {
|
||||
interface IssueDialogState {
|
||||
open: boolean;
|
||||
proforma: ProformaSummaryData | null;
|
||||
loading: boolean;
|
||||
target: IssueProformaTarget | null;
|
||||
}
|
||||
|
||||
export function useProformaIssueDialogController() {
|
||||
const { issueProforma, isPending } = useIssueProformaMutation();
|
||||
const canIssueProforma = (target: IssueProformaTarget) => target.status === "approved";
|
||||
|
||||
const [state, setState] = React.useState<State>({
|
||||
export const useIssueProformaDialogController = () => {
|
||||
const { t } = useTranslation();
|
||||
const issueMutation = useProformaIssueMutation();
|
||||
|
||||
const [state, setState] = useState<IssueDialogState>({
|
||||
open: false,
|
||||
proforma: null,
|
||||
loading: false,
|
||||
target: null,
|
||||
});
|
||||
|
||||
// abrir diálogo
|
||||
const openDialog = (proforma: ProformaSummaryData) => {
|
||||
setState({ open: true, proforma: proforma, loading: false });
|
||||
};
|
||||
const openDialog = (target: IssueProformaTarget) => {
|
||||
if (!canIssueProforma(target)) {
|
||||
showErrorToast(
|
||||
t("proformas.issue_proforma_dialog.not_allowed_title"),
|
||||
t("proformas.issue_proforma_dialog.not_allowed_description")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// cerrar diálogo
|
||||
const closeDialog = () => {
|
||||
setState((s) => ({ ...s, open: false }));
|
||||
};
|
||||
|
||||
// confirmar emisión
|
||||
const confirmIssue = async () => {
|
||||
if (!state.proforma) return;
|
||||
|
||||
setState((s) => ({ ...s, loading: true }));
|
||||
|
||||
await issueProforma(state.proforma.id, {
|
||||
onSuccess: () => {
|
||||
showSuccessToast("Proforma emitida a factura");
|
||||
},
|
||||
onError: (err: unknown) => {
|
||||
const error = err as Error;
|
||||
showErrorToast("Error al emitir la proforma a factura", error.message);
|
||||
},
|
||||
setState({
|
||||
open: true,
|
||||
target,
|
||||
});
|
||||
};
|
||||
|
||||
setState((s) => ({ ...s, loading: false }));
|
||||
closeDialog();
|
||||
const closeDialog = () => {
|
||||
setState((current) => ({
|
||||
...current,
|
||||
open: false,
|
||||
}));
|
||||
};
|
||||
|
||||
const confirmIssue = async () => {
|
||||
const target = state.target;
|
||||
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canIssueProforma(target)) {
|
||||
showErrorToast(
|
||||
t("proformas.issue_proforma_dialog.not_allowed_title"),
|
||||
t("proformas.issue_proforma_dialog.not_allowed_description")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await issueMutation.mutateAsync({ id: target.id });
|
||||
|
||||
showSuccessToast(
|
||||
t("proformas.issue_proforma_dialog.success_title"),
|
||||
t("proformas.issue_proforma_dialog.success_description", {
|
||||
reference: target.reference,
|
||||
})
|
||||
);
|
||||
|
||||
setState({
|
||||
open: false,
|
||||
target: null,
|
||||
});
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error ? error.message : t("proformas.issue_proforma_dialog.unknown_error");
|
||||
|
||||
showErrorToast(t("proformas.issue_proforma_dialog.error_title"), message);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
open: state.open,
|
||||
proforma: state.proforma,
|
||||
isSubmitting: isPending,
|
||||
|
||||
target: state.target,
|
||||
isSubmitting: issueMutation.isPending,
|
||||
openDialog,
|
||||
closeDialog,
|
||||
confirmIssue,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@ -0,0 +1 @@
|
||||
export * from './issue-proforma-target.entity';
|
||||
@ -0,0 +1,8 @@
|
||||
import type { ProformaStatus } from "../../shared";
|
||||
|
||||
// proformas/issue/entities/issue-proforma-target.entity.ts
|
||||
export interface IssueProformaTarget {
|
||||
id: string;
|
||||
reference: string;
|
||||
status: ProformaStatus;
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
export * from "./use-issue-proforma-mutation";
|
||||
@ -1,48 +0,0 @@
|
||||
import { useDataSource } from "@erp/core/hooks";
|
||||
import { type DefaultError, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { type IssueProformaInvoiceResponse, issueProformaInvoiceApi } from "../api";
|
||||
|
||||
interface IssueProformaPayload {
|
||||
proformaId: string;
|
||||
}
|
||||
|
||||
interface IssueProformaOptions {
|
||||
onSuccess?: () => void;
|
||||
onError?: (err: unknown) => void;
|
||||
onLoadingChange?: (loading: boolean) => void;
|
||||
}
|
||||
|
||||
export function useIssueProformaMutation() {
|
||||
const dataSource = useDataSource();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const mutation = useMutation<IssueProformaInvoiceResponse, DefaultError, IssueProformaPayload>({
|
||||
mutationFn: ({ proformaId }) => issueProformaInvoiceApi(dataSource, proformaId),
|
||||
|
||||
onSuccess(_data, _vars, _ctx) {
|
||||
// Refresca el listado de proformas
|
||||
queryClient.invalidateQueries({ queryKey: ["proformas"] });
|
||||
|
||||
// Opcional: refrescar facturas si existe la feature
|
||||
queryClient.invalidateQueries({ queryKey: ["invoices"] });
|
||||
},
|
||||
});
|
||||
|
||||
async function issueProforma(proformaId: string, opts?: IssueProformaOptions) {
|
||||
try {
|
||||
opts?.onLoadingChange?.(true);
|
||||
await mutation.mutateAsync({ proformaId });
|
||||
opts?.onSuccess?.();
|
||||
} catch (err) {
|
||||
opts?.onError?.(err);
|
||||
} finally {
|
||||
opts?.onLoadingChange?.(false);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
issueProforma,
|
||||
isPending: mutation.isPending,
|
||||
};
|
||||
}
|
||||
@ -1,2 +1,3 @@
|
||||
export * from "./controllers";
|
||||
export * from "./ui";
|
||||
export * from "./utils";
|
||||
|
||||
@ -10,59 +10,58 @@ import {
|
||||
} from "@repo/shadcn-ui/components";
|
||||
|
||||
import { useTranslation } from "../../../i18n";
|
||||
import type { ProformaSummaryData } from "../../types";
|
||||
import type { IssueProformaTarget } from "../entities";
|
||||
|
||||
interface ProformaIssueDialogProps {
|
||||
interface IssueProformaDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
proforma: ProformaSummaryData | null;
|
||||
target: IssueProformaTarget | null;
|
||||
isSubmitting: boolean;
|
||||
onConfirm: (proforma?: ProformaSummaryData) => void;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
|
||||
export function ProformaIssueDialog({
|
||||
export const IssueProformaDialog = ({
|
||||
open,
|
||||
onOpenChange,
|
||||
proforma,
|
||||
target,
|
||||
isSubmitting,
|
||||
onConfirm,
|
||||
}: ProformaIssueDialogProps) {
|
||||
}: IssueProformaDialogProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<AlertDialog onOpenChange={onOpenChange} open={open}>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Emitir a factura</AlertDialogTitle>
|
||||
<AlertDialogTitle>{t("proformas.issue_proforma_dialog.title")}</AlertDialogTitle>
|
||||
|
||||
<AlertDialogDescription className="space-y-4">
|
||||
<p>
|
||||
¿Seguro que quieres emitir la factura desde la proforma{" "}
|
||||
<strong>{proforma?.reference}</strong>?
|
||||
</p>
|
||||
<p>
|
||||
Esta acción creará una nueva factura definitiva y la proforma pasará al estado
|
||||
"Emitida", no pudiendo modificarse ni eliminarse posteriormente.
|
||||
</p>
|
||||
{t("proformas.issue_proforma_dialog.description", {
|
||||
reference: target?.reference ?? "",
|
||||
})}
|
||||
<br />
|
||||
<br />
|
||||
{t("proformas.issue_proforma_dialog.warning")}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
|
||||
<AlertDialogFooter>
|
||||
<Button disabled={isSubmitting} onClick={() => onOpenChange(false)} variant="outline">
|
||||
Cancelar
|
||||
{t("proformas.issue_proforma_dialog.cancel")}
|
||||
</Button>
|
||||
|
||||
<Button disabled={isSubmitting} onClick={() => onConfirm(proforma)}>
|
||||
<Button disabled={isSubmitting} onClick={onConfirm}>
|
||||
{isSubmitting ? (
|
||||
<>
|
||||
<Spinner className="mr-2 size-4" />
|
||||
Emitiendo...
|
||||
<Spinner aria-hidden className="mr-2 size-4" />
|
||||
<span aria-live="polite">{t("proformas.issue_proforma_dialog.submitting")}</span>
|
||||
</>
|
||||
) : (
|
||||
<>Emitir factura</>
|
||||
t("proformas.issue_proforma_dialog.confirm")
|
||||
)}
|
||||
</Button>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -0,0 +1 @@
|
||||
export * from './prepare-issue-proforma-targets';
|
||||
@ -0,0 +1,25 @@
|
||||
// proformas/issue/utils/prepare-issue-proforma-targets.ts
|
||||
import type { Proforma, ProformaListRow } from "../../shared";
|
||||
import type { IssueProformaTarget } from "../entities";
|
||||
|
||||
type SupportedIssueSource = Proforma | ProformaListRow;
|
||||
type SupportedIssueInput = SupportedIssueSource | SupportedIssueSource[];
|
||||
|
||||
const mapToIssueProformaTarget = (proforma: SupportedIssueSource): IssueProformaTarget => ({
|
||||
id: proforma.id,
|
||||
reference: proforma.reference,
|
||||
status: proforma.status,
|
||||
});
|
||||
|
||||
export const prepareIssueProformaTargets = (input: SupportedIssueInput): IssueProformaTarget[] => {
|
||||
const items = Array.isArray(input) ? input : [input];
|
||||
return items.map(mapToIssueProformaTarget);
|
||||
};
|
||||
|
||||
export const prepareIssueProformaTarget = (
|
||||
input: Proforma | ProformaListRow
|
||||
): IssueProformaTarget => ({
|
||||
id: input.id,
|
||||
reference: input.reference,
|
||||
status: input.status,
|
||||
});
|
||||
@ -2,6 +2,7 @@ import type { RightPanelMode } from "@repo/rdx-ui/hooks";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
|
||||
import { useDeleteProformaDialogController } from "../../delete";
|
||||
import { useIssueProformaDialogController } from "../../issue-proforma";
|
||||
|
||||
import { useListProformasController } from "./use-list-proformas.controller";
|
||||
import { useProformaSummaryPanelController } from "./use-proforma-summary-panel.controller";
|
||||
@ -9,6 +10,7 @@ import { useProformaSummaryPanelController } from "./use-proforma-summary-panel.
|
||||
export const useListProformasPageController = () => {
|
||||
const listCtrl = useListProformasController();
|
||||
const deleteDialogCtrl = useDeleteProformaDialogController();
|
||||
const issueDialogCtrl = useIssueProformaDialogController();
|
||||
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
@ -26,5 +28,6 @@ export const useListProformasPageController = () => {
|
||||
panelCtrl,
|
||||
|
||||
deleteDialogCtrl,
|
||||
issueDialogCtrl,
|
||||
};
|
||||
};
|
||||
|
||||
@ -53,6 +53,7 @@ export const ProformasGrid = ({
|
||||
manualPagination
|
||||
onPageChange={onPageChange}
|
||||
onPageSizeChange={onPageSizeChange}
|
||||
//onRowClick={(row) => onRowClick?.(row.id)}
|
||||
pageIndex={pageIndex}
|
||||
pageSize={pageSize}
|
||||
totalItems={totalItems}
|
||||
|
||||
@ -18,6 +18,7 @@ import * as React from "react";
|
||||
|
||||
import { useTranslation } from "../../../../../i18n";
|
||||
import {
|
||||
PROFORMA_STATUS,
|
||||
PROFORMA_STATUS_TRANSITIONS,
|
||||
type ProformaListRow,
|
||||
type ProformaStatus,
|
||||
@ -227,12 +228,12 @@ export function useProformasGridColumns(
|
||||
enableSorting: false,
|
||||
cell: ({ row }) => {
|
||||
const proforma = row.original;
|
||||
const isIssued = proforma.status === "issued";
|
||||
const isApproved = proforma.status === "approved";
|
||||
const isIssued = proforma.status === PROFORMA_STATUS.ISSUED;
|
||||
const isApproved = proforma.status === PROFORMA_STATUS.APPROVED;
|
||||
const availableTransitions =
|
||||
PROFORMA_STATUS_TRANSITIONS[proforma.status as ProformaStatus] ?? [];
|
||||
|
||||
console.log(availableTransitions);
|
||||
console.log(availableTransitions, proforma.status);
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-1">
|
||||
@ -280,7 +281,7 @@ export function useProformasGridColumns(
|
||||
)}
|
||||
|
||||
{/* Emitir factura: solo si approved */}
|
||||
{!isIssued && proforma.status === "approved" && actionHandlers.onIssueClick && (
|
||||
{!isIssued && isApproved && actionHandlers.onIssueClick && (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
|
||||
@ -17,6 +17,8 @@ import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "../../../../i18n";
|
||||
import { DeleteProformaDialog } from "../../../delete";
|
||||
import { prepareDeleteProformaTargets } from "../../../delete/utils";
|
||||
import { IssueProformaDialog } from "../../../issue-proforma";
|
||||
import { prepareIssueProformaTarget } from "../../../issue-proforma/utils";
|
||||
import type { ProformaListRow } from "../../../shared";
|
||||
import { useListProformasPageController } from "../../controllers";
|
||||
import { ProformaSummaryPanel, ProformasGrid, useProformasGridColumns } from "../blocks";
|
||||
@ -25,16 +27,15 @@ export const ListProformasPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { listCtrl, panelCtrl, deleteDialogCtrl } = useListProformasPageController();
|
||||
|
||||
const handleDeleteProforma = (proformaRow: ProformaListRow) => {
|
||||
deleteDialogCtrl.openDialog(prepareDeleteProformaTargets(proformaRow));
|
||||
};
|
||||
const { listCtrl, panelCtrl, deleteDialogCtrl, issueDialogCtrl } =
|
||||
useListProformasPageController();
|
||||
|
||||
const columns = useProformasGridColumns({
|
||||
onEditClick: (proforma) => navigate(`/proformas/${proforma.id}/edit`),
|
||||
//onIssueClick: handleIssueProforma,
|
||||
onDeleteClick: handleDeleteProforma,
|
||||
onIssueClick: (proformaRow) =>
|
||||
issueDialogCtrl.openDialog(prepareIssueProformaTarget(proformaRow)),
|
||||
onDeleteClick: (proformaRow: ProformaListRow) =>
|
||||
deleteDialogCtrl.openDialog(prepareDeleteProformaTargets(proformaRow)),
|
||||
//onChangeStatusClick: handleChangeStatusProforma,
|
||||
});
|
||||
|
||||
@ -148,6 +149,19 @@ export const ListProformasPage = () => {
|
||||
<div className="flex min-h-0 flex-1 overflow-hidden">{listContent}</div>
|
||||
)}
|
||||
<>
|
||||
{/* Issue */}
|
||||
<IssueProformaDialog
|
||||
isSubmitting={issueDialogCtrl.isSubmitting}
|
||||
onConfirm={issueDialogCtrl.confirmIssue}
|
||||
onOpenChange={(open) => {
|
||||
if (!open) {
|
||||
issueDialogCtrl.closeDialog();
|
||||
}
|
||||
}}
|
||||
open={issueDialogCtrl.open}
|
||||
target={issueDialogCtrl.target}
|
||||
/>
|
||||
|
||||
{/* Eliminar */}
|
||||
<DeleteProformaDialog
|
||||
isSecondConfirmStep={deleteDialogCtrl.isSecondConfirmStep}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
export * from "./keys";
|
||||
export * from "./use-proforma-change-status-mutation";
|
||||
export * from "./use-proforma-create-mutation";
|
||||
export * from "./use-proforma-delete-mutation";
|
||||
export * from "./use-proforma-get-query";
|
||||
export * from "./use-proforma-issue-mutation";
|
||||
export * from "./use-proforma-update-mutation";
|
||||
export * from "./use-proformas-list-query";
|
||||
|
||||
@ -16,7 +16,7 @@ export const useProformaIssueMutation = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const dataSource = useDataSource();
|
||||
|
||||
useMutation<
|
||||
return useMutation<
|
||||
IssueProformaByIdResult,
|
||||
DefaultError,
|
||||
IssueProformaByIdParams,
|
||||
|
||||
@ -192,16 +192,6 @@
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"delete_proforma_dialog": {
|
||||
"single_title": "Eliminar proforoma",
|
||||
"single_description": "",
|
||||
"second_confirm_single_title": "Confirmar eliminación",
|
||||
"second_confirm_single_description": "",
|
||||
"confirm_delete": "Confirmar eliminación",
|
||||
"deleting": "Eliminando...",
|
||||
"cancel": "Cancelar",
|
||||
"continue": "Eliminar"
|
||||
},
|
||||
"entity_selector": {
|
||||
"close": "Close",
|
||||
"select_entity": "Select entity",
|
||||
|
||||
@ -194,18 +194,6 @@
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"delete_proforma_dialog": {
|
||||
"single_title": "Eliminar proforoma",
|
||||
"single_description": "",
|
||||
"second_confirm_single_title": "Confirmar eliminación",
|
||||
"second_confirm_single_description": "",
|
||||
"multiple_description": "",
|
||||
"confirm_delete": "Confirmar eliminación",
|
||||
"deleting": "Eliminando...",
|
||||
"cancel": "Cancelar",
|
||||
"continue": "Eliminar",
|
||||
"list_item": ""
|
||||
},
|
||||
"entity_selector": {
|
||||
"close": "Cerrar",
|
||||
"select_entity": "Seleccionar entidad",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user