feat(cfdi): agrega columna y filtro no_identificacion en tabla Conceptos
- Backend (cfdi.service.ts): getConceptosList ahora soporta filtro noIdentificacion via cc.no_identificacion ILIKE - Frontend API (cfdi.ts): ConceptosFilters incluye noIdentificacion; se envía como query param - Frontend página (cfdi/page.tsx): * Nuevo estado noIdentificacion en conceptosFilters * Nueva columna 'No. Identificación' en header de tabla con Popover filtro * Celda no_identificacion renderizada en cada fila * Export a Excel respeta el nuevo filtro
This commit is contained in:
@@ -325,10 +325,11 @@ export default function CfdiPage() {
|
||||
uuidLike: string;
|
||||
claveProdServ: string;
|
||||
descripcionConcepto: string;
|
||||
noIdentificacion: string;
|
||||
orderBy?: 'fecha' | 'importe';
|
||||
orderDir?: 'asc' | 'desc';
|
||||
}>({ uuidLike: '', claveProdServ: '', descripcionConcepto: '' });
|
||||
const [conceptosOpenFilter, setConceptosOpenFilter] = useState<'uuid' | 'clave' | 'descripcion' | null>(null);
|
||||
}>({ uuidLike: '', claveProdServ: '', descripcionConcepto: '', noIdentificacion: '' });
|
||||
const [conceptosOpenFilter, setConceptosOpenFilter] = useState<'uuid' | 'clave' | 'descripcion' | 'noIdentificacion' | null>(null);
|
||||
|
||||
const conceptosQuery = useQuery({
|
||||
queryKey: ['cfdi-conceptos', filters, selectedContribuyenteId, conceptosFilters],
|
||||
@@ -338,6 +339,7 @@ export default function CfdiPage() {
|
||||
uuidLike: conceptosFilters.uuidLike || undefined,
|
||||
claveProdServ: conceptosFilters.claveProdServ || undefined,
|
||||
descripcionConcepto: conceptosFilters.descripcionConcepto || undefined,
|
||||
noIdentificacion: conceptosFilters.noIdentificacion || undefined,
|
||||
orderBy: conceptosFilters.orderBy,
|
||||
orderDir: conceptosFilters.orderDir,
|
||||
}),
|
||||
@@ -481,6 +483,7 @@ export default function CfdiPage() {
|
||||
uuidLike: conceptosFilters.uuidLike || undefined,
|
||||
claveProdServ: conceptosFilters.claveProdServ || undefined,
|
||||
descripcionConcepto: conceptosFilters.descripcionConcepto || undefined,
|
||||
noIdentificacion: conceptosFilters.noIdentificacion || undefined,
|
||||
orderBy: conceptosFilters.orderBy,
|
||||
orderDir: conceptosFilters.orderDir,
|
||||
page: 1,
|
||||
@@ -1647,6 +1650,28 @@ export default function CfdiPage() {
|
||||
</Popover>
|
||||
</div>
|
||||
</th>
|
||||
<th className="pb-3 font-medium">
|
||||
<div className="flex items-center gap-1 justify-center">
|
||||
No. Identificación
|
||||
<Popover open={conceptosOpenFilter === 'noIdentificacion'} onOpenChange={(open) => setConceptosOpenFilter(open ? 'noIdentificacion' : null)}>
|
||||
<PopoverTrigger asChild>
|
||||
<button className={`p-1 rounded hover:bg-muted ${conceptosFilters.noIdentificacion ? 'text-primary' : ''}`}>
|
||||
<Filter className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-64" align="start">
|
||||
<div className="space-y-3">
|
||||
<h4 className="font-medium text-sm">Filtrar por No. Identificación</h4>
|
||||
<Input className="h-8 text-sm font-mono" placeholder="Ej: PROD-001" value={conceptosFilters.noIdentificacion} onChange={(e) => setConceptosFilters({ ...conceptosFilters, noIdentificacion: e.target.value })} />
|
||||
<div className="flex gap-2">
|
||||
<Button size="sm" className="flex-1" onClick={() => { setFilters({ ...filters, page: 1 }); setConceptosOpenFilter(null); }}>Aplicar</Button>
|
||||
{conceptosFilters.noIdentificacion && <Button size="sm" variant="outline" onClick={() => { setConceptosFilters({ ...conceptosFilters, noIdentificacion: '' }); setFilters({ ...filters, page: 1 }); }}>Limpiar</Button>}
|
||||
</div>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</th>
|
||||
<th className="pb-3 font-medium">RFC Emisor</th>
|
||||
<th className="pb-3 font-medium">RFC Receptor</th>
|
||||
<th className="pb-3 font-medium text-right">Cantidad</th>
|
||||
@@ -1676,6 +1701,7 @@ export default function CfdiPage() {
|
||||
<td className="py-2 font-mono text-xs" title={row.uuid}>{row.uuid?.substring(0, 8) || '-'}</td>
|
||||
<td className="py-2 font-mono text-xs">{row.clave_prod_serv || '-'}</td>
|
||||
<td className="py-2 text-left max-w-[280px] truncate" title={row.descripcion}>{row.descripcion}</td>
|
||||
<td className="py-2 font-mono text-xs" title={row.no_identificacion || ''}>{row.no_identificacion || '-'}</td>
|
||||
<td className="py-2 font-mono text-xs">{row.rfcEmisor}</td>
|
||||
<td className="py-2 font-mono text-xs">{row.rfcReceptor}</td>
|
||||
<td className="py-2 text-right">{Number(row.cantidad ?? 0).toLocaleString('es-MX', { minimumFractionDigits: 2 })}</td>
|
||||
|
||||
Reference in New Issue
Block a user