fix(impuestos): desactivar JIT en queries con subplans correlacionados

- Agrega helper withJitOff en impuestos.service.ts
- Ejecuta getResumenIva, getIvaMensual y readResumenIvaFromCache con SET LOCAL jit = off
- Evita compilación JIT de ~17s en queries con costo estimado alto

feat(contribuyentes): auto-asignar a cartera del supervisor

- Al crear contribuyente con supervisorUserId, se agrega automáticamente
  a todas las carteras top-level del supervisor

feat(permisos): restricciones de UI por rol en contribuyentes

- Oculta botón Add-ons para roles distintos de owner/cfo
- Oculta botón Eliminar contribuyente para no-owner
- Oculta botón Agregar RFC para auxiliar/visor/cliente/contador

feat(cfdi): ver CFDI desde conceptos y forma de pago en Excel

- Agrega botón Ver CFDI en cada fila de la tabla de Conceptos
- Agrega columna Forma de Pago en export Excel de CFDIs
- Agrega columna Forma de Pago en export individual de CFDI

chore(migraciones): índices GIN para relaciones de activos

- 048: índices btree parciales para activos
- 049: índices GIN para cfdis_relacionados y uuid_relacionado
This commit is contained in:
Horux Dev
2026-05-28 02:38:30 +00:00
parent 138e223361
commit 2208cee87f
14 changed files with 390 additions and 152 deletions

View File

@@ -14,6 +14,7 @@ import {
useDesasignarObligacion,
useAsignarTarea,
useDesasignarTarea,
useAuxiliaresElegibles,
} from '@/lib/hooks/use-asignaciones';
import { useUsuarios } from '@/lib/hooks/use-usuarios';
import { useAuthStore } from '@/stores/auth-store';
@@ -36,6 +37,11 @@ export default function SeguimientoAuxiliares() {
const auxiliares = (usuarios ?? []).filter((u: any) => u.role === 'auxiliar');
const { data: elegiblesData, isLoading: loadingElegibles } = useAuxiliaresElegibles(modalItem?.contribuyenteId);
const auxiliaresIdsElegibles = elegiblesData?.auxiliares ?? [];
const auxiliaresFiltrados = auxiliares.filter((a: any) => auxiliaresIdsElegibles.includes(a.id));
const puedeAsignar = !loadingElegibles && auxiliaresFiltrados.length > 0;
const openAssignModal = (type: 'obligacion' | 'tarea', item: any) => {
setModalType(type);
setModalItem(item);
@@ -169,20 +175,28 @@ export default function SeguimientoAuxiliares() {
<p className="text-xs text-muted-foreground mb-4">
Contribuyente: {modalItem?.contribuyenteRazonSocial} ({modalItem?.contribuyenteRfc})
</p>
<Select value={selectedAuxiliar} onValueChange={setSelectedAuxiliar}>
<SelectTrigger>
<SelectValue placeholder="Selecciona un auxiliar" />
</SelectTrigger>
<SelectContent>
{auxiliares.map((a: any) => (
<SelectItem key={a.id} value={a.id}>{a.nombre} ({a.email})</SelectItem>
))}
</SelectContent>
</Select>
{loadingElegibles ? (
<p className="text-sm text-muted-foreground">Verificando subcarteras...</p>
) : auxiliaresFiltrados.length === 0 ? (
<p className="text-sm text-red-600">
Ningún auxiliar tiene este contribuyente en su subcartera. No se puede asignar.
</p>
) : (
<Select value={selectedAuxiliar} onValueChange={setSelectedAuxiliar}>
<SelectTrigger>
<SelectValue placeholder="Selecciona un auxiliar" />
</SelectTrigger>
<SelectContent>
{auxiliaresFiltrados.map((a: any) => (
<SelectItem key={a.id} value={a.id}>{a.nombre} ({a.email})</SelectItem>
))}
</SelectContent>
</Select>
)}
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setModalOpen(false)}>Cancelar</Button>
<Button onClick={handleAssign} disabled={!selectedAuxiliar}>
<Button onClick={handleAssign} disabled={!selectedAuxiliar || !puedeAsignar}>
{modalItem?.auxiliarUserId ? 'Reasignar' : 'Asignar'}
</Button>
</DialogFooter>