/* global React */ const { useState, useEffect, useMemo } = React; // ===================================================================== // MODAL DE SELEÇÃO DE ITENS DO XML // ===================================================================== // Props: // open — boolean // parsed — resultado de parseXmlNFe (com itens, totalNF, etc) // onCancel — fechar sem aplicar // onConfirm — recebe { selecao, parsed, grupos } da seleção // ===================================================================== function XmlSelectModal({ open, parsed, onCancel, onConfirm }) { // grupos derivados dos itens const grupos = useMemo(() => { if (!parsed || !parsed.ok) return []; return window.agruparItensXml(parsed.itens); }, [parsed]); // índices dos grupos selecionados const [selecionados, setSelecionados] = useState(new Set()); // Quando o modal abre, selecionar todos por padrão useEffect(() => { if (open && grupos.length > 0) { setSelecionados(new Set(grupos.map((_, i) => i))); } }, [open, grupos]); if (!open || !parsed || !parsed.ok) return null; const toggleItem = (idx) => { setSelecionados(prev => { const next = new Set(prev); if (next.has(idx)) next.delete(idx); else next.add(idx); return next; }); }; const selecionarTodos = () => setSelecionados(new Set(grupos.map((_, i) => i))); const limparSelecao = () => setSelecionados(new Set()); // Calcula totais com base na seleção atual const gruposSel = grupos.filter((_, i) => selecionados.has(i)); const totais = gruposSel.length > 0 ? window.calcularSelecaoXml(gruposSel, parsed) : null; const confirmar = () => { if (gruposSel.length === 0) return; onConfirm({ selecao: totais, parsed, grupos: gruposSel }); }; const brl = window.brl; const intFmt = window.intFmt; return (
e.stopPropagation()}>
Selecionar itens do XML
{parsed.fornecedor || 'Fornecedor não identificado'} {parsed.cnpj && · CNPJ {parsed.cnpj}} · {parsed.itens.length} item(s) total {parsed.isSimples && Simples Nacional}
{selecionados.size} de {grupos.length} grupo(s) selecionado(s)
{grupos.map((g, idx) => { const checked = selecionados.has(idx); return (
toggleItem(idx)}>
toggleItem(idx)} onClick={(e) => e.stopPropagation()} />
{g.xProd || '(sem descrição)'} {g.isST && ( ICMS-ST )}
{g.nItems.length > 1 ? {g.nItems.length}× linhas (#{g.nItems.join(', #')}) : Linha #{g.nItems[0]}} {g.ncms.length > 0 && · NCM {g.ncms.join('/')}} · {intFmt(g.qCom)} {g.unidades.join('/')} {g.aliqICMS > 0 && · ICMS {g.aliqICMS.toFixed(2)}%} {g.aliqIPI > 0 && · IPI {g.aliqIPI.toFixed(2)}%}
{brl(g.vProd)}
); })}
{totais && (
Valor total selecionado {brl(totais.valor)}
Quantidade {intFmt(totais.qtd)} {totais.unidade}
ICMS médio · IPI médio {totais.aliqICMS.toFixed(2)}% · {totais.aliqIPI.toFixed(2)}%
{(totais.frete > 0 || totais.seguro > 0 || totais.outras > 0 || totais.desconto > 0) && (
Despesas rateadas {totais.frete > 0 && `Frete ${brl(totais.frete)} `} {totais.seguro > 0 && `Seguro ${brl(totais.seguro)} `} {totais.outras > 0 && `Outras ${brl(totais.outras)} `} {totais.desconto > 0 && `Desc. -${brl(totais.desconto)}`}
)} {totais.hasST && (
⚠ Há item(ns) com ICMS-ST: crédito de ICMS será zerado para os itens marcados como ST.
)}
)}
); } window.XmlSelectModal = XmlSelectModal;