Gastos
Ruta /pimia/gastos · componentes, campos y acciones del checkout documentado.
Ruta y puntos de edición
Ruta: /pimia/gastos. Revisión: 2aec1b16cc01.
Esta ficha procede de lectura estática del código. Los componentes asociados pueden incluir diálogos cerrados y bloques condicionales. Las expresiones dinámicas se conservan como código; no equivalen a campos siempre visibles ni a permisos concedidos.
Vista en el tenant de referencia

Captura de escritorio del tenant de demostración Reformas Vera, S.L., tomada el 10 de septiembre de 2026. Los datos ilustran la composición de la pantalla y pueden cambiar.
| Capa | Archivo relativo al repositorio |
|---|---|
| Ruta | src/app/pimia/gastos/page.tsx |
| Adaptador Next.js | src/host/screens/PimiaExpenseScreens.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaExpensesScreen.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaStates.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaScreenShell.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaPageHeader.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaFilterBar.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaCustomerCombobox.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaTablePanel.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaPagination.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaSortableHead.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaExpenseRow.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaExpenseDialog.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaConnectDialog.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaAmountCell.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaExpenseReceiptDialog.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaFieldCaption.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaSupplierCombobox.tsx |
| Vista o componente asociado | src/features/pimia/ui/PimiaOcrDialog.tsx |
PimiaExpensesScreen
Fuente: src/features/pimia/ui/PimiaExpensesScreen.tsx.
Campos y controles
La columna «Reglas JSX» recoge propiedades explícitas; la validación adicional vive en los helpers y en el servidor. El enlace de estado indica dónde se lee el valor.
| Etiqueta o pista | Control | Enlace de estado | Reglas JSX | Línea |
|---|---|---|---|---|
| Sin etiqueta literal resoluble | Select | categoryId === null ? TODAS : String(categoryId) | No declaradas en este nodo | 313 |
| Desde | Input | fromDate | type=date | 352 |
| Hasta | Input | toDate | type=date | 366 |
| Filtrar por el cliente al que se repercute | PimiaCustomerCombobox | customerFilter === null ? null : String(customerFilter) | No declaradas en este nodo | 382 |
Columnas declaradas
- Concepto
- Repercutido a
- Acciones
Acciones
| Rótulo literal | Handler o envío | Deshabilitado cuando | Línea |
|---|---|---|---|
| Anotar un gasto | openNew | No declarado en este nodo | 294 |
| Limpiar filtros | clearFilters | No declarado en este nodo | 414 |
| Limpiar los filtros | clearFilters | No declarado en este nodo | 491 |
| Anotar el primer gasto | openNew | No declarado en este nodo | 495 |
Estados reutilizados
-
PimiaNotConnected -
PimiaRowsSkeleton -
PimiaErrorState -
PimiaEmpty
Clases de presentación locales
Selección de clases literales; las clases condicionales y los estilos de los primitivos se consultan en el archivo.
gap-2, text-xs, text-destructive, text-muted-foreground, bg-muted/40, text-sm, text-center, text-foreground.
PimiaStates
Fuente: src/features/pimia/ui/PimiaStates.tsx.
Acciones
| Rótulo literal | Handler o envío | Deshabilitado cuando | Línea |
|---|---|---|---|
| Conectar una empresa | () => setIsConnectOpen(true) | No declarado en este nodo | 99 |
| Rótulo dinámico / icono | () => void goPimiaPath(notFound.listPath) | No declarado en este nodo | 233 |
| Rótulo dinámico / icono | delegado al contenedor | No declarado en este nodo | 247 |
| Rótulo dinámico / icono | () => void goPimiaPath( closedDoor.action?.kind === "plan" ? PLAN_PATH : MODULES_SETTINGS_PATH, ) | No declarado en este nodo | 257 |
| Volver a conectar | () => setIsConnectOpen(true) | No declarado en este nodo | 273 |
| Reintentar | onRetry | No declarado en este nodo | 279 |
Clases de presentación locales
Selección de clases literales; las clases condicionales y los estilos de los primitivos se consultan en el archivo.
gap-4, p-8, text-center, text-base, text-foreground, text-sm, text-muted-foreground, gap-2, overflow-hidden, bg-muted/40.
PimiaFilterBar
Fuente: src/features/pimia/ui/PimiaFilterBar.tsx.
Campos y controles
La columna «Reglas JSX» recoge propiedades explícitas; la validación adicional vive en los helpers y en el servidor. El enlace de estado indica dónde se lee el valor.
| Etiqueta o pista | Control | Enlace de estado | Reglas JSX | Línea |
|---|---|---|---|---|
| searchLabel ?? searchPlaceholder | Input | searchValue ?? "" | No declaradas en este nodo | 56 |
Clases de presentación locales
Selección de clases literales; las clases condicionales y los estilos de los primitivos se consultan en el archivo.
text-muted-foreground, gap-2.
PimiaCustomerCombobox
Fuente: src/features/pimia/ui/PimiaCustomerCombobox.tsx.
Acciones
| Rótulo literal | Handler o envío | Deshabilitado cuando | Línea |
|---|---|---|---|
| label | delegado al contenedor | disabled | 87 |
Clases de presentación locales
Selección de clases literales; las clases condicionales y los estilos de los primitivos se consultan en el archivo.
text-muted-foreground, p-0, text-xs.
PimiaPagination
Fuente: src/features/pimia/ui/PimiaPagination.tsx.
Campos y controles
La columna «Reglas JSX» recoge propiedades explícitas; la validación adicional vive en los helpers y en el servidor. El enlace de estado indica dónde se lee el valor.
| Etiqueta o pista | Control | Enlace de estado | Reglas JSX | Línea |
|---|---|---|---|---|
| Sin etiqueta literal resoluble | Select | String(pageSize) | No declaradas en este nodo | 82 |
Acciones
| Rótulo literal | Handler o envío | Deshabilitado cuando | Línea |
|---|---|---|---|
| Anterior | () => onPageChange(Math.max(1, page - 1)) | page <= 1 || isBusy | 104 |
| Siguiente | () => onPageChange(page + 1) | page >= lastPage || isBusy | 115 |
Clases de presentación locales
Selección de clases literales; las clases condicionales y los estilos de los primitivos se consultan en el archivo.
gap-3, text-xs, text-muted-foreground, gap-2.
PimiaSortableHead
Fuente: src/features/pimia/ui/PimiaSortableHead.tsx.
Acciones
| Rótulo literal | Handler o envío | Deshabilitado cuando | Línea |
|---|---|---|---|
| Rótulo dinámico / icono | () => onSortChange({ direction: isActive && sort.direction === "desc" ? "asc" : ("desc" as const), field, }) | No declarado en este nodo | 61 |
PimiaExpenseRow
Fuente: src/features/pimia/ui/PimiaExpenseRow.tsx.
Acciones
| Rótulo literal | Handler o envío | Deshabilitado cuando | Línea |
|---|---|---|---|
| Rótulo dinámico / icono | () => onEdit(expense) | No declarado en este nodo | 174 |
| Rótulo dinámico / icono | () => void goPimiaCustomer(String(expense.customerId)) | No declarado en este nodo | 223 |
| `Acciones de ${concept}` | delegado al contenedor | No declarado en este nodo | 257 |
| Editar | () => onEdit(expense) | No declarado en este nodo | 278 |
| Ver el justificante | () => { void openExternalUrl(expense.receiptUrl as string).catch( (error: unknown) => toast.error( errorMessage(error, "No se pudo abrir el justificante"), ), ); } | No declarado en este nodo | 285 |
| Rótulo dinámico / icono | () => setIsAttachingReceipt(true) | No declarado en este nodo | 301 |
| Eliminar | () => setIsConfirmingDelete(true) | No declarado en este nodo | 312 |
| Eliminar | () => void handleDelete() | No declarado en este nodo | 373 |
Clases de presentación locales
Selección de clases literales; las clases condicionales y los estilos de los primitivos se consultan en el archivo.
text-muted-foreground, text-left, text-foreground, gap-x-2, gap-y-1, text-xs, bg-muted/60, gap-1, text-sm, hover:text-foreground, text-right.
PimiaExpenseDialog
Fuente: src/features/pimia/ui/PimiaExpenseDialog.tsx.
Campos y controles
La columna «Reglas JSX» recoge propiedades explícitas; la validación adicional vive en los helpers y en el servidor. El enlace de estado indica dónde se lee el valor.
| Etiqueta o pista | Control | Enlace de estado | Reglas JSX | Línea |
|---|---|---|---|---|
| Justificante (opcional) | Input | delegado | type=file | 434 |
| Quitarlo al guardar. Se borra de tu empresa y no hay papelera: es el papel que justifica el gasto ante Hacienda. | Checkbox | removeReceipt | No declaradas en este nodo | 455 |
| Fecha (obligatoria) | Input | form.expenseDate | type=date | 485 |
| Importe (obligatorio) | Input | form.amountText | No declaradas en este nodo | 512 |
| Quitarlo al guardar. Se borra de tu empresa y no hay papelera: es el papel que justifica el gasto ante Hacienda. | Select | form.categoryId === null ? "" : String(form.categoryId) | No declaradas en este nodo | 552 |
| Concepto | Textarea | form.notes | No declaradas en este nodo | 610 |
| Quitarlo al guardar. Se borra de tu empresa y no hay papelera: es el papel que justifica el gasto ante Hacienda. | Select | form.paymentMethodId === "" ? SIN_METODO : form.paymentMethodId | No declaradas en este nodo | 627 |
| Repercutir a | PimiaCustomerCombobox | form.customerId === null ? null : String(form.customerId) | No declaradas en este nodo | 665 |
| Proveedor | PimiaSupplierCombobox | form.supplierId | No declaradas en este nodo | 716 |
Acciones
| Rótulo literal | Handler o envío | Deshabilitado cuando | Línea |
|---|---|---|---|
| Leer un ticket (OCR) | () => setIsOcrOpen(true) | No declarado en este nodo | 398 |
| Quitar el cliente | () => { set("customerId", null); setCustomerName(null); } | No declarado en este nodo | 691 |
| Quitar el proveedor | () => { set("supplierId", null); setSupplierName(null); } | No declarado en este nodo | 755 |
| Cancelar | () => onOpenChange(false) | No declarado en este nodo | 830 |
| Rótulo dinámico / icono | submit del formulario | isBlocked | 837 |
| Reintentar | onRetry | No declarado en este nodo | 935 |
Clases de presentación locales
Selección de clases literales; las clases condicionales y los estilos de los primitivos se consultan en el archivo.
text-muted-foreground, text-xs, p-3, text-sm, text-foreground, gap-2, grid-cols-1, gap-4, sm:grid-cols-2, text-destructive, bg-muted/40, bg-destructive/5, p-2.5.
PimiaConnectDialog
Fuente: src/features/pimia/ui/PimiaConnectDialog.tsx.
Campos y controles
La columna «Reglas JSX» recoge propiedades explícitas; la validación adicional vive en los helpers y en el servidor. El enlace de estado indica dónde se lee el valor.
| Etiqueta o pista | Control | Enlace de estado | Reglas JSX | Línea |
|---|---|---|---|---|
| Tu empresa | Input | baseUrl | disabled=connect.isPending | 114 |
Acciones
| Rótulo literal | Handler o envío | Deshabilitado cuando | Línea |
|---|---|---|---|
| Cancelar | () => handleOpenChange(false) | No declarado en este nodo | 155 |
| Rótulo dinámico / icono | submit del formulario | !canSubmit | 162 |
Clases de presentación locales
Selección de clases literales; las clases condicionales y los estilos de los primitivos se consultan en el archivo.
text-sm, text-foreground, gap-2, text-muted-foreground, text-xs, text-destructive.
PimiaExpenseReceiptDialog
Fuente: src/features/pimia/ui/PimiaExpenseReceiptDialog.tsx.
Campos y controles
La columna «Reglas JSX» recoge propiedades explícitas; la validación adicional vive en los helpers y en el servidor. El enlace de estado indica dónde se lee el valor.
| Etiqueta o pista | Control | Enlace de estado | Reglas JSX | Línea |
|---|---|---|---|---|
| El archivo | Input | delegado | type=file; disabled=subir.isPending | 125 |
Acciones
| Rótulo literal | Handler o envío | Deshabilitado cuando | Línea |
|---|---|---|---|
| Cancelar | () => onOpenChange(false) | subir.isPending | 159 |
| Rótulo dinámico / icono | () => void subirlo() | !file || problema !== null || subir.isPending | 167 |
Clases de presentación locales
Selección de clases literales; las clases condicionales y los estilos de los primitivos se consultan en el archivo.
gap-2, text-xs, text-muted-foreground, text-destructive.
PimiaSupplierCombobox
Fuente: src/features/pimia/ui/PimiaSupplierCombobox.tsx.
Acciones
| Rótulo literal | Handler o envío | Deshabilitado cuando | Línea |
|---|---|---|---|
| label | delegado al contenedor | disabled | 111 |
Clases de presentación locales
Selección de clases literales; las clases condicionales y los estilos de los primitivos se consultan en el archivo.
text-muted-foreground, p-0, text-left, text-xs.
PimiaOcrDialog
Fuente: src/features/pimia/ui/PimiaOcrDialog.tsx.
Campos y controles
La columna «Reglas JSX» recoge propiedades explícitas; la validación adicional vive en los helpers y en el servidor. El enlace de estado indica dónde se lee el valor.
| Etiqueta o pista | Control | Enlace de estado | Reglas JSX | Línea |
|---|---|---|---|---|
| `El documento a leer (jpg, png, pdf, tiff o webp, 10 MB máximo)` | Input | delegado | type=file | 132 |
Acciones
| Rótulo literal | Handler o envío | Deshabilitado cuando | Línea |
|---|---|---|---|
| Rótulo dinámico / icono | () => file && extract.mutate(file) | file === null || extract.isPending | 146 |
| Cancelar | () => onOpenChange(false) | No declarado en este nodo | 221 |
| Usar estos datos | () => { if (result) { onUse(result); onOpenChange(false); } } | result === null | 228 |
Clases de presentación locales
Selección de clases literales; las clases condicionales y los estilos de los primitivos se consultan en el archivo.
overflow-y-auto, bg-muted/40, text-sm, text-muted-foreground, text-xs, text-destructive, grid-cols-[auto_1fr], gap-x-4, gap-y-1.5, p-3.
Hooks, adaptadores y utilidades relacionados
-
src/features/pimia/api/auth.ts -
src/features/pimia/api/customers.ts -
src/features/pimia/api/expenses.ts -
src/features/pimia/api/ocr.ts -
src/features/pimia/api/pimiaClient.ts -
src/features/pimia/api/shell.ts -
src/features/pimia/api/suppliers.ts -
src/features/pimia/hooks/usePimiaAuth.ts -
src/features/pimia/hooks/usePimiaGastos.ts -
src/features/pimia/hooks/usePimiaProveedores.ts -
src/features/pimia/hooks/usePimiaResources.ts -
src/features/pimia/lib/calendar.ts -
src/features/pimia/lib/closedDoors.ts -
src/features/pimia/lib/expenseDraft.ts -
src/features/pimia/lib/expenseReceipt.ts -
src/features/pimia/lib/expenses.ts -
src/features/pimia/lib/missingRecord.ts -
src/features/pimia/lib/money.ts -
src/features/pimia/lib/pagination.ts -
src/features/pimia/lib/scopeDenial.ts
Antes de entregar un retoque
- Revisa los archivos de formulario y sus helpers antes de cambiar tipos, obligatoriedad o valores iniciales.
- Prueba carga, error, vacío, permisos insuficientes y guardado pendiente en las variantes que usa esta pantalla.
- Comprueba escritorio, móvil, teclado, tema oscuro y scroll con suficientes filas.
- Conserva los handlers y la invalidación de datos al modificar la presentación.