@fayz-ai/plugin-financial 0.25.9 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CashRegistersView-2G7DTIAA.js +4 -0
- package/dist/CashRegistersView-2G7DTIAA.js.map +1 -0
- package/dist/CommissionRulesView-2RW4ZCDT.js +878 -0
- package/dist/CommissionRulesView-2RW4ZCDT.js.map +1 -0
- package/dist/FinancialGeneralSettings-WXJOCJPZ.js +3 -0
- package/dist/FinancialGeneralSettings-WXJOCJPZ.js.map +1 -0
- package/dist/FinancialPage-PGODULVH.js +6484 -0
- package/dist/FinancialPage-PGODULVH.js.map +1 -0
- package/dist/PersonStatementWidget-ULXXXYZ4.js +214 -0
- package/dist/PersonStatementWidget-ULXXXYZ4.js.map +1 -0
- package/dist/chunk-7VKJLBYY.js +1736 -0
- package/dist/chunk-7VKJLBYY.js.map +1 -0
- package/dist/chunk-CNXAVGSW.js +13 -0
- package/dist/chunk-CNXAVGSW.js.map +1 -0
- package/dist/chunk-K37Q7SKX.js +4340 -0
- package/dist/chunk-K37Q7SKX.js.map +1 -0
- package/dist/chunk-MGDAJLUQ.js +823 -0
- package/dist/chunk-MGDAJLUQ.js.map +1 -0
- package/dist/chunk-POYZFEAN.js +64 -0
- package/dist/chunk-POYZFEAN.js.map +1 -0
- package/dist/components/BatchClassify.d.ts +26 -0
- package/dist/components/BatchClassify.d.ts.map +1 -0
- package/dist/components/CashSessionHeaderControl.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4944 -45345
- package/dist/index.js.map +1 -1
- package/dist/migrations/main.browser.js +143 -0
- package/dist/migrations/main.browser.js.map +1 -0
- package/dist/migrations/main.js +26230 -0
- package/dist/migrations/main.js.map +1 -0
- package/dist/payable-agent-TCKHUAQG.js +3 -0
- package/dist/payable-agent-TCKHUAQG.js.map +1 -0
- package/dist/views/ReconciliationView.d.ts.map +1 -1
- package/package.json +11 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/amount-in-words.ts","../src/views/payable-lines.ts","../src/views/document-memory.ts","../src/views/receipt-agent.ts","../src/views/payable-agent.tsx"],"names":["text","useChatStore","round2","revealPage"],"mappings":"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","file":"chunk-7VKJLBYY.js","sourcesContent":["// ---------------------------------------------------------------------------\n// O valor por extenso, virando número.\n//\n// Existe por causa de um recibo de táxi. Os algarismos estavam escritos à mão\n// como \"50|00\" — o traço que todo mundo usa para separar reais de centavos — e\n// o modelo leu \"5000\". Cem vezes o valor, e nada na imagem contradizia a\n// leitura: o traço simplesmente não é uma vírgula.\n//\n// Mas o papel dizia, na linha de baixo, \"a importância de CINQUENTA REAIS\". É\n// para isso que recibo e cheque escrevem o valor por extenso, e é por isso que\n// a convenção — no comércio e na lei — é que o extenso PREVALECE sobre os\n// algarismos. Aqui ele deixa de ser decoração e vira o desempate.\n// ---------------------------------------------------------------------------\n\nconst UNITS: Record<string, number> = {\n zero: 0, um: 1, uma: 1, dois: 2, duas: 2, tres: 3, quatro: 4, cinco: 5,\n seis: 6, sete: 7, oito: 8, nove: 9, dez: 10, onze: 11, doze: 12, treze: 13,\n catorze: 14, quatorze: 14, quinze: 15, dezesseis: 16, dezasseis: 16,\n dezessete: 17, dezassete: 17, dezoito: 18, dezenove: 19, dezanove: 19,\n vinte: 20, trinta: 30, quarenta: 40, cinquenta: 50, cincoenta: 50,\n sessenta: 60, setenta: 70, oitenta: 80, noventa: 90,\n cem: 100, cento: 100, duzentos: 200, duzentas: 200, trezentos: 300, trezentas: 300,\n quatrocentos: 400, quatrocentas: 400, quinhentos: 500, quinhentas: 500,\n seiscentos: 600, seiscentas: 600, setecentos: 700, setecentas: 700,\n oitocentos: 800, oitocentas: 800, novecentos: 900, novecentas: 900,\n}\n\nconst SCALES: Record<string, number> = {\n mil: 1_000, milhao: 1_000_000, milhoes: 1_000_000,\n bilhao: 1_000_000_000, bilhoes: 1_000_000_000,\n}\n\n/** Sem acento e sem pontuação: o extenso chega de uma leitura de foto, não de\n * um teclado — \"trÊs\", \"TRES\" e \"três,\" são a mesma palavra. */\nfunction normalize(text: string): string[] {\n return text\n .toLowerCase()\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .replace(/[^a-z\\s]/g, ' ')\n .split(/\\s+/)\n .filter(Boolean)\n}\n\n/** Soma um trecho sem escalas: \"cento e vinte e tres\" → 123. */\nfunction sumGroup(words: string[]): number {\n let total = 0\n for (const word of words) {\n const value = UNITS[word]\n if (value !== undefined) total += value\n }\n return total\n}\n\n/**\n * \"cinquenta reais\" → 50. \"cento e vinte e três reais e cinquenta centavos\" →\n * 123.5. Devolve null quando não há número nenhum ali — o extenso é opcional, e\n * ausente não é o mesmo que zero.\n */\nexport function parseAmountInWords(raw: unknown): number | null {\n if (typeof raw !== 'string') return null\n const words = normalize(raw)\n if (!words.length) return null\n\n // \"e cinquenta centavos\" é a parte fracionária; tudo antes são os inteiros.\n const centsAt = words.findIndex((w) => w === 'centavo' || w === 'centavos')\n const whole = centsAt >= 0 ? words.slice(0, centsAt) : words\n const cents = centsAt >= 0 ? sumGroup(words.slice(0, centsAt).slice(lastCurrencyIndex(words, centsAt))) : 0\n\n let total = 0\n let group: string[] = []\n let sawNumber = false\n for (const word of whole) {\n if (word === 'centavo' || word === 'centavos') break\n const scale = SCALES[word]\n if (scale !== undefined) {\n // \"mil\" sozinho é mil, não zero vezes mil.\n total += (sumGroup(group) || 1) * scale\n group = []\n sawNumber = true\n continue\n }\n if (UNITS[word] !== undefined) { group.push(word); sawNumber = true }\n }\n total += sumGroup(group)\n if (!sawNumber) return null\n\n // Os centavos vieram de um trecho DEPOIS da moeda (\"... reais e cinquenta\n // centavos\"); sem essa marca não há como separá-los dos inteiros.\n const value = centsAt >= 0 && cents > 0 && cents < 100 ? total - cents + cents / 100 : total\n return value > 0 ? Math.round(value * 100) / 100 : null\n}\n\n/** Onde começa a fração: logo depois de \"real\"/\"reais\". */\nfunction lastCurrencyIndex(words: string[], before: number): number {\n for (let i = before - 1; i >= 0; i--) {\n if (words[i] === 'real' || words[i] === 'reais') return i + 1\n }\n return before\n}\n","import { parseReceiptAmount } from './receipt-agent'\n\nexport interface PayableLine { description: string; quantity: number; unitPrice: number }\n\n/**\n * As linhas da tabela, como o modelo as leu.\n *\n * `unitPrice` chega como TEXTO pela mesma razão que `amount`: \"47,90\" vira\n * 4790 quando alguém trata a vírgula como separador de milhar, e num pedido de\n * doze unidades o erro sai multiplicado por doze. Um número cru ainda é aceito\n * aqui — ao contrário do total, uma linha errada é pega pela conferência da\n * soma logo em seguida, que é justamente o ponto dela.\n */\nexport function parseLineItems(raw: unknown): { items: PayableLine[]; error?: string } {\n if (raw === undefined || raw === null) return { items: [] }\n if (!Array.isArray(raw)) return { items: [], error: '`items` must be an array of table rows.' }\n\n const items: PayableLine[] = []\n for (const entry of raw) {\n if (!entry || typeof entry !== 'object') continue\n const row = entry as Record<string, unknown>\n const description = typeof row.description === 'string' ? row.description.trim() : ''\n const unitPrice = parseReceiptAmount(row.unitPrice)\n if (!description || unitPrice === null) {\n return {\n items: [],\n error:\n 'Every row needs a `description` and a readable `unitPrice` copied from the paper (\"47,90\"). '\n + 'Re-read the table and resend all rows.',\n }\n }\n const quantityRaw = typeof row.quantity === 'number' ? row.quantity : Number(row.quantity)\n const quantity = Number.isFinite(quantityRaw) && quantityRaw > 0 ? quantityRaw : 1\n items.push({ description, quantity, unitPrice })\n }\n return { items }\n}\n\n/** Texto que sobrou vazio é ausência, não string vazia. */\nexport function text(value: unknown): string | undefined {\n const s = typeof value === 'string' ? value.trim() : ''\n return s || undefined\n}\n\n/**\n * Hoje, no fuso de quem está lançando — não em UTC.\n *\n * `toISOString().slice(0,10)` é o dia em Greenwich: às 21h de São Paulo já é\n * amanhã lá, e uma conta paga \"hoje\" nasceria com a data de amanhã. Os campos\n * de data do produto são DIAS do calendário do negócio, e o calendário do\n * negócio é o do navegador de quem opera.\n */\nexport function today(): string {\n const now = new Date()\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`\n}\n\n","import { parseReceiptAmount, parseReceiptDate } from './receipt-agent'\nimport { round2 } from '@fayz-ai/financial/domain/money'\nimport { parseLineItems, text, type PayableLine } from './payable-lines'\n\n// ---------------------------------------------------------------------------\n// O DOCUMENTO, LIDO UMA VEZ SÓ\n//\n// O passo 0 conferia as três dependências e devolvia só isso. A conta vinha\n// depois, e o modelo relia o papel para preenchê-la — só que na segunda leitura\n// ele não tem mais o papel na frente, tem a lembrança da primeira. É aí que\n// \"1.489,19\" vira \"200,00\" e nasce um `amountInWords` que ninguém escreveu.\n//\n// Agora a extração inteira entra no passo 0, é NORMALIZADA aqui (os mesmos\n// parsers do resto: vírgula decimal, data brasileira, soma conferida) e fica\n// GUARDADA. A ferramenta seguinte consome o que ficou, em vez de reextrair.\n// ---------------------------------------------------------------------------\n\nexport interface PayableDocument {\n items: PayableLine[]\n subtotal?: number\n shipping?: number\n total?: number\n /** A soma das linhas mais frete bate com o total impresso. */\n reconciles: boolean\n lineSum?: number\n documentDate?: string\n /** `null` quando o papel não diz — à vista não tem vencimento, e o formulário pergunta. */\n dueDate: string | null\n paymentDate?: string\n orderRef?: string\n deliveryDate?: string\n method?: string\n}\n\ninterface StoredRead {\n at: number\n doc: PayableDocument\n /** De onde veio — só para diagnóstico e para a mensagem poder nomear o arquivo. */\n source?: string\n conversationId?: string\n}\n\nlet lastDocument: StoredRead | null = null\nconst DOCUMENT_TTL_MS = 15 * 60 * 1000\n\n// A LEITURA TEM DE SOBREVIVER A UM F5.\n//\n// Variável de módulo morre no reload, e quem está testando recarrega o tempo\n// todo. Sem persistir, recarregar entre o passo 0 e o lançamento fazia a\n// ferramenta cair EXATAMENTE no caminho que ela existe para eliminar: os\n// números que o modelo lembra, em vez dos que o documento diz — em silêncio,\n// que é o pior jeito de errar.\n//\n// `sessionStorage` e não `localStorage`: a leitura de um documento é assunto da\n// sessão de trabalho, não do navegador para sempre. Fecha a aba, acabou.\n//\n// A chave é uma só, e a escrita mais nova sobrepõe — é o que faz \"ler um\n// documento novo\" invalidar o anterior sem nenhuma lógica de expiração extra.\n// Não se exige que a conversa seja a mesma: depois do reload o cliente NÃO tem\n// mais o `conversationId` (a store não o persiste), e exigi-lo devolveria o\n// buraco que isto fecha. O TTL é quem limita o alcance.\nconst STORAGE_KEY = 'fayz:financial:last-document-read'\n\nfunction readStored(): StoredRead | null {\n try {\n const raw = globalThis.sessionStorage?.getItem(STORAGE_KEY)\n if (!raw) return null\n const parsed = JSON.parse(raw) as StoredRead\n return parsed && typeof parsed.at === 'number' && parsed.doc ? parsed : null\n } catch {\n // Aba anônima, armazenamento bloqueado, JSON corrompido: seguir sem memória\n // é pior que com ela, mas muito melhor que derrubar o lançamento.\n return null\n }\n}\n\nfunction writeStored(entry: StoredRead | null): void {\n try {\n if (entry) globalThis.sessionStorage?.setItem(STORAGE_KEY, JSON.stringify(entry))\n else globalThis.sessionStorage?.removeItem(STORAGE_KEY)\n } catch {\n /* sem persistência, a memória de módulo ainda vale dentro desta página */\n }\n}\n\n/** O que o passo 0 leu, enquanto ainda é o assunto da conversa. */\nexport function rememberedDocument(): PayableDocument | null {\n const entry = lastDocument ?? readStored()\n if (!entry) return null\n if (Date.now() - entry.at > DOCUMENT_TTL_MS) {\n clearRememberedDocument()\n return null\n }\n // Reidrata a memória de módulo depois de um reload, para as próximas\n // chamadas desta página não pagarem o JSON de novo.\n lastDocument = entry\n return entry.doc\n}\n\n/** O documento lido, com o que se sabe sobre a origem dele. */\nexport function rememberedRead(): StoredRead | null {\n return rememberedDocument() ? lastDocument : null\n}\n\nexport function clearRememberedDocument(): void {\n lastDocument = null\n writeStored(null)\n}\n\n/** Normaliza e confere o que o modelo leu do papel. Nada aqui é chute. */\nexport function normalizeDocument(args: Record<string, unknown>): PayableDocument {\n const parsed = parseLineItems(args.items)\n const items = parsed.error ? [] : parsed.items\n const shipping = parseReceiptAmount(args.shipping) ?? undefined\n const subtotal = parseReceiptAmount(args.subtotal) ?? undefined\n const total = parseReceiptAmount(args.total) ?? undefined\n const lineSum = items.length\n ? round2(items.reduce((s, i) => s + i.quantity * i.unitPrice, 0))\n : undefined\n const computed = lineSum === undefined ? undefined : round2(lineSum + (shipping ?? 0))\n // Sem linhas ou sem total não há o que conferir — e \"não confere\" seria uma\n // acusação falsa. Conferido é só quando os dois lados existem.\n const reconciles =\n computed === undefined || total === undefined ? false : Math.abs(computed - total) <= 0.02\n\n return {\n items,\n ...(subtotal === undefined ? {} : { subtotal }),\n ...(shipping === undefined ? {} : { shipping }),\n ...(total === undefined ? {} : { total }),\n ...(lineSum === undefined ? {} : { lineSum }),\n reconciles,\n ...(parseReceiptDate(args.documentDate) ? { documentDate: parseReceiptDate(args.documentDate)! } : {}),\n // `null` é uma RESPOSTA: \"o papel não diz\". Diferente de \"ainda não li\".\n dueDate: parseReceiptDate(args.dueDate) ?? null,\n ...(parseReceiptDate(args.paymentDate) ? { paymentDate: parseReceiptDate(args.paymentDate)! } : {}),\n ...(text(args.orderRef) ? { orderRef: text(args.orderRef)! } : {}),\n ...(parseReceiptDate(args.deliveryDate) ? { deliveryDate: parseReceiptDate(args.deliveryDate)! } : {}),\n ...(text(args.paymentMethod) ? { method: text(args.paymentMethod)! } : {}),\n }\n}\n\n\n/**\n * Guarda o que acabou de ser lido — em memória E no armazenamento da sessão.\n *\n * Uma leitura nova substitui a anterior: é o que garante que um segundo\n * documento não seja lançado com os números do primeiro.\n */\nexport function rememberDocument(\n doc: PayableDocument,\n meta?: { source?: string; conversationId?: string },\n): void {\n lastDocument = {\n at: Date.now(),\n doc,\n ...(meta?.source ? { source: meta.source } : {}),\n ...(meta?.conversationId ? { conversationId: meta.conversationId } : {}),\n }\n writeStored(lastDocument)\n}\n","import type { PluginAITool } from '@fayz-ai/core'\nimport { parseAmountInWords } from '../lib/amount-in-words'\nimport { rememberedDocument } from './document-memory'\nimport { text as textOf } from './payable-lines'\nimport { askAI, requestChatUpload, revealPage, toInlineFile, type AgentSurfaceTool, type AskAIIntro } from '@fayz-ai/admin'\nimport { useChatStore } from '@fayz-ai/admin'\n\n// ---------------------------------------------------------------------------\n// Um recibo fotografado, lido pelo assistente.\n//\n// A porta antiga abria o mesmo formulário de sempre com o seletor de arquivo\n// disparado: a foto virava anexo e a pessoa digitava tudo de novo olhando para\n// o papel que ela acabou de fotografar. Fotografar era o começo do trabalho, não\n// o fim dele.\n//\n// Aqui a foto é o pedido. O assistente lê, diz o que entendeu, e ENTREGA o\n// formulário preenchido — não grava nada. É a mesma regra do resto do produto:\n// o agente pergunta o essencial e sobe a ficha editável; quem confirma é quem\n// assina. E é a única forma honesta aqui, porque `createInvoice` não existe:\n// foi removida justamente por não conseguir exprimir `direction`, `invoiceDate`\n// e `installments[]` numa lista de parâmetros.\n// ---------------------------------------------------------------------------\n\n/** O convite da porta \"Enviar recibo\". */\nexport const RECEIPT_INTRO: AskAIIntro = {\n role: 'finance',\n persona: 'Leitor de recibos',\n pitch: 'Fotografe o recibo que eu leio e preencho a conta.',\n description:\n 'Leio o que está no papel — fornecedor, valor e data —, digo o que entendi e abro o cadastro já preenchido '\n + 'para você conferir. Não gravo nada sozinho: quem confirma é você.',\n suggestions: [\n { label: 'O que você consegue ler de um recibo?' },\n { label: 'E se a foto estiver torta ou escura?' },\n ],\n}\n\n// A ordem aqui não é estilo, é o que decide se a ferramenta é chamada.\n//\n// A primeira versão dizia \"chame a ferramenta; diga ANTES, em uma frase, o que\n// entendeu\". O modelo obedeceu a metade fácil: escreveu \"Entendi que o recibo é\n// de R$ 500,00… vou abrir o cadastro\" e encerrou o turno satisfeito. Um recibo\n// manuscrito, que já consome a atenção toda na leitura, cai nisso sempre.\n//\n// Agora a chamada é a única forma de terminar, e a frase é o que a ferramenta\n// devolve — não um passo antes dela.\nexport const RECEIPT_INSTRUCTIONS = [\n 'A pessoa vai mandar a FOTO de um recibo ou nota. Leia a imagem e extraia apenas o que está escrito nela.',\n 'Termine o turno CHAMANDO `openPayableDraft` com o que leu. Descrever o recibo em texto não abre nada:',\n 'sem a chamada a pessoa fica olhando para uma frase e para nenhum formulário. Não anuncie que vai abrir —',\n 'abra.',\n 'O valor vai COPIADO como está escrito — \"50,00\", não 5000. A vírgula é decimal em português, e',\n 'convertê-la você mesmo já transformou cinquenta reais em cinco mil.',\n 'Se o papel escreve o valor POR EXTENSO (\"CINQUENTA REAIS\"), copie em `amountInWords`. Num recibo',\n 'manuscrito é ele que manda: os algarismos vêm com um traço entre reais e centavos (\"50|00\") que não',\n 'é vírgula, e é exatamente por isso que o recibo escreve o valor duas vezes.',\n 'Preencha os campos NESTA ORDEM antes de chamar: valor, data, descrição, fornecedor — e só então',\n '`notes`, com o que sobrou. `notes` é o resto, nunca o lugar de algo que tem campo próprio: a data',\n 'escrita como \"Rio, 20/01/22\" é a DATA, e \"proveniente da prestação de serviço de táxi\" é a',\n 'DESCRIÇÃO. Enfiadas nas observações, elas somem dos campos onde a pessoa vai procurá-las.',\n 'NÃO confunda as linhas do recibo: \"a importância de CINQUENTA REAIS\" é o VALOR por extenso, não',\n 'um fornecedor chamado Cinquenta Reais. Sem um nome claro de quem recebeu, deixe `supplier` de fora.',\n 'Ponha em `notes` tudo o mais que está escrito e não coube nos outros campos: itinerário, placa,',\n 'número do documento, quem assinou. É onde a pessoa vai procurar o que o papel dizia.',\n 'NÃO invente campo que o papel não responde. Vencimento, categoria e conta de pagamento quase nunca estão',\n 'num recibo: deixe de fora. Campo vazio custa um toque; campo errado custa uma conferência inteira.',\n 'Só existe uma razão para NÃO chamar: a foto estar ilegível ou o valor total ambíguo. Aí pergunte — e',\n 'pergunte só isso, sem descrever o resto.',\n].join(' ')\n\nconst OPEN_DRAFT: PluginAITool = {\n id: 'financial.receipt.open-draft',\n name: 'openPayableDraft',\n description:\n 'Opens the \"new payable\" form pre-filled with what was read from a receipt photo. '\n + 'Call this as soon as you can read an amount — it is how a receipt turns into a record, '\n + 'and describing the receipt in prose instead leaves the person with a sentence and no form. '\n + 'Writes nothing: the person reviews the form and saves it. '\n + 'Send ONLY fields the receipt actually states — omit anything you would be guessing at.',\n icon: 'ReceiptText',\n mode: 'read',\n execution: { plane: 'client' },\n category: 'Finance',\n role: 'finance',\n parameters: {\n type: 'object',\n properties: {\n supplier: {\n type: 'string',\n description:\n 'Quem RECEBEU o dinheiro, se o papel nomear. Cuidado: \"Recebi de\" e \"a importância de\" '\n + 'não são nomes — a primeira é quem pagou e a segunda é o valor por extenso. '\n + 'Um recibo de táxi normalmente não tem fornecedor nenhum: omita em vez de inventar.',\n },\n amount: {\n type: 'string',\n description:\n 'O valor total COPIADO LETRA POR LETRA do papel, com a pontuação que estiver lá: '\n + '\"50,00\", \"1.234,56\", \"R$ 89,90\". NÃO converta para número e não tire a vírgula — '\n + 'quem lê a pontuação é o aplicativo, que sabe a moeda do país.',\n },\n amountInWords: {\n type: 'string',\n description:\n 'O valor POR EXTENSO, se o papel escrever (\"CINQUENTA REAIS\", \"cento e vinte reais e '\n + 'cinquenta centavos\"). Copie as palavras como estão. Num recibo manuscrito é ele que '\n + 'desempata: os algarismos costumam vir com um traço entre reais e centavos (\"50|00\"), '\n + 'que não é vírgula nenhuma.',\n },\n date: {\n type: 'string',\n description: 'A data do documento como está escrita (\"20/01/2022\", \"2022-01-20\"). Omita se o papel não diz.',\n },\n description: {\n type: 'string',\n description:\n 'O que foi pago, em poucas palavras — é o nome do item na conta. Um recibo quase sempre diz '\n + '(\"prestação de serviço de táxi\", \"insumos de padaria\"). Sem ele a conta nasce como '\n + '\"Sem descrição\", que não diz nada a quem for conferir depois.',\n },\n notes: {\n type: 'string',\n description:\n 'Todo o RESTO que está escrito e não coube nos campos acima: itinerário, placa, '\n + 'número do documento, condições, nome de quem assinou. Vai para as observações da conta, '\n + 'que é onde a pessoa procura o que o papel dizia. Copie o que leu; não resuma em uma palavra. '\n + 'NÃO repita aqui o que já foi para `date`, `amount` ou `description` — o resto significa o resto.',\n },\n },\n required: ['amount'],\n },\n}\n\n// ---------------------------------------------------------------------------\n// The same reader, from Contas a Receber.\n//\n// A receivable document is usually an NF-e the tenant ISSUED: the issuer\n// (emitente) is the tenant itself and the counterparty is the recipient\n// (destinatário). The payable reading names \"who received the money\", which on\n// that paper is the tenant — so a receivable opened from it named the tenant as\n// its own customer. This direction gets its own instructions and its own tool,\n// so the model is never asked to reinterpret the payable field.\n// ---------------------------------------------------------------------------\n\nexport type ReceiptDirection = 'payable' | 'receivable'\n\n/** The \"Digitalizar comprovante\" invitation in Contas a Receber (user-facing, pt-BR). */\nexport const RECEIVABLE_RECEIPT_INTRO: AskAIIntro = {\n role: 'finance',\n persona: 'Leitor de notas e comprovantes',\n pitch: 'Envie a nota que você emitiu e eu preencho a conta a receber.',\n description:\n 'Leio o que está no documento — cliente, valor, data, número e chave da NF-e —, digo o que entendi e abro '\n + 'a conta a receber já preenchida para você conferir. Não gravo nada sozinho: quem confirma é você.',\n suggestions: [\n { label: 'O que você consegue ler de uma nota fiscal?' },\n { label: 'E se a foto estiver torta ou escura?' },\n ],\n}\n\nexport const RECEIVABLE_RECEIPT_INSTRUCTIONS = [\n 'The person will send a PHOTO or PDF of a document for money they are going to RECEIVE: usually an NF-e/NFS-e',\n 'they ISSUED to a customer, or a receipt they gave. Read it and extract only what is written on it.',\n 'End the turn by CALLING `openReceivableDraft` with what you read. Describing the document in text opens nothing.',\n 'Do not announce that you will open it — open it. Talk to the person in Brazilian Portuguese.',\n 'THE COUNTERPARTY IS THE CUSTOMER. On an NF-e the person issued, the EMITENTE (issuer) is the person\\'s own',\n 'company: never send it as the customer. Send the DESTINATÁRIO / TOMADOR (recipient) name in `customer`.',\n 'On a receipt, the customer is the one who PAID (\"Recebi de ...\"). Without a clear customer name, omit `customer`.',\n 'Copy `amount` exactly as printed (\"1.234,56\"), never converted — the app parses the punctuation.',\n 'If the paper spells the amount out in words, copy it into `amountInWords`.',\n 'If it is an NF-e, copy the note NUMBER into `fiscalNumber` and the 44-digit ACCESS KEY (chave de acesso) into',\n '`accessKey`, digits only. Omit either one when the paper does not show it.',\n 'Use `date` for the issue date, `description` for what was sold, and `notes` for anything else written that has',\n 'no field of its own. Do not invent fields the paper does not answer.',\n 'The only reason NOT to call is an illegible photo or an ambiguous total: then ask only that.',\n].join(' ')\n\nconst OPEN_RECEIVABLE_DRAFT: PluginAITool = {\n id: 'financial.receipt.open-receivable-draft',\n name: 'openReceivableDraft',\n description:\n 'Opens the \"new receivable\" form pre-filled with what was read from an issued invoice (NF-e) or receipt. '\n + 'Call this as soon as you can read an amount. Writes nothing: the person reviews the form and saves it. '\n + 'Send ONLY fields the document actually states — omit anything you would be guessing at.',\n icon: 'ReceiptText',\n mode: 'read',\n execution: { plane: 'client' },\n category: 'Finance',\n role: 'finance',\n parameters: {\n type: 'object',\n properties: {\n customer: {\n type: 'string',\n description:\n 'Who OWES / PAID the money: the DESTINATÁRIO or TOMADOR on an NF-e, or \"Recebi de ...\" on a receipt. '\n + 'NEVER the EMITENTE of an NF-e — that is the person\\'s own company. Omit when not named.',\n },\n amount: {\n type: 'string',\n description: 'The total COPIED as printed, punctuation included (\"50,00\", \"1.234,56\"). Do not convert it.',\n },\n amountInWords: {\n type: 'string',\n description: 'The amount spelled out in words, if the paper writes it. Copy the words as they are.',\n },\n date: {\n type: 'string',\n description: 'The issue date as written (\"20/01/2026\", \"2026-01-20\"). Omit if absent.',\n },\n description: {\n type: 'string',\n description: 'What was sold or provided, in a few words. It becomes the item name on the receivable.',\n },\n fiscalNumber: {\n type: 'string',\n description: 'The NF-e / NFS-e number (e.g. \"1234\" or \"000.001.234\"), when the document is a fiscal note.',\n },\n accessKey: {\n type: 'string',\n description: 'The NF-e 44-digit access key (\"chave de acesso\"), when printed. Digits only.',\n },\n notes: {\n type: 'string',\n description:\n 'Everything ELSE written that has no field above. Do not repeat the amount, date, description, number or key.',\n },\n },\n required: ['amount'],\n },\n}\n\n/** An NF-e access key is 44 digits; anything else is a misread, not a key. */\nexport function parseAccessKey(raw: unknown): string | undefined {\n if (typeof raw !== 'string') return undefined\n const digits = raw.replace(/\\D/g, '')\n return digits.length === 44 ? digits : undefined\n}\n\n/**\n * O valor como está no papel, virando número.\n *\n * O modelo NÃO faz essa conta. Ele leu \"50,00\" num recibo de táxi e mandou\n * 5000: a vírgula decimal do português é um separador de milhar em inglês, e um\n * erro de 100x num lançamento financeiro passa despercebido até a conciliação.\n * Por isso o parâmetro é texto — a pontuação chega intacta e quem a interpreta é\n * este código, que sabe em que país está e pode ser testado.\n *\n * Regra: o ÚLTIMO separador manda. \"1.234,56\" e \"1,234.56\" são o mesmo número\n * escrito em dois idiomas, e em ambos o que vem depois do último ponto ou\n * vírgula são os centavos — a menos que sejam três dígitos, e aí era milhar\n * (\"5.000\" é cinco mil, não cinco).\n */\nexport function parseReceiptAmount(raw: unknown): number | null {\n if (typeof raw === 'number') return Number.isFinite(raw) && raw > 0 ? raw : null\n if (typeof raw !== 'string') return null\n\n const text = raw.replace(/[^\\d.,-]/g, '').trim()\n if (!text || !/\\d/.test(text)) return null\n\n const lastComma = text.lastIndexOf(',')\n const lastDot = text.lastIndexOf('.')\n const cut = Math.max(lastComma, lastDot)\n\n let normalized: string\n if (cut < 0) {\n normalized = text\n } else {\n const decimals = text.length - cut - 1\n // Três casas depois do último separador é agrupamento de milhar, não\n // centavos: \"5.000\" e \"5,000\" são cinco mil nos dois idiomas.\n normalized = decimals === 3\n ? text.replace(/[.,]/g, '')\n : `${text.slice(0, cut).replace(/[.,]/g, '')}.${text.slice(cut + 1)}`\n }\n\n const value = Number(normalized)\n return Number.isFinite(value) && value > 0 ? value : null\n}\n\n/**\n * A data como está no papel, virando YYYY-MM-DD.\n *\n * Mesma história do valor: o modelo devolve o que leu, e num recibo brasileiro\n * isso é \"20/01/2022\". A primeira versão exigia ISO e DESCARTAVA o resto —\n * silenciosamente, o que é o pior jeito de errar: o papel respondia a data e a\n * tela abria com o campo vazio, sem nada dizendo por quê.\n *\n * Dia antes do mês: é a ordem do país em que este recibo foi escrito. Quando os\n * dois cabem em 12 não há como distinguir pelo número, e chutar a ordem\n * americana num recibo em português erra onze meses por ano.\n */\nexport function parseReceiptDate(raw: unknown): string | undefined {\n const text = typeof raw === 'string' ? raw.trim() : ''\n if (!text) return undefined\n\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(text)) return isRealDate(text) ? text : undefined\n\n const br = text.match(/^(\\d{1,2})[/.-](\\d{1,2})[/.-](\\d{2}|\\d{4})$/)\n if (!br) return undefined\n const [, d, m, y] = br\n // \"22\" é 2022, não 1922: um recibo é um documento recente por natureza.\n const year = y.length === 2 ? `20${y}` : y\n const iso = `${year}-${m.padStart(2, '0')}-${d.padStart(2, '0')}`\n return isRealDate(iso) ? iso : undefined\n}\n\n/** A primeira data solta num texto corrido. Só dígitos: \"20/01/22\", \"5-3-2026\". */\nexport function findDateIn(text: unknown): string | undefined {\n if (typeof text !== 'string') return undefined\n return text.match(/\\b\\d{1,2}[/.-]\\d{1,2}[/.-](?:\\d{4}|\\d{2})\\b/)?.[0]\n}\n\n/** 31 de fevereiro passa em qualquer regex e em nenhum calendário. */\nfunction isRealDate(iso: string): boolean {\n const [y, m, d] = iso.split('-').map(Number)\n const date = new Date(Date.UTC(y, m - 1, d))\n return date.getUTCFullYear() === y && date.getUTCMonth() === m - 1 && date.getUTCDate() === d\n}\n\n/** O rascunho que o formulário consome ao montar. */\nexport interface PayableDraft {\n supplier?: string\n amount: number\n /** As linhas da tabela, quando o documento tem uma. O formulário abre com\n * todas — uma linha só de \"serviço prestado\" perde o pedido inteiro. */\n items?: Array<{ description: string; quantity: number; unitPrice: number }>\n /** O frete cobrado à parte, que vira linha própria. */\n shipping?: number\n date?: string\n description?: string\n /** O resto do que estava escrito — vai para as observações. */\n notes?: string\n /** A própria foto, para nascer anexada ao pagamento. */\n receiptUrl?: string\n /** Which form the draft belongs to. Absent = payable (the original reader). */\n direction?: 'debit' | 'credit'\n /** The customer, on a receivable draft (the NF-e recipient). */\n customer?: string\n /** The NF-e number, on a receivable draft. */\n fiscalNumber?: string\n /** The NF-e access key, on a receivable draft. */\n accessKey?: string\n}\n\n// Variável de módulo e não store: o rascunho vive entre uma navegação e a\n// montagem seguinte, e nada mais precisa reagir a ele. Consumido uma vez —\n// voltar para o cadastro depois não pode ressuscitar um recibo antigo.\nlet pending: PayableDraft | null = null\n\n/**\n * Takes the pending draft. With a `direction`, a draft read for the OTHER form is\n * dropped instead of seeded: a receivable read must never open as a payable.\n */\nexport function consumePayableDraft(direction?: 'debit' | 'credit'): PayableDraft | null {\n const draft = pending\n pending = null\n if (draft && direction && (draft.direction ?? 'debit') !== direction) return null\n return draft\n}\n\n// A foto que a pessoa acabou de mandar, guardada entre o upload e a chamada da\n// ferramenta. Mesmo motivo do rascunho: vive entre dois momentos e nada reage a\n// ela no meio do caminho.\nlet lastPhoto: string | undefined\n\nexport function rememberReceiptPhoto(dataUrl: string | undefined): void {\n lastPhoto = dataUrl\n}\n\nexport function lastReceiptPhoto(): string | undefined {\n return lastPhoto\n}\n\nexport interface ReceiptToolDeps {\n /** Chamado depois de guardar o rascunho — normalmente navega para o cadastro. */\n onDraft: () => void\n /** A foto que a pessoa acabou de mandar, como data URL. */\n getReceiptUrl?: () => string | undefined\n /** Which list the reader was opened from. Default: payable. */\n direction?: ReceiptDirection\n}\n\n/** The amount as the tool received it, or the correctable error to send back. */\nfunction readAmount(args: Record<string, unknown>):\n | { ok: true; amount: number; spelled: number | null; figures: number | null }\n | { ok: false; error: string; message: string } {\n if (typeof args.amount !== 'string') {\n return {\n ok: false,\n error: 'amount_must_be_literal',\n message:\n 'Send `amount` as the TEXT printed on the receipt, punctuation included (\"50,00\", '\n + '\"1.234,56\") — never as a number. A decimal comma is a thousands separator in English, '\n + 'so converting it yourself turns fifty into five thousand. Read the paper again and resend.',\n }\n }\n const figures = parseReceiptAmount(args.amount)\n // Words win over figures: that is why receipts and cheques write the amount twice.\n const spelled = parseAmountInWords(args.amountInWords)\n const amount = spelled ?? figures\n if (amount === null) {\n return {\n ok: false,\n error: 'invalid_amount',\n message: 'That is not a readable amount. If the total is illegible on the photo, ask the person.',\n }\n }\n return { ok: true, amount, spelled, figures }\n}\n\nfunction trimmed(value: unknown): string | undefined {\n const s = typeof value === 'string' ? value.trim() : ''\n return s || undefined\n}\n\nfunction createReceivableReceiptTools({ onDraft, getReceiptUrl }: Required<Omit<ReceiptToolDeps, 'direction'>>): AgentSurfaceTool[] {\n return [\n {\n tool: OPEN_RECEIVABLE_DRAFT,\n // The payable path's `rememberedDocument` is NOT read here: it is a\n // supplier-side reading, and seeding a receivable from it would bring the\n // issuer back as the counterparty.\n execute: async (args) => {\n const read = readAmount(args)\n if (!read.ok) return read\n const accessKey = parseAccessKey(args.accessKey)\n const notes = [\n trimmed(args.notes),\n accessKey ? `Chave de acesso NF-e: ${accessKey}` : undefined,\n ].filter(Boolean).join(' · ') || undefined\n pending = {\n direction: 'credit',\n amount: read.amount,\n customer: trimmed(args.customer),\n description: trimmed(args.description),\n fiscalNumber: trimmed(args.fiscalNumber),\n accessKey,\n notes,\n date: parseReceiptDate(args.date) ?? parseReceiptDate(findDateIn(args.notes)),\n receiptUrl: getReceiptUrl(),\n }\n onDraft()\n revealPage()\n return {\n ok: true,\n opened: true,\n ...(read.spelled !== null && read.figures !== null && Math.abs(read.spelled - read.figures) > 0.005\n ? { amountFromWords: read.spelled, amountFromFigures: read.figures,\n note: `The figures looked like ${read.figures} and the words say ${read.spelled}. The words were used — tell the person.` }\n : {}),\n filled: Object.entries(pending)\n .filter(([, v]) => v !== undefined && v !== '')\n .map(([k]) => k),\n }\n },\n },\n ]\n}\n\nexport function createReceiptTools({ onDraft, getReceiptUrl = lastReceiptPhoto, direction = 'payable' }: ReceiptToolDeps): AgentSurfaceTool[] {\n if (direction === 'receivable') return createReceivableReceiptTools({ onDraft, getReceiptUrl })\n return [\n {\n tool: OPEN_DRAFT,\n execute: async (args) => {\n // Um NÚMERO não é confiável aqui, por mais que pareça um.\n //\n // O schema pede texto, mas schema é pedido, não garantia: o modelo pode\n // mandar 5000 mesmo assim, e 5000 é exatamente o que \"50,00\" vira quando\n // alguém trata a vírgula como separador de milhar. Aceitar o número era\n // deixar a porta de trás aberta para o mesmo erro de cem vezes.\n //\n // Devolver um erro CORRIGÍVEL em vez de recusar: o modelo relê o papel e\n // reenvia o literal. Custa uma rodada e vale um lançamento certo.\n // A LEITURA DO PASSO 0 GANHA DE UMA RELEITURA.\n //\n // Foi por aqui que passou o lançamento de R$ 200,00 num pedido de\n // 1.489,19: o modelo abriu o rascunho com números que não estavam em\n // lugar nenhum do papel. Quando `resolvePayableContext` já leu o\n // documento nesta conversa, é ele quem manda — e o rascunho abre com as\n // LINHAS de verdade, não com uma linha genérica carregando um total.\n const read = rememberedDocument()\n if (read && read.total !== undefined) {\n pending = {\n amount: read.total,\n ...(read.items.length ? { items: read.items } : {}),\n ...(read.shipping === undefined ? {} : { shipping: read.shipping }),\n supplier: textOf(args.supplier) ?? undefined,\n description: textOf(args.description) ?? undefined,\n notes: [\n textOf(args.notes),\n read.orderRef ? `Pedido: ${read.orderRef}` : null,\n read.deliveryDate ? `Entrega: ${read.deliveryDate}` : null,\n ].filter(Boolean).join(' · ') || undefined,\n date: read.documentDate ?? parseReceiptDate(args.date),\n receiptUrl: getReceiptUrl(),\n }\n onDraft()\n revealPage()\n return {\n ok: true,\n opened: true,\n fromDocument: true,\n items: read.items.length,\n total: read.total,\n message:\n 'O cadastro abriu com o que foi LIDO do documento — '\n + `${read.items.length || 1} linha(s), total ${read.total}. Diga isso em UMA frase e pare. `\n + 'Não repita os valores campo a campo e NÃO os recalcule: a pessoa está olhando para eles.',\n }\n }\n\n if (typeof args.amount !== 'string') {\n return {\n ok: false,\n error: 'amount_must_be_literal',\n message:\n 'Send `amount` as the TEXT printed on the receipt, punctuation included (\"50,00\", '\n + '\"1.234,56\") — never as a number. A decimal comma is a thousands separator in English, '\n + 'so converting it yourself turns fifty into five thousand. Read the paper again and resend.',\n }\n }\n const figures = parseReceiptAmount(args.amount)\n // O extenso PREVALECE sobre os algarismos. Não é preferência: é para\n // isso que recibo e cheque escrevem o valor por extenso, e é a regra que\n // o comércio e a lei já seguem. Num manuscrito os algarismos vêm com um\n // traço entre reais e centavos (\"50|00\") que nenhuma leitura distingue\n // de \"5000\" — e a linha de baixo dizia \"CINQUENTA REAIS\".\n const spelled = parseAmountInWords(args.amountInWords)\n const amount = spelled ?? figures\n\n if (amount === null) {\n return {\n ok: false,\n error: 'invalid_amount',\n message: 'That is not a readable amount. If the total is illegible on the photo, ask the person.',\n }\n }\n\n const text = (value: unknown): string | undefined => {\n const s = typeof value === 'string' ? value.trim() : ''\n return s || undefined\n }\n // Aceita o que o papel escreveu, no formato que ele escreveu — e, quando\n // o campo vem vazio, procura a data na prosa. Num recibo ela costuma\n // aparecer como \"Rio, 20/01/22\", grudada na cidade, e o modelo a manda\n // inteira para as observações. Deixar o campo em branco por causa de uma\n // vírgula seria perder um dado que o papel respondeu.\n const isoDate = parseReceiptDate(args.date) ?? parseReceiptDate(findDateIn(args.notes))\n\n pending = {\n amount,\n supplier: text(args.supplier),\n description: text(args.description),\n notes: text(args.notes),\n date: isoDate,\n receiptUrl: getReceiptUrl(),\n }\n onDraft()\n // O rascunho vive no navegador: não há registro salvo, então não há\n // link para oferecer. O que a pessoa precisa é VER o formulário — e no\n // celular ele abriu atrás do painel do assistente.\n revealPage()\n return {\n ok: true,\n opened: true,\n // Divergiram: o formulário abriu com o extenso, e quem assina merece\n // saber que os algarismos diziam outra coisa.\n ...(spelled !== null && figures !== null && Math.abs(spelled - figures) > 0.005\n ? { amountFromWords: spelled, amountFromFigures: figures,\n note: `Os algarismos pareciam ${figures} e o extenso diz ${spelled}. Usei o extenso, que é o que vale num recibo — diga isso à pessoa.` }\n : {}),\n filled: Object.entries(pending)\n .filter(([, v]) => v !== undefined && v !== '')\n .map(([k]) => k),\n }\n },\n },\n ]\n}\n\n// ---------------------------------------------------------------------------\n// A porta: \"Enviar recibo\"\n// ---------------------------------------------------------------------------\n\n/**\n * Abre o assistente pedindo a foto, e manda a foto para ser LIDA.\n *\n * `capture: 'environment'` abre a câmera traseira direto no celular — quem está\n * com o papel na mão não quer passear pela galeria. E os bytes vão pelo canal\n * de leitura (`queuePrompt(..., files)`), não pelo `+` do composer: aquele\n * estagia arquivo para ser DESCRITO, e um recibo descrito não é um recibo lido.\n */\nexport function startReceiptCapture(labels: {\n ask: string\n uploadLabel: string\n uploadHint: string\n prompt: string\n /** Which list the capture started from. Default: payable. */\n direction?: ReceiptDirection\n}): void {\n rememberReceiptPhoto(undefined)\n askAI({ hint: labels.ask, intro: labels.direction === 'receivable' ? RECEIVABLE_RECEIPT_INTRO : RECEIPT_INTRO })\n requestChatUpload({\n label: labels.uploadLabel,\n description: labels.uploadHint,\n accept: 'image/*,application/pdf',\n capture: 'environment',\n onFiles: async (files) => {\n const photo = files[0]\n if (!photo) return\n // A MESMA foto vira o comprovante do pagamento, então ela é guardada como\n // data URL aqui: ler e anexar são duas coisas, e fotografar duas vezes\n // para fazer as duas seria o produto perdendo a única foto que tinha.\n if (photo.type.startsWith('image/')) {\n const inline = await toInlineFile(photo)\n rememberReceiptPhoto(`data:${inline.mime};base64,${inline.data}`)\n }\n useChatStore.getState().queuePrompt(labels.prompt, [photo])\n },\n })\n}\n","import * as React from 'react'\nimport type { PluginAITool } from '@fayz-ai/core'\nimport {\n adminNavigateTo,\n createArchetypeLookup,\n resolveEntityRoute,\n revealPage,\n useAgentSurface,\n useChatStore,\n type AgentSurfaceContribution,\n type AgentSurfaceTool,\n type EntityLookup,\n} from '@fayz-ai/admin'\n\nimport type { ResolvedFinancialConfig } from '../context'\nimport type { FinancialDataProvider } from '@fayz-ai/financial/data/provider'\nimport type { BankAccount, BankAccountType } from '@fayz-ai/financial/domain/account'\nimport { parseAmountInWords } from '../lib/amount-in-words'\nimport { parseReceiptAmount, parseReceiptDate, findDateIn, consumePayableDraft } from './receipt-agent'\nimport { round2 } from '@fayz-ai/financial/domain/money'\nimport { parseLineItems, text, today, type PayableLine } from './payable-lines'\nimport {\n rememberDocument,\n rememberedDocument,\n normalizeDocument,\n type PayableDocument,\n} from './document-memory'\nimport { formatCurrency } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Lançar uma conta a pagar, de onde quer que a pessoa esteja.\n//\n// A porta de lançar uma despesa existia só DENTRO da lista de contas a pagar\n// (ver ReceiptAgentSurface): fora dela o assistente não tinha ferramenta\n// nenhuma para uma despesa, e o catálogo de escrita do Financeiro é só o de\n// registros de configuração. Pedido \"salva essa conta a pagar do fornecedor\n// X\", o modelo pegou o substantivo financeiro mais próximo que sabia escrever\n// — `financial:payment-methods` — e propôs cadastrar o FORNECEDOR como uma\n// forma de pagamento. Não foi o modelo alucinando: era a única porta aberta.\n//\n// Por isso esta superfície não é de tela, é de app: montada no shell, vale em\n// qualquer rota. Ver FinancialAgentMount no manifesto do plugin.\n// ---------------------------------------------------------------------------\n\n/**\n * O domínio, dito ao modelo uma vez.\n *\n * Curto de propósito: vai no prompt de TODO turno do app, não só quando alguém\n * fala de dinheiro. O que ele precisa saber é qual porta é qual — o resto está\n * na descrição de cada ferramenta.\n */\nexport const PAYABLE_INSTRUCTIONS = [\n 'Uma \"conta a pagar\" é uma DESPESA com um FORNECEDOR — quem a empresa deve. Para registrar uma,',\n 'chame `createPayable`. NUNCA use `createRecord` em `financial:payment-methods` para isso: aquele',\n 'registro configura como os CLIENTES pagam a empresa (bandeira, taxa, parcelamento), e um',\n 'fornecedor cadastrado lá não vira conta nenhuma — vira lixo na configuração da loja.',\n 'Se a pessoa mandar a FOTO de um recibo ou de uma nota, leia a imagem e use o que está escrito',\n 'nela. Uma foto não tem colunas: nunca proponha importação para ela.',\n 'Num pedido ou nota com TABELA, leia a tabela LINHA A LINHA e mande todas em `items` — código,',\n 'descrição, quantidade e preço unitário de cada uma. Uma linha genérica de \"serviço prestado\" com',\n 'o total dentro perde o pedido inteiro. O FRETE é campo próprio (`shipping`), não some ao produto.',\n '`amount` é sempre o TOTAL do rodapé (com frete), nunca o subtotal e nunca o total de uma linha.',\n 'Capture também \"Método de pagamento:\" quando impresso, o NÚMERO DO PEDIDO (\"Pedido: #164223\") e a',\n 'data de ENTREGA — pedido e entrega vão em `notes`, que é onde a pessoa procura o que o papel dizia.',\n 'Se o texto trouxer uma linha como \"[código Pix copia-e-cola — valor embutido: X]\", aquilo é o',\n 'código do pagamento: X confirma o total, e os dígitos em volta NÃO são preços.',\n '\"Expira em\" de um código Pix é a validade do CÓDIGO, não o vencimento da conta. Um pedido pago à',\n 'vista não tem vencimento: deixe `dueDate` de fora e o formulário pergunta. Data chutada custa uma',\n 'cobrança; campo vazio custa um toque.',\n 'LEU UM PAPEL? PASSO 0 é `resolvePayableContext`, ANTES de escrever qualquer coisa. Extraia TUDO o',\n 'que está escrito — fornecedor, CNPJ, o que foi comprado, forma de pagamento, bandeira e final do',\n 'cartão, datas, valores — e mande para conferir contra o que este negócio já tem. Ele responde o',\n 'que existe e o que falta, sem gravar nada. Diga o resultado em uma linha curta por dependência e',\n 'resolva as que faltam NA ORDEM que ele devolve: fornecedor, forma de pagamento, depois a conta,',\n 'depois a baixa. Se voltar um candidato parecido, PERGUNTE se é o mesmo — não cadastre de novo.',\n 'Valor vai COPIADO como está escrito (\"50,00\", \"1.234,56\"), nunca convertido — a vírgula é',\n 'decimal em português, e convertê-la você mesmo já transformou cinquenta reais em cinco mil.',\n 'Não entreviste a pessoa campo a campo. Mande o que ela disse e chame a ferramenta: o que abre',\n 'é um FORMULÁRIO editável, e o que faltar ela preenche ali — em um toque, olhando os campos.',\n 'Uma conta a pagar tem TRÊS passos, cada um confirmado pela pessoa: (1) o fornecedor, (2) o título,',\n '(3) o pagamento — e o terceiro só existe se a conta JÁ foi paga. Se o recibo ou a pessoa disser',\n 'que já pagou (\"pago hoje\", \"paguei no Pix\"), mande `paid: true`; a ferramenta cuida da ordem.',\n 'Quando faltar saber COMO foi pago, a ferramenta PERGUNTA com as opções do próprio negócio na tela.',\n 'Não repita as opções em texto e não escolha por ela: espere a resposta e então chame',\n '`registerPayablePayment` com o id que ela tocou.',\n 'REGRA DE PRECEDÊNCIA: se o cadastro de conta a pagar estiver ABERTO na tela com um rascunho (veja',\n '\"Tela aberta agora\"), ele é a conta em curso. Complete-o com `fillPayableDraft` e salve com',\n '`submitPayableDraft`. `createPayable` é só para quando NÃO há rascunho aberto — chamá-la com o',\n 'formulário na tela cria uma segunda conta e deixa a pessoa num rascunho órfão.',\n 'Depois de lançar, a tela da conta abre sozinha — é o normal e não precisa ser anunciado. Mande',\n '`redirect: false` só quando levar a pessoa embora atrapalharia: várias contas em sequência, ou',\n 'alguém no meio de outra tarefa que só passou a conta de lado.',\n '\"Marca como pago\", \"paguei\", \"foi pago\" sobre uma conta que VOCÊ acabou de lançar é sempre',\n '`registerPayablePayment` com o invoiceId daquela conta — NUNCA `createPayable` de novo. Lançar a',\n 'mesma despesa duas vezes é dinheiro contado em dobro, e desfazer isso é trabalho de conciliação.',\n].join(' ')\n\nconst CREATE_PAYABLE: PluginAITool = {\n id: 'financial.create-payable',\n name: 'createPayable',\n description:\n 'Records a BILL THE BUSINESS OWES a supplier (conta a pagar, despesa, boleto, invoice from a vendor). '\n + 'This is the tool for \"lançar/salvar uma conta a pagar\", \"paguei o fornecedor X\", \"recibo de despesa\". '\n + 'It walks a CHECKLIST, one confirmable step at a time: (1) the supplier — found by name or created as a '\n + 'supplier contact, (2) the bill itself. Each step opens an EDITABLE FORM pre-filled with what you send and '\n + 'writes nothing until the person confirms it — so call it as soon as you have an amount and let the forms '\n + 'ask for the rest. '\n + 'If the receipt says it was ALREADY PAID (\"pago hoje\", \"paguei via Pix\"), set `paid: true`: step (3) is the '\n + 'payment, and this tool will either ask HOW it was paid or hand you off to `registerPayablePayment`. '\n + 'Send ONLY what you were actually told or could read; omit anything you would be guessing at. '\n + 'When the bill came off a receipt/photo/PDF, call `resolvePayableContext` FIRST and settle the missing '\n + 'dependencies it reports before calling this. '\n + 'A document with a TABLE goes in row by row through `items` (plus `shipping` for frete): the lines are '\n + 'reconciled against `amount`, and a mismatch comes back to be asked about rather than silently trusted. '\n + 'DO NOT use this when a payable form is already open on screen (a draft read from a receipt or PDF): '\n + 'that draft is the bill in progress — use `fillPayableDraft` and `submitPayableDraft` instead, or this '\n + 'writes a second, duplicate bill and strands the person on a draft that no longer means anything.',\n icon: 'ReceiptText',\n mode: 'persist',\n execution: { plane: 'client' },\n // O guard é desta ferramenta: ela abre o próprio cartão de confirmação, que é\n // um formulário. O cartão genérico do loop seria um segundo \"tem certeza?\"\n // antes do formulário — duas perguntas para uma decisão.\n requiresConfirmation: false,\n category: 'Finance',\n role: 'finance',\n permission: { feature: 'financial', action: 'create' },\n limitKey: 'movements_month',\n parameters: {\n type: 'object',\n properties: {\n supplier: {\n type: 'string',\n description:\n 'Quem RECEBE o dinheiro — o fornecedor, a empresa, o prestador. É um NOME de quem foi pago '\n + '(\"Printi\", \"Padaria do Zé\"). Não é o que foi comprado nem o valor por extenso.',\n },\n amount: {\n type: 'string',\n description:\n 'O valor TOTAL da conta — o que vai ser pago, incluindo frete. Num pedido é o \"Total\" do '\n + 'rodapé, nunca o subtotal e nunca o total de uma linha. '\n + 'COPIADO LETRA POR LETRA, com a pontuação que estiver escrita: \"50,00\", '\n + '\"1.234,56\", \"R$ 89,90\". NÃO converta para número e não tire a vírgula — quem lê a '\n + 'pontuação é o aplicativo, que sabe a moeda do país.',\n },\n amountInWords: {\n type: 'string',\n description:\n 'O valor POR EXTENSO, quando o papel escrever (\"CINQUENTA REAIS\"). Num recibo manuscrito é '\n + 'ele que desempata os algarismos. Copie as palavras como estão.',\n },\n dueDate: {\n type: 'string',\n description:\n 'O VENCIMENTO, como está escrito (\"20/01/2026\", \"2026-01-20\"). Omita se ninguém disse — '\n + 'o formulário pergunta. Uma data de vencimento chutada custa uma conferência inteira.',\n },\n date: {\n type: 'string',\n description: 'A data do DOCUMENTO (quando a compra aconteceu), se souber. \"hoje\" é hoje.',\n },\n description: {\n type: 'string',\n description:\n 'O que foi comprado ou pago, em poucas palavras — é o nome da linha da conta '\n + '(\"cartões de visita\", \"insumos de padaria\"). Sem ela a conta nasce sem dizer o que é.',\n },\n items: {\n type: 'array',\n description:\n 'As LINHAS da nota, uma por linha da tabela — leia a tabela linha a linha e copie todas. '\n + 'Um pedido de três produtos vira três linhas aqui, não uma linha genérica de \"serviço '\n + 'prestado\": é assim que a conta diz depois o que foi comprado. Omita quando o papel não '\n + 'tem tabela (um recibo de táxi é uma linha só, e aí basta `description`).',\n items: {\n type: 'object',\n properties: {\n description: { type: 'string', description: 'O que é a linha, como está escrito (código + nome).' },\n quantity: { type: 'number', description: 'A quantidade da linha. 1 quando a tabela não diz.' },\n unitPrice: {\n type: 'string',\n description:\n 'O preço UNITÁRIO copiado letra por letra (\"47,90\"), não o total da linha e não convertido.',\n },\n },\n required: ['description', 'unitPrice'],\n },\n },\n shipping: {\n type: 'string',\n description:\n 'O FRETE, copiado como está escrito (\"52,19\"), quando o papel o cobra em separado. '\n + 'Vira uma linha própria na conta — somado a um produto ele desapareceria dentro do preço dele.',\n },\n notes: {\n type: 'string',\n description:\n 'Todo o RESTO que foi dito e não coube nos campos acima: NÚMERO DO PEDIDO ou do documento '\n + '(\"Pedido: #164223\"), data de entrega, condições, para qual projeto. É onde a pessoa vai '\n + 'procurar o que o papel dizia. NÃO repita aqui o que já foi para os outros campos.',\n },\n paid: {\n type: 'boolean',\n description:\n 'true quando a conta JÁ FOI PAGA — \"pago hoje\", \"paguei via Pix\", um recibo quitado. '\n + 'Uma conta paga tem um terceiro passo: registrar o pagamento. Não marque true por um '\n + 'boleto ou uma nota que ainda vai vencer.',\n },\n paymentMethod: {\n type: 'string',\n description:\n 'COMO foi pago, se a pessoa disse (\"Pix\", \"dinheiro\", \"cartão de crédito\"). Não chute: '\n + 'sem isto a ferramenta PERGUNTA, oferecendo as formas que este negócio aceita.',\n },\n paymentDate: {\n type: 'string',\n description: 'QUANDO foi pago, se disserem. \"pago hoje\" é hoje.',\n },\n redirect: {\n type: 'boolean',\n description:\n 'Levar a pessoa até a conta recém-criada (default: true). Deixe true no caso normal — '\n + 'quem acabou de lançar uma conta quer vê-la. Mande FALSE quando levar embora atrapalharia: '\n + 'ela está lançando VÁRIAS contas em sequência, está no meio de outra tarefa (uma tela de '\n + 'cadastro, uma conciliação) e só passou a conta de lado, ou pediu explicitamente para ficar '\n + 'onde está. Com false a conta é criada do mesmo jeito e o link volta na resposta.',\n },\n },\n // `amount` deixa de ser obrigatório SÓ porque o passo 0 pode tê-lo lido: sem\n // leitura guardada a ferramenta recusa do mesmo jeito, com a mesma mensagem.\n required: [],\n },\n}\n\nconst REGISTER_PAYMENT: PluginAITool = {\n id: 'financial.register-payable-payment',\n name: 'registerPayablePayment',\n description:\n 'Step 3 of the payable checklist: registers that a bill WAS PAID — the money leaving, with its method '\n + 'and date. Call it with the `invoiceId` a previous `createPayable` returned, and the `method` the person '\n + 'chose (send the option id when they tapped one). Opens an editable confirmation before writing. '\n + 'Use it whenever a bill already recorded turns out to be settled; never to create the bill itself.',\n icon: 'BadgeDollarSign',\n mode: 'persist',\n execution: { plane: 'client' },\n requiresConfirmation: false,\n category: 'Finance',\n role: 'finance',\n permission: { feature: 'financial', action: 'update' },\n parameters: {\n type: 'object',\n properties: {\n invoiceId: { type: 'string', description: 'Id da conta a pagar, devolvido por createPayable.' },\n method: {\n type: 'string',\n description:\n 'A forma de pagamento — o id da opção que a pessoa tocou, ou o nome dela (\"Pix\", \"Dinheiro\").',\n },\n paymentDate: { type: 'string', description: 'A data do pagamento. Omita para hoje.' },\n },\n required: ['invoiceId'],\n },\n}\n\nconst OPEN_FULL_FORM: PluginAITool = {\n id: 'financial.open-payable-form',\n name: 'openPayableForm',\n description:\n 'Opens the full \"new payable\" screen, empty or pre-filled, for a bill that needs more than a '\n + 'one-line entry: several installments, a receipt to attach, a ledger account or cost centre. '\n + 'Writes nothing. Prefer `createPayable` for an ordinary single bill — this one is the long form.',\n icon: 'FilePlus',\n mode: 'read',\n execution: { plane: 'client' },\n category: 'Finance',\n role: 'finance',\n permission: { feature: 'financial', action: 'create' },\n parameters: { type: 'object', properties: {} },\n}\n\nexport interface PayableAgentDeps {\n config: ResolvedFinancialConfig\n provider: FinancialDataProvider\n}\n\n/**\n * O link do fornecedor, só quando existe tela para ele.\n *\n * Uma ficha de fornecedor não é garantida: o app registra (ou não) uma rota\n * para `person:supplier`. Sem essa checagem o resolvedor cai no palpite pelo\n * plural — `#/suppliers/<id>` — e o botão \"abrir\" leva a uma tela que aquele\n * app não tem. Link que não abre é pior que nenhum link: promete e falha.\n */\nfunction supplierRef(id: string, label: string): { ref: { id: string; label: string; archetype: string } } | Record<string, never> {\n if (!resolveEntityRoute('person', 'supplier')) return {}\n return { ref: { id, label, archetype: 'person:supplier' } }\n}\n\n/**\n * O fornecedor, em passo próprio: procurar, e só então perguntar.\n *\n * Um fornecedor é uma linha de `people` com `kind = 'supplier'` — a mesma que o\n * seletor do formulário procura. Procurar antes de criar é o que impede um\n * \"Printi\" novo a cada nota da Printi, com o extrato do fornecedor deixando de\n * somar.\n *\n * E cadastrar uma PESSOA é uma decisão própria, com cartão próprio: era a\n * correção do founder. Um único cartão \"nova conta a pagar\" que também criava\n * silenciosamente um fornecedor escondia metade do que ia acontecer — quem\n * assina tem de ver as duas coisas que vai assinar.\n *\n * O app pode ter entregue o seu próprio `contactLookup` (o formulário usa\n * esse); quando não entregou, o arquétipo de pessoa responde igual.\n */\nasync function resolveSupplier(\n lookup: EntityLookup,\n name: string,\n): Promise<\n | { ok: true; id?: string; name: string; created: boolean }\n | { ok: false; cancelled: true }\n> {\n const wanted = name.trim().toLowerCase()\n const hits = await lookup.search(name).catch(() => [])\n const exact = hits.find((r) => r.label.trim().toLowerCase() === wanted)\n if (exact) return { ok: true, id: exact.id, name: exact.label, created: false }\n\n // Sem porta de criação (um lookup só de leitura) a conta ainda pode nascer\n // com o nome digitado — é o que o formulário longo faz com `pendingContact`.\n if (!lookup.create) return { ok: true, name, created: false }\n\n const decision = await useChatStore.getState().requestConfirmation({\n id: `supplier-${Date.now()}`,\n toolName: 'createPayable',\n title: 'Novo fornecedor',\n params: { name },\n plane: 'client',\n scope: 'financial:supplier',\n scopeLabel: 'Cadastrar fornecedor',\n fields: [\n { key: 'name', label: 'Nome', type: 'text', required: true },\n { key: 'document_number', label: 'CNPJ / CPF', type: 'text' },\n { key: 'phone', label: 'Telefone', type: 'text' },\n { key: 'email', label: 'E-mail', type: 'text' },\n ],\n })\n if (!decision.approved) return { ok: false, cancelled: true }\n\n const draft = { ...{ name }, ...(decision.values ?? {}) } as Record<string, unknown>\n const finalName = text(draft.name) ?? name\n const made = await lookup.create({\n ...draft,\n name: finalName,\n } as never)\n return { ok: true, id: made.id, name: made.label, created: true }\n}\n\n/**\n * As formas de pagamento QUE ESTE NEGÓCIO aceita.\n *\n * Perguntar \"foi pago como?\" em texto livre devolve \"pix\" escrito de seis\n * jeitos e nenhum deles é um id. A lista sai do registro do próprio locatário,\n * então a pergunta oferece o que existe aqui — e a resposta já vem como o id\n * que a baixa precisa.\n */\ninterface PaymentOption {\n id: string\n label: string\n /** O código que a RPC valida: cash, pix, credit_card… */\n transactionType?: string\n /** As contas que ESTE método aceita, quando o catálogo restringe. */\n allowedAccountTypes?: BankAccountType[]\n}\n\nasync function paymentOptions(provider: FinancialDataProvider): Promise<PaymentOption[]> {\n const types = await provider.getPaymentMethodTypes().catch(() => [])\n return types.filter((t) => t.isActive !== false).map((t) => ({\n id: t.id,\n label: t.name,\n transactionType: t.transactionType,\n allowedAccountTypes: t.allowedAccountTypes,\n }))\n}\n\n/**\n * As contas em que ESTE método pode liquidar.\n *\n * Mesma regra da PaymentModal, e não uma regra nova: `financial_receive_payment`\n * valida a combinação, então oferecer o Santander para um cartão de crédito é\n * oferecer o que o banco vai recusar. Cartão liquida em conta de recebível\n * porque no dia da venda o dinheiro ainda está com a adquirente.\n */\nconst ACCOUNT_TYPES_FOR_TX: Record<string, BankAccountType[]> = {\n cash: ['cash_physical', 'cash_session'],\n credit_card: ['card_receivable_credit'],\n debit_card: ['card_receivable_debit'],\n pix: ['bank'],\n bank_transfer: ['bank'],\n boleto: ['bank'],\n check: ['bank'],\n voucher: ['bank'],\n}\n\nasync function eligibleAccounts(\n provider: FinancialDataProvider,\n method: PaymentOption,\n): Promise<BankAccount[]> {\n const accounts = (await provider.getBankAccounts().catch(() => [])).filter((a) => a.isActive !== false)\n const allowed = method.allowedAccountTypes?.length\n ? method.allowedAccountTypes\n : ACCOUNT_TYPES_FOR_TX[method.transactionType ?? '']\n // Nada declarado = nada a estreitar. Vazio DECLARADO continua vazio: cair de\n // volta para todas as contas é o que faz a tela oferecer o que a RPC recusa.\n if (!allowed) return accounts\n return accounts.filter((a) => allowed.includes(a.accountType))\n}\n\n/** A opção que o nome (ou o id) da pessoa aponta. Null quando não dá para saber. */\nfunction matchPaymentOption(\n options: PaymentOption[],\n raw: unknown,\n): PaymentOption | null {\n const wanted = typeof raw === 'string' ? raw.trim().toLowerCase() : ''\n if (!wanted) return null\n return (\n options.find((o) => o.id.toLowerCase() === wanted)\n ?? options.find((o) => o.label.toLowerCase() === wanted)\n ?? options.find((o) => o.label.toLowerCase().includes(wanted) || wanted.includes(o.label.toLowerCase()))\n ?? null\n )\n}\n\n/**\n * PASSO 3 — o dinheiro que saiu.\n *\n * Pela MESMA porta que o botão \"pagar\" usa (`payMovement`), não por um atalho\n * paralelo: o extrato, os saldos e os KPIs veem exatamente o evento que veriam\n * se alguém tivesse clicado.\n *\n * A consulta LEVA `invoiceId`, e isso não é um filtro a mais — é o que escolhe\n * a fonte. Uma conta em aberto é uma PARCELA\n * (`plg_financial_invoice_installments`, lida por\n * `v_financial_installment_balances`); `plg_financial_movements` só recebe linha\n * quando alguém paga. Sem `invoiceId` o provider vai ao espelho de movimentos e\n * uma conta recém-lançada não está lá — a primeira versão disto procurava a\n * parcela entre os movimentos e teria respondido \"essa conta não tem parcela em\n * aberto\" para toda conta que acabara de nascer. `payMovement` também espera o\n * id da PARCELA, que é o `id` que este ramo devolve.\n */\nasync function settlePayable(\n provider: FinancialDataProvider,\n input: { invoiceId: string; method: PaymentOption; paymentDate?: string; currency?: string },\n): Promise<Record<string, unknown>> {\n const schedule = await provider.getMovements({\n invoiceId: input.invoiceId,\n direction: 'debit',\n status: 'pending',\n })\n const bill = schedule.data.find((m) => m.movementKind === 'bill')\n if (!bill) {\n return {\n ok: false,\n error: 'no_open_bill',\n message: 'That bill has no open installment — it may already be settled. Say so and stop.',\n }\n }\n\n // QUAL conta está sendo paga, em palavras. Um cartão que diz só \"Pix, hoje,\n // R$ 141,68\" pede para quitar às cegas, e a conta errada quitada é o tipo de\n // erro que só a conciliação encontra, semanas depois.\n const invoice = await provider.getInvoiceById(input.invoiceId).catch(() => null)\n const money = (n: number) => formatCurrency(n, input.currency ?? 'BRL')\n // `fiscalNumber` é onde `rowToInvoice` guarda o número da fatura (\"PAG-000001\").\n const invoiceLabel = [\n invoice?.fiscalNumber ? `#${invoice.fiscalNumber}` : null,\n invoice?.contactName ?? null,\n money(bill.amount),\n ].filter(Boolean).join(' — ') || money(bill.amount)\n\n // DE ONDE O DINHEIRO SAIU. `financial_receive_payment` recusa um pix sem\n // conta (\"an account is required for method pix\", 22023): a baixa é um evento\n // de duas pernas e a conta é a outra perna. Faltava, e o cartão só falhava na\n // confirmação.\n // DINHEIRO É A EXCEÇÃO. Para `cash` a RPC resolve a conta pela SESSÃO de\n // caixa aberta (`plg_financial_open_session_of`) e ignora `p_account_id` — um\n // seletor aqui pediria uma escolha que não é usada. Sem caixa aberto ela\n // recusa com a sua própria mensagem, que é a certa (\"abra o caixa primeiro\").\n const needsAccount = input.method.transactionType !== 'cash'\n const accounts = needsAccount ? await eligibleAccounts(provider, input.method) : []\n if (needsAccount && !accounts.length) {\n return {\n ok: false,\n error: 'no_eligible_account',\n message:\n `The bill is recorded but NOT settled: this business has no account that can settle a `\n + `${input.method.label} payment. Say that, and that it has to be registered from the payables screen.`,\n }\n }\n // Uma conta só não é uma escolha: é a resposta. Perguntar seria pedir um\n // toque para confirmar o óbvio.\n const onlyAccount = accounts.length === 1 ? accounts[0] : undefined\n\n const paymentDate = parseReceiptDate(input.paymentDate) ?? today()\n const decision = await useChatStore.getState().requestConfirmation({\n id: `payment-${bill.id}`,\n toolName: 'registerPayablePayment',\n title: 'Registrar pagamento',\n params: {\n invoice: invoiceLabel,\n method: input.method.label,\n accountId: onlyAccount?.id,\n paymentDate,\n amount: bill.amount,\n },\n plane: 'client',\n scope: 'financial:payment',\n scopeLabel: 'Registrar pagamento',\n fields: [\n // Qual conta está sendo quitada, por extenso e primeiro. Só de leitura:\n // é a identidade do que se assina, não um campo a editar.\n { key: 'invoice', label: 'Conta a pagar', type: 'text', readOnly: true },\n { key: 'method', label: 'Forma de pagamento', type: 'text', required: true, readOnly: true },\n ...(needsAccount\n ? [{\n key: 'accountId',\n label: 'Conta de saída',\n type: 'select',\n required: true,\n options: accounts.map((a) => ({ value: a.id, label: a.name })),\n }]\n : []),\n { key: 'paymentDate', label: 'Data do pagamento', type: 'date', required: true },\n { key: 'amount', label: 'Valor pago', type: 'number', required: true, min: 0 },\n ],\n })\n if (!decision.approved) {\n return {\n ok: false,\n cancelled: true,\n reason: 'user_declined',\n message: 'The bill is recorded but NOT settled — the payment step was declined. Say exactly that.',\n }\n }\n\n const values = { paymentDate, amount: bill.amount, accountId: onlyAccount?.id, ...(decision.values ?? {}) }\n const accountId = typeof values.accountId === 'string' && values.accountId ? values.accountId : undefined\n if (needsAccount && !accountId) {\n return {\n ok: false,\n error: 'no_account',\n message: 'NOTHING WAS SETTLED. The form came back with no outgoing account — do not say it was paid.',\n }\n }\n await provider.payMovement({\n movementId: bill.id,\n amount: parseReceiptAmount(values.amount) ?? bill.amount,\n paymentDate: parseReceiptDate(values.paymentDate) ?? paymentDate,\n paymentMethodTypeId: input.method.id,\n bankAccountId: accountId,\n })\n return {\n ok: true,\n settled: true,\n invoiceId: input.invoiceId,\n movementId: bill.id,\n method: input.method.label,\n account: accounts.find((a) => a.id === accountId)?.name,\n paymentDate: parseReceiptDate(values.paymentDate) ?? paymentDate,\n // O botão que abre a conta quitada. `path` existe para exatamente isto —\n // uma tela de plugin que o mapa de rotas por arquétipo não sabe resolver.\n ref: {\n id: input.invoiceId,\n label: invoiceLabel,\n path: `/financial/payables/${input.invoiceId}`,\n },\n message:\n `Pago via ${input.method.label}. Diga em UMA frase que a conta foi lançada e quitada, e pare.`,\n }\n}\n\n/**\n * As contas que ESTA conversa acabou de lançar.\n *\n * \"marca como pago no pix hoje\" chegou logo depois de uma conta lançada e o\n * modelo chamou `createPayable` de novo — abriu um SEGUNDO cartão de nova conta\n * em vez de dar baixa na primeira. Uma conta a pagar duplicada não é um\n * incômodo de conversa: é dinheiro contado duas vezes.\n *\n * Então a ferramenta lembra o que escreveu e recusa o repetido, apontando para\n * a baixa. Memória de módulo e por conversa curta — a chave é fornecedor+valor,\n * que é o que uma pessoa repete quando quer dizer \"aquela conta\".\n */\ninterface RecentPayable { invoiceId: string; supplier: string; amount: number; at: number }\nlet recentPayables: RecentPayable[] = []\n/** Dez minutos: tempo de uma conversa, não da tarde inteira. */\nconst RECENT_WINDOW_MS = 10 * 60 * 1000\n\nfunction rememberPayable(entry: RecentPayable): void {\n recentPayables = [...recentPayables.filter((p) => p.invoiceId !== entry.invoiceId), entry].slice(-10)\n}\n\nfunction findRecentPayable(supplier: string, amount: number): RecentPayable | undefined {\n const now = Date.now()\n recentPayables = recentPayables.filter((p) => now - p.at < RECENT_WINDOW_MS)\n const wanted = supplier.trim().toLowerCase()\n return recentPayables.find(\n (p) => p.supplier.trim().toLowerCase() === wanted && Math.abs(p.amount - amount) < 0.005,\n )\n}\n\n/** Exposto para os testes — uma conversa nova não herda a memória da anterior. */\nexport function clearRecentPayables(): void {\n recentPayables = []\n}\n\n// ---------------------------------------------------------------------------\n// UMA PERGUNTA COM BOTÕES, NÃO UM PARÁGRAFO\n//\n// \"Você confirma que deseja criar o fornecedor 'CAMISA DIMONA E MALHAS LTDA'?\"\n// chegava como texto: quem lê tem de digitar \"sim\" — e digitar de volta um nome\n// que a tela acabou de mostrar é exatamente o trabalho que o assistente existe\n// para poupar. Pior, um \"sim\" é ambíguo quando havia três candidatos.\n//\n// O chat já sabe desenhar isso: um resultado de ferramenta com\n// `kind: 'record_choice'` vira linhas tocáveis (ver lib/choice-cards e\n// ChoiceCard), e o toque responde como se a pessoa tivesse escrito a opção.\n// Faltava as respostas do passo 0 saírem nesse formato — a pergunta da forma de\n// pagamento já saía, e é por isso que aquela aparecia como botões.\n//\n// Quem monta a pergunta é a FERRAMENTA, não o modelo: o cartão só nasce se o\n// payload vier certo, e pedir ao gpt-4o-mini que emita JSON estrutural no meio\n// de uma resposta em prosa é apostar a interface num acerto de formatação.\n// ---------------------------------------------------------------------------\n\ninterface ChoiceOption { id: string; label: string; meta?: string }\ninterface ChoiceQuestion { id: string; question: string; options: ChoiceOption[] }\n\n/** Menos de duas opções não é escolha — o chat descarta, e com razão. */\nfunction asChoiceCards(choices: ChoiceQuestion[]): Record<string, unknown> {\n const usable = choices.filter((c) => c.options.length >= 2)\n return usable.length ? { kind: 'record_choice', choices: usable } : {}\n}\n\n/** As perguntas que cada buraco do passo 0 levanta, com os botões que as fecham. */\nfunction gapChoices(input: {\n supplierName?: string\n supplier: { status: string; candidates?: Array<{ id: string; name: string; why: string }> }\n method: Record<string, unknown>\n account: Record<string, unknown>\n}): ChoiceQuestion[] {\n const questions: ChoiceQuestion[] = []\n const { supplierName, supplier, method, account } = input\n\n if (supplier.status !== 'found' && supplierName) {\n const candidates = supplier.candidates ?? []\n questions.push({\n id: 'supplier',\n question: candidates.length\n ? `\"${supplierName}\" não está cadastrado. É algum destes?`\n : `\"${supplierName}\" ainda não está cadastrado. Cadastrar agora?`,\n options: [\n // Os parecidos PRIMEIRO: a razão de eles existirem é evitar o\n // duplicado, então a opção de criar não pode ser a mais fácil de tocar.\n ...candidates.slice(0, 4).map((c) => ({\n id: `supplier:${c.id}`,\n label: c.name,\n meta: c.why,\n })),\n { id: 'supplier:create', label: `Criar fornecedor \"${supplierName}\"` },\n { id: 'supplier:cancel', label: 'Cancelar' },\n ],\n })\n }\n\n if (method.status !== 'found') {\n const available = (method.available as Array<{ id: string; label: string }> | undefined) ?? []\n questions.push({\n id: 'method',\n question: method.spoken\n ? `O papel diz \"${String(method.spoken)}\", que não está cadastrado. Qual forma corresponde?`\n : 'Como esta conta foi (ou vai ser) paga?',\n options: [\n ...available.slice(0, 5).map((o) => ({ id: `method:${o.id}`, label: o.label })),\n { id: 'method:none', label: 'Deixar em aberto' },\n ],\n })\n }\n\n if (account.status === 'ambiguous') {\n const options = (account.options as Array<{ id: string; name: string }> | undefined) ?? []\n questions.push({\n id: 'account',\n question: account.cardLast4\n ? `Nenhuma conta cadastrada tem o final ${String(account.cardLast4)}. De qual conta saiu?`\n : 'De qual conta o dinheiro saiu?',\n options: [\n ...options.slice(0, 5).map((o) => ({ id: `account:${o.id}`, label: o.name })),\n { id: 'account:skip', label: 'Decidir na hora de pagar' },\n ],\n })\n }\n\n return questions\n}\n\n/** A pergunta \"foi pago como?\", no formato que vira cartão de opções. */\nfunction askHowItWasPaid(\n invoiceId: string,\n options: Array<{ id: string; label: string }>,\n): Record<string, unknown> {\n return {\n kind: 'record_choice',\n choices: [{\n id: `payment-method-${invoiceId}`,\n question: 'Foi pago como?',\n options,\n }],\n invoiceId,\n nextStep: 'registerPayablePayment',\n message:\n 'The bill is recorded but NOT yet settled. The person is being asked HOW it was paid — the options are '\n + 'on screen. Do not list them again in prose and do not guess one. When they answer, call '\n + `registerPayablePayment with invoiceId \"${invoiceId}\" and the option id they chose.`,\n }\n}\n\nexport function createPayableTools({ config, provider }: PayableAgentDeps): AgentSurfaceTool[] {\n const lookup: EntityLookup =\n config.contactLookup ?? createArchetypeLookup({\n archetype: 'person',\n kind: 'supplier',\n createKinds: ['supplier', 'staff', 'customer'],\n kindLabels: { supplier: 'Fornecedor', customer: 'Cliente', staff: 'Funcionário' },\n })\n\n return [\n {\n tool: RESOLVE_CONTEXT,\n execute: async (args) => {\n // UM RASCUNHO VELHO NÃO PODE SEMEAR UMA LEITURA NOVA.\n //\n // `openPayableDraft` guarda o rascunho numa variável de módulo até o\n // formulário montar e consumi-lo. Um rascunho que ficou pendurado — de\n // uma leitura anterior, possivelmente errada — semearia o PRÓXIMO\n // cadastro aberto, e a pessoa veria de novo o valor que já tinha\n // rejeitado. Ler um documento novo descarta o anterior.\n consumePayableDraft()\n\n const supplierName = text(args.supplier)\n const supplier = supplierName\n ? await findSupplier(lookup, supplierName, args.supplierDocument)\n : { status: 'missing' as const, candidates: [] as SupplierCandidate[] }\n const method = await findMethod(provider, args)\n const account = await findAccount(provider, method, args.cardLast4)\n\n // O que ainda falta, na ORDEM em que tem de ser resolvido: o fornecedor\n // é dono da conta, o método decide a conta de saída, e a baixa depende\n // dos dois. Resolver fora de ordem é escrever a fatura e descobrir na\n // baixa que o método não existe — metade do trabalho no banco.\n const gaps = [\n supplier.status !== 'found' ? 'supplier' : null,\n method.status !== 'found' ? 'method' : null,\n account.status === 'ambiguous' || account.status === 'missing' ? 'account' : null,\n ].filter(Boolean)\n\n // Cada buraco vira uma PERGUNTA COM BOTÕES, montada aqui — ver\n // gapChoices. O modelo narra o checklist; quem desenha a escolha é a\n // ferramenta.\n const choices = gapChoices({ supplierName, supplier, method, account })\n\n // Lido, normalizado e GUARDADO. O passo seguinte consome isto.\n const document = normalizeDocument(args)\n // Guardado com a origem: sobrevive a um reload (sessionStorage) e a\n // mensagem seguinte pode dizer de qual documento está falando.\n rememberDocument(document, {\n ...(text(args.supplier) ? { source: text(args.supplier)! } : {}),\n ...(useChatStore.getState().conversationId\n ? { conversationId: useChatStore.getState().conversationId! }\n : {}),\n })\n\n return {\n ok: true,\n read: {\n supplier: supplierName,\n supplierDocument: onlyDigits(args.supplierDocument) || undefined,\n paymentMethod: text(args.paymentMethod),\n cardBrand: text(args.cardBrand),\n cardLast4: lastFour(args.cardLast4) || undefined,\n },\n supplier,\n method,\n account,\n gaps,\n document,\n ...asChoiceCards(choices),\n message:\n 'NOTHING WAS WRITTEN — this was a check. Tell the person the result as ONE short line per '\n + 'dependency, saying which already exist and which are missing (e.g. \"Fornecedor Printi: ja existe '\n + '- Pix: cadastrado - cartao final 4242: nao encontrei\"). '\n + 'FIRST say what you READ, in one line, from `document`: how many items, the total, the method, '\n + 'the order ref, and the dates — and when `document.dueDate` is null say plainly there is no due '\n + 'date on the paper (à vista) and that the form will ask. If `document.reconciles` is false and '\n + 'there are items and a total, say the numbers do not add up and ask, instead of choosing one. '\n + 'The extraction is SAVED: when you call createPayable next, you may omit items/shipping/total/'\n + 'dates entirely — it reuses exactly what was read here. Do NOT re-read the document to fill them '\n + 'in again; re-reading from memory is where wrong numbers come from. '\n + (choices.length\n ? 'The open questions are ALREADY ON SCREEN as tappable buttons — do NOT repeat the options in '\n + 'prose and do NOT ask the person to type an answer. End your reply after the checklist and '\n + 'WAIT for the tap. When they answer, the option id says what to do: `supplier:create` means '\n + 'create the supplier under the name in `read.supplier` (call createPayable and its supplier '\n + 'step will confirm it), `supplier:<uuid>` means use that existing one, `method:<id>` is the '\n + 'payment method, `account:<id>` the outgoing account, and anything `:cancel` means stop. '\n : 'Then continue with createPayable for the bill, and the payment. ')\n + 'Never invent a value the paper did not state.',\n }\n },\n },\n {\n tool: OPEN_FULL_FORM,\n execute: async () => {\n adminNavigateTo('/financial/payables/new')\n return { ok: true, opened: '/financial/payables/new' }\n },\n },\n {\n tool: CREATE_PAYABLE,\n execute: async (args) => {\n // O RASCUNHO NA TELA GANHA. Com o cadastro aberto, escrever aqui criaria\n // uma segunda conta para a mesma despesa e deixaria a pessoa parada num\n // formulário órfão — que foi exatamente o que aconteceu.\n if (hasLivePayableDraft()) {\n return {\n ok: false,\n error: 'draft_open',\n message:\n 'NOTHING WAS WRITTEN, and no second bill was created. The payable form is OPEN ON SCREEN with '\n + 'the draft this conversation has been building — that draft IS this bill. Continue in it: use '\n + '`fillPayableDraft` for what is missing and `submitPayableDraft` to save. Do not call '\n + 'createPayable again while that form is open.',\n }\n }\n\n // Um NÚMERO não é confiável aqui, por mais que pareça um: 5000 é\n // exatamente o que \"50,00\" vira quando alguém trata a vírgula como\n // separador de milhar. Erro corrigível, não recusa — o modelo relê e\n // reenvia o literal, custa uma rodada e vale um lançamento certo.\n // O que o passo 0 leu vale mais que uma releitura: ele teve o documento\n // na frente, esta chamada tem só a lembrança dele. O que o modelo mandar\n // EXPLICITAMENTE agora sobrepõe — aí é correção, não memória.\n const remembered = rememberedDocument()\n if (args.amount === undefined && remembered?.total !== undefined) {\n args = { ...args, amount: String(remembered.total) }\n }\n if (typeof args.amount !== 'string') {\n return {\n ok: false,\n error: 'amount_must_be_literal',\n message:\n 'Send `amount` as the TEXT that was written, punctuation included (\"50,00\", \"1.234,56\") — '\n + 'never as a number. A decimal comma is a thousands separator in English, so converting it '\n + 'yourself turns fifty into five thousand. Resend the literal.',\n }\n }\n const figures = parseReceiptAmount(args.amount)\n // O extenso prevalece: é para isso que recibo e cheque o escrevem.\n const spelled = parseAmountInWords(args.amountInWords)\n const amount = spelled ?? figures\n if (amount === null) {\n return {\n ok: false,\n error: 'invalid_amount',\n message: 'That is not a readable amount. If the total is illegible or was never said, ask the person.',\n }\n }\n\n // AS LINHAS DA NOTA, e a conferência entre elas e o total.\n //\n // Escrever uma linha só de \"serviço prestado\" com o total dentro perde\n // o pedido inteiro: três camisetas viram uma despesa anônima, e quem\n // for conferir daqui a um mês não tem o que conferir. E somar as linhas\n // é a única forma de saber se a leitura do papel bateu — por isso a\n // divergência VOLTA para ser perguntada, em vez de ser resolvida aqui\n // por um palpite de qual dos dois números está certo.\n const lines = args.items === undefined && remembered?.items.length\n ? { items: remembered.items, error: undefined }\n : parseLineItems(args.items)\n if (lines.error) return { ok: false, error: 'invalid_items', message: lines.error }\n // O FRETE entra na soma venha de onde vier. Passado agora vale; não\n // passado, vale o que o passo 0 leu. Esquecer o guardado foi o que fez\n // 1.437 ser comparado com 1.489 e a conta ser recusada por 52,19 que\n // estavam escritos no papel o tempo todo.\n const shipping = args.shipping === undefined\n ? (remembered?.shipping ?? null)\n : parseReceiptAmount(args.shipping)\n const lineSum = round2(lines.items.reduce((s, i) => s + i.quantity * i.unitPrice, 0))\n const computed = round2(lineSum + (shipping ?? 0))\n\n // O TOTAL TEM DOIS CANDIDATOS, e o que fecha com as linhas ganha.\n //\n // O modelo relê o documento para preencher a conta e volta com\n // \"R$ 1.489\" — sem os centavos. Isso não é um parser errado: é uma\n // leitura de memória, e a memória de um número longo perde o fim. O\n // passo 0 teve o papel na frente e guardou 1.489,19. Quando a soma das\n // linhas mais o frete bate com o guardado e não com o que veio agora,\n // quem está certo é o guardado — e recusar a conta por 19 centavos que\n // o próprio documento traz seria transformar a conferência em obstáculo.\n const candidates: Array<{ value: number; from: 'argumento' | 'leitura' }> = [\n { value: amount, from: 'argumento' },\n ...(remembered?.total !== undefined ? [{ value: remembered.total, from: 'leitura' as const }] : []),\n ]\n const agreed = lines.items.length\n ? candidates.find((c) => Math.abs(computed - c.value) <= 0.02)\n : candidates[0]\n if (lines.items.length && !agreed) {\n return {\n ok: false,\n error: 'total_mismatch',\n lineSum,\n shipping: shipping ?? undefined,\n computed,\n total: amount,\n ...(remembered?.total !== undefined ? { totalFromDocument: remembered.total } : {}),\n message:\n `NOTHING WAS WRITTEN. The lines do not add up to the total: the item(s) sum to ${lineSum}`\n + `${shipping ? ` plus ${shipping} of shipping` : ''} = ${computed}, but the total given is `\n + `${amount}. Do NOT pick one of them and do not adjust a line to make it fit. Re-read the `\n + `document — a line may have been missed, a quantity misread, or a discount or shipping line `\n + `not captured. If the paper genuinely disagrees with itself, ask the person which is right.`,\n }\n }\n // O valor que vai ser escrito: o que fechou. Sem linhas, o que veio.\n const reconciledTotal = agreed?.value ?? amount\n const correctedFromRead = agreed?.from === 'leitura' && Math.abs(agreed.value - amount) > 0.005\n\n // Datas e referências saem da MESMA leitura. `dueDate: null` guardado\n // é uma resposta (\"o papel não diz\"), não uma lacuna — então não se\n // procura de novo: o cartão pergunta.\n const dueDate = parseReceiptDate(args.dueDate) ?? remembered?.dueDate ?? undefined\n const issueDate = parseReceiptDate(args.date)\n ?? remembered?.documentDate\n ?? parseReceiptDate(findDateIn(args.notes))\n\n // O cartão É o formulário. O que a fonte não respondeu chega em branco e\n // marcado como obrigatório — o botão de confirmar fica desligado até a\n // pessoa preencher. Campo vazio custa um toque; campo chutado custa uma\n // conferência inteira, e um vencimento inventado custa uma cobrança.\n const params: Record<string, unknown> = { amount }\n const supplierName = text(args.supplier)\n if (supplierName) params.supplier = supplierName\n const description = text(args.description)\n if (description) params.description = description\n if (dueDate) params.dueDate = dueDate\n if (issueDate) params.issueDate = issueDate\n // O pedido e a entrega vêm da leitura quando o modelo não os repetiu —\n // é onde a pessoa vai procurar o que o papel dizia.\n const carried = [\n remembered?.orderRef ? `Pedido: ${remembered.orderRef}` : null,\n remembered?.deliveryDate ? `Entrega: ${remembered.deliveryDate}` : null,\n ].filter(Boolean).join(' · ')\n const notes = text(args.notes) ?? (carried || undefined)\n if (notes) params.notes = notes\n if (lines.items.length) {\n params.items = lines.items\n .map((i) => `${i.quantity}× ${i.description} @ ${i.unitPrice}`)\n .join(' · ')\n params.amount = computed\n }\n if (shipping) params.shipping = shipping\n\n // Já lançada nesta conversa? Então o pedido é a BAIXA, não uma segunda\n // conta. Recusar aqui é mais barato que descobrir a duplicata na\n // conciliação — ver findRecentPayable.\n if (supplierName) {\n const already = findRecentPayable(supplierName, amount)\n if (already) {\n return {\n ok: false,\n error: 'already_recorded',\n invoiceId: already.invoiceId,\n message:\n `NOTHING WAS WRITTEN and no second bill was created. The bill for ${supplierName} of `\n + `${amount} was ALREADY recorded in this conversation — its invoiceId is \"${already.invoiceId}\". `\n + 'If the person is saying it was PAID (\"marca como pago\", \"paguei no Pix\"), call '\n + `registerPayablePayment with invoiceId \"${already.invoiceId}\". Only call createPayable again `\n + 'if this is genuinely a DIFFERENT bill, with a different amount or supplier.',\n }\n }\n }\n\n // PASSO 1 — o fornecedor, antes da conta.\n //\n // A ordem não é cerimônia: uma conta a pagar APONTA para uma pessoa, e\n // criar as duas num cartão só escondia metade do que ia acontecer. Sem\n // nome nenhum não há passo 1 — o cartão da conta pede o nome e este\n // passo acontece depois, na volta.\n let supplier: { id?: string; name: string; created: boolean } | null = null\n if (supplierName) {\n const step = await resolveSupplier(lookup, supplierName)\n if (!step.ok) {\n return {\n ok: false,\n cancelled: true,\n reason: 'user_declined_supplier',\n message:\n 'NOTHING WAS WRITTEN. The person declined creating the supplier, so the bill has nobody to '\n + 'point at. Ask which existing supplier it belongs to — do not retry the same name.',\n }\n }\n supplier = { id: step.id, name: step.name, created: step.created }\n params.supplier = step.name\n }\n\n // PASSO 2 — a conta. O cartão É o formulário: o que a fonte não\n // respondeu chega em branco e marcado como obrigatório, e o botão de\n // confirmar fica desligado até a pessoa preencher.\n const decision = await useChatStore.getState().requestConfirmation({\n id: `payable-${Date.now()}`,\n toolName: 'createPayable',\n // Nomeia o que está sendo criado. Era `config.labels.payablesNew`,\n // que é o rótulo da AÇÃO na sub-navegação (\"New\") — no topo de um\n // cartão de confirmação ele dizia só \"New\" e não nomeava nada.\n title: 'Nova conta a pagar',\n params,\n plane: 'client',\n scope: 'financial:payable',\n scopeLabel: 'Lançar conta a pagar',\n fields: [\n { key: 'supplier', label: 'Fornecedor', type: 'text', required: true },\n { key: 'description', label: 'Descrição', type: 'text', required: true },\n // As linhas lidas da tabela, à vista e só de leitura: é o que a\n // pessoa confere para saber se a leitura do papel bateu.\n ...(lines.items.length ? [{ key: 'items', label: 'Itens', type: 'text', readOnly: true }] : []),\n ...(shipping ? [{ key: 'shipping', label: 'Frete', type: 'number', readOnly: true }] : []),\n // Com tabela lida, o valor É a soma conferida — editá-lo aqui o\n // separaria das linhas, e o banco recusa uma fatura cujas parcelas\n // não fecham com os itens. Sem tabela, ele continua editável.\n {\n key: 'amount',\n label: 'Valor total',\n type: 'number',\n required: true,\n min: 0,\n ...(lines.items.length ? { readOnly: true } : {}),\n },\n { key: 'dueDate', label: 'Vencimento', type: 'date', required: true },\n { key: 'issueDate', label: 'Data do documento', type: 'date', default: today() },\n { key: 'notes', label: 'Observações', type: 'text' },\n ],\n })\n if (!decision.approved) return { ok: false, cancelled: true, reason: 'user_declined' }\n\n const values = { ...params, ...(decision.values ?? {}) }\n // Com tabela, o total é a soma conferida — nunca o que voltou do\n // campo, que nem é editável nesse caso.\n const finalAmount = lines.items.length ? computed : (parseReceiptAmount(values.amount) ?? amount)\n const finalSupplier = text(values.supplier)\n const finalDescription = text(values.description) ?? finalSupplier ?? ''\n const finalDue = parseReceiptDate(values.dueDate)\n const finalIssue = parseReceiptDate(values.issueDate) ?? today()\n\n if (!finalSupplier || !finalDue) {\n return {\n ok: false,\n error: 'incomplete',\n message: 'NOTHING WAS WRITTEN. The form came back without a supplier or a due date — do not tell the user it worked.',\n }\n }\n\n // Reuse step 1's resolution when the form kept the same name; changing\n // the name in the form is a NEW supplier decision, so step 1 runs again\n // rather than filing the bill under the person nobody chose.\n let resolvedSupplier = supplier\n if (!resolvedSupplier || resolvedSupplier.name !== finalSupplier) {\n const again = await resolveSupplier(lookup, finalSupplier)\n if (!again.ok) {\n return {\n ok: false,\n cancelled: true,\n reason: 'user_declined_supplier',\n message: 'NOTHING WAS WRITTEN. The supplier step was declined — ask which supplier this bill belongs to.',\n }\n }\n resolvedSupplier = { id: again.id, name: again.name, created: again.created }\n }\n // Uma linha e uma parcela: o caminho curto da mesma escrita que o\n // formulário faz. Parcelamento, rateio e comprovante são a razão de o\n // formulário longo existir — ver openPayableForm.\n const invoice = await provider.createInvoice({\n direction: 'debit',\n invoiceDate: finalIssue,\n contactId: resolvedSupplier.id,\n contactName: resolvedSupplier.name,\n observations: text(values.notes),\n // A nota que o papel descreve, linha por linha. Sem tabela, a conta\n // nasce com uma linha só — que é o que um recibo de táxi é. O FRETE é\n // linha PRÓPRIA: somado ao preço de um produto ele sumiria dentro\n // dele, e a conciliação com a transportadora não teria onde olhar.\n items: [\n ...(lines.items.length\n ? lines.items.map((line) => ({\n itemKind: 'other' as const,\n description: line.description,\n quantity: line.quantity,\n unitPrice: line.unitPrice,\n }))\n : [{\n itemKind: 'other' as const,\n description: finalDescription,\n quantity: 1,\n unitPrice: round2(finalAmount - (shipping ?? 0)),\n }]),\n ...(shipping\n ? [{ itemKind: 'other' as const, description: 'Frete', quantity: 1, unitPrice: shipping }]\n : []),\n ],\n installments: [{\n direction: 'debit',\n movementKind: 'bill',\n amount: finalAmount,\n dueDate: finalDue,\n installmentNumber: 1,\n }],\n })\n\n const id = (invoice as { id?: string } | null)?.id\n if (id) {\n rememberPayable({ invoiceId: id, supplier: resolvedSupplier.name, amount: finalAmount, at: Date.now() })\n }\n // Um rascunho de recibo que ficou pendurado de antes não pode sobreviver\n // a esta escrita: ele semearia o PRÓXIMO cadastro aberto com a conta que\n // acabou de ser lançada, e a pessoa lançaria a mesma despesa de novo\n // sem perceber. Consumir é descartar.\n consumePayableDraft()\n const drift =\n spelled !== null && figures !== null && Math.abs(spelled - figures) > 0.005\n ? { note: `Os algarismos pareciam ${figures} e o extenso diz ${spelled}. Usei o extenso.` }\n : {}\n\n // Levar até a conta que acabou de nascer. Default SIM: quem lançou quer\n // ver o que lançou, e \"criei, procure na lista\" é mandar a pessoa fazer\n // o último passo a pé. O modelo desliga quando levar embora atrapalha —\n // várias contas seguidas, ou alguém no meio de outra tarefa.\n const invoicePath = id ? `/financial/payables/${id}` : null\n const redirected = invoicePath !== null && args.redirect !== false\n if (redirected) {\n adminNavigateTo(invoicePath)\n // No celular o formulário abria ATRÁS do painel do assistente — ver\n // o mesmo passo em receipt-agent. Navegar sem revelar é levar a\n // pessoa a uma tela que ela não vê.\n revealPage()\n }\n const invoiceLink = invoicePath\n ? { ref: { id: id!, label: `${resolvedSupplier.name} — ${finalDescription}`, path: invoicePath } }\n : {}\n\n // PASSO 3 — o pagamento, quando o papel diz que já foi pago.\n //\n // Só acontece com a fatura JÁ escrita: a conta existe mesmo que a baixa\n // seja recusada, e um recibo quitado que não virou nada seria o pior\n // dos dois mundos.\n if (args.paid === true && id) {\n const options = await paymentOptions(provider)\n const chosen = matchPaymentOption(options, args.paymentMethod)\n // Sem forma de pagamento, PERGUNTA — não chuta. \"Dinheiro\" no lugar de\n // \"Pix\" não é um detalhe: é a conciliação de um mês que não bate.\n if (!chosen) {\n if (options.length >= 2) {\n return {\n ...askHowItWasPaid(id, options),\n supplier: resolvedSupplier.name,\n supplierCreated: resolvedSupplier.created,\n amount: finalAmount,\n openedInvoice: redirected,\n ...drift,\n }\n }\n // Um negócio com uma forma só (ou nenhuma cadastrada) não tem o que\n // perguntar — a conta fica lançada e em aberto, dito claramente.\n return {\n ok: true,\n invoiceId: id,\n settled: false,\n supplier: resolvedSupplier.name,\n amount: finalAmount,\n dueDate: finalDue,\n openedInvoice: redirected,\n ...invoiceLink,\n message:\n 'A conta foi lançada, mas o pagamento NÃO foi registrado: este negócio não tem formas de '\n + 'pagamento cadastradas para escolher. Diga isso e ofereça registrar a baixa pela tela.',\n ...drift,\n }\n }\n const settled = await settlePayable(provider, {\n invoiceId: id,\n method: chosen,\n paymentDate: typeof args.paymentDate === 'string' ? args.paymentDate : undefined,\n currency: config.currency?.code,\n })\n return {\n ...settled,\n invoiceId: id,\n supplier: resolvedSupplier.name,\n supplierCreated: resolvedSupplier.created,\n amount: finalAmount,\n openedInvoice: redirected,\n ...drift,\n }\n }\n\n return {\n ok: true,\n invoiceId: id,\n settled: false,\n supplier: resolvedSupplier.name,\n supplierCreated: resolvedSupplier.created,\n amount: finalAmount,\n dueDate: finalDue,\n openedInvoice: redirected,\n ...(lines.items.length ? { itemsWritten: lines.items.length } : {}),\n // Dito, nunca silencioso: se o total que veio na chamada perdeu os\n // centavos e o da leitura fechou com as linhas, quem escreveu foi a\n // leitura — e quem confere merece saber disso.\n ...(correctedFromRead\n ? {\n correctedTotal: {\n sent: amount,\n written: reconciledTotal,\n why: 'o total enviado não fechava com as linhas; o lido do documento fechou',\n },\n }\n : {}),\n ...(shipping ? { shipping } : {}),\n // A CONTA é o destino principal — é o que a pessoa acabou de criar.\n ...invoiceLink,\n // O fornecedor vai como segundo botão, e só onde existe tela para ele\n // (ver supplierRef): `extractRecordLinks` lê `ref` e `record.ref`.\n ...(resolvedSupplier.id\n ? { record: supplierRef(resolvedSupplier.id, resolvedSupplier.name) }\n : {}),\n // O que fazer DEPOIS, dito com o id dentro. Sem esta linha, \"marca\n // como pago no pix hoje\" na mensagem seguinte virou uma SEGUNDA conta\n // a pagar: o modelo tinha a ferramenta de baixa e nenhuma frase\n // ligando-a a esta fatura.\n message:\n `A conta a pagar de ${resolvedSupplier.name} foi lançada (invoiceId \"${id}\"), em aberto. `\n + (resolvedSupplier.created ? 'O fornecedor foi cadastrado agora. ' : '')\n + (redirected ? 'A tela da conta JÁ foi aberta — não ofereça abri-la. ' : '')\n + 'Diga isso em UMA frase e pare — não repita os campos, a pessoa acabou de conferi-los. '\n + 'IMPORTANTE: se a pessoa disser depois que esta conta foi paga (\"marca como pago\", \"paguei no '\n + `Pix\", \"foi pago hoje\"), chame registerPayablePayment com invoiceId \"${id}\". NÃO chame `\n + 'createPayable de novo — isso criaria uma segunda conta para a mesma despesa.',\n ...drift,\n }\n },\n },\n {\n tool: REGISTER_PAYMENT,\n execute: async (args) => {\n const invoiceId = typeof args.invoiceId === 'string' ? args.invoiceId : ''\n if (!invoiceId) {\n return {\n ok: false,\n error: 'missing_invoice',\n message: 'Which bill? Pass the `invoiceId` that createPayable returned.',\n }\n }\n const options = await paymentOptions(provider)\n const chosen = matchPaymentOption(options, args.method)\n if (!chosen) {\n if (options.length < 2) {\n return {\n ok: false,\n error: 'no_payment_methods',\n message: 'This business has no payment methods to choose from. Say so instead of guessing one.',\n }\n }\n return askHowItWasPaid(invoiceId, options)\n }\n return settlePayable(provider, {\n invoiceId,\n method: chosen,\n paymentDate: typeof args.paymentDate === 'string' ? args.paymentDate : undefined,\n currency: config.currency?.code,\n })\n },\n },\n ]\n}\n\n// ---------------------------------------------------------------------------\n// O RASCUNHO ABERTO NA TELA\n//\n// Havia duas portas para o mesmo ato e elas não se falavam. O caminho da foto\n// abre o cadastro PREENCHIDO em /financial/payables/new e espera a pessoa\n// conferir; `createPayable` escreve sozinho. Com o rascunho na tela e o\n// fornecedor faltando, o assistente não tinha como mexer NAQUELE rascunho —\n// então chamava `createPayable` e escrevia uma SEGUNDA conta, deixando a pessoa\n// parada num formulário que já não queria dizer nada.\n//\n// A correção não é escolher uma das portas: é fazer a de cima ceder enquanto a\n// de baixo está aberta. Enquanto o formulário está montado, ELE é a conta em\n// curso — a lista de passos opera nos campos dele e o passo final é o MESMO\n// salvar do botão. `createPayable` se recusa e aponta para lá.\n// ---------------------------------------------------------------------------\n\nexport interface PayableDraftState {\n supplier?: string\n /** O fornecedor já casou com um cadastro — ou é só um nome digitado. */\n supplierResolved: boolean\n description?: string\n total: number\n dueDate?: string\n itemCount: number\n}\n\nexport interface LivePayableDraft {\n describe: () => PayableDraftState\n setSupplier: (name: string, id?: string) => void\n setDueDate: (iso: string) => void\n submit: () => Promise<void>\n}\n\nlet liveDraft: LivePayableDraft | null = null\n\n/** True enquanto o cadastro de conta a pagar está na tela, com um rascunho. */\nexport function hasLivePayableDraft(): boolean {\n return liveDraft !== null\n}\n\n// ---------------------------------------------------------------------------\n// PASSO 0 — o que o papel pede que este negócio ainda não tem.\n//\n// Um recibo não nomeia só um valor: nomeia um fornecedor, uma forma de\n// pagamento, às vezes um cartão com quatro dígitos. Cada um deles ou já existe\n// aqui dentro ou precisa nascer ANTES da conta — e descobrir isso no meio da\n// escrita é descobrir tarde. Escrever a fatura e só então falhar na baixa\n// porque o método não existe deixa metade do trabalho no banco.\n//\n// Então há um passo de LEITURA antes de qualquer escrita: confere as três\n// dependências contra o locatário e devolve um relatório. Quem decide o que\n// criar é a pessoa, um cartão de cada vez; o relatório é o que deixa o\n// assistente dizer \"Printi: já existe · cartão final 4242: não achei\".\n// ---------------------------------------------------------------------------\n\n/** Sufixos societários e conectivos: \"PRINTI LTDA\" e \"Printi\" são a mesma empresa. */\nconst COMPANY_NOISE = new Set([\n 'ltda', 'ltd', 'me', 'epp', 'eireli', 'sa', 'mei', 'cia', 'ei', 'inc',\n 'comercio', 'servicos', 'industria', 'do', 'da', 'de', 'dos', 'das', 'e',\n])\n\n/** Sem acento, sem pontuação, sem sufixo societário, minúsculo. */\nexport function normalizeCompanyName(raw: unknown): string {\n if (typeof raw !== 'string') return ''\n return raw\n .normalize('NFD')\n // Marcas de combinação — o acento vira um caractere próprio depois do NFD.\n .replace(/[̀-ͯ]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, ' ')\n .split(/\\s+/)\n .filter((w) => w && !COMPANY_NOISE.has(w))\n .join(' ')\n .trim()\n}\n\n/** Só os dígitos — um CNPJ escrito com ponto e barra é o mesmo número. */\nfunction onlyDigits(raw: unknown): string {\n return typeof raw === 'string' ? raw.replace(/\\D/g, '') : ''\n}\n\n/** Os últimos quatro dígitos de um cartão, venham como vierem. */\nfunction lastFour(raw: unknown): string {\n const digits = onlyDigits(raw)\n return digits.length >= 4 ? digits.slice(-4) : ''\n}\n\ninterface SupplierCandidate { id: string; name: string; document?: string; why: string }\n\n/**\n * O fornecedor do papel contra os que já existem.\n *\n * Fuzzy ANTES de declarar que falta: o campo procura por `ilike` no nome\n * inteiro, então \"PRINTI LTDA\" não acha \"Printi\" e o cadastro nasceria em\n * dobro — dois fornecedores, o extrato de cada um contando metade das compras.\n * A busca vai pelo NÚCLEO do nome e a decisão é tomada aqui, sobre o\n * normalizado.\n */\nasync function findSupplier(\n lookup: EntityLookup,\n rawName: string,\n rawDocument?: unknown,\n): Promise<{ status: 'found' | 'ambiguous' | 'missing'; match?: SupplierCandidate; candidates: SupplierCandidate[] }> {\n const wanted = normalizeCompanyName(rawName)\n const doc = onlyDigits(rawDocument)\n if (!wanted) return { status: 'missing', candidates: [] }\n\n // O núcleo é o que se procura: a primeira palavra significativa acha\n // \"Printi\", \"Printi Grafica\" e \"PRINTI LTDA\" de uma vez.\n const core = wanted.split(' ')[0] ?? wanted\n const seen = new Map<string, SupplierCandidate>()\n for (const query of core === wanted ? [core] : [core, wanted]) {\n for (const hit of await lookup.search(query).catch(() => [])) {\n const row = (hit.data ?? {}) as Record<string, unknown>\n seen.set(hit.id, {\n id: hit.id,\n name: hit.label,\n document: onlyDigits(row.document_number) || undefined,\n why: '',\n })\n }\n }\n const all = [...seen.values()]\n\n // O DOCUMENTO manda: mesmo CNPJ é a mesma empresa, escreva-se como escrever.\n if (doc) {\n const byDoc = all.find((c) => c.document && c.document === doc)\n if (byDoc) return { status: 'found', match: { ...byDoc, why: 'mesmo CNPJ/CPF' }, candidates: [] }\n }\n\n const exact = all.filter((c) => normalizeCompanyName(c.name) === wanted)\n if (exact.length === 1) {\n const only = exact[0]!\n // Nome igual e documento DIFERENTE é provavelmente outra empresa homônima —\n // não se junta à força o que o papel diz ser outro CNPJ.\n if (doc && only.document && only.document !== doc) {\n return {\n status: 'ambiguous',\n candidates: [{ ...only, why: 'mesmo nome, mas o CNPJ do papel é outro' }],\n }\n }\n return { status: 'found', match: { ...only, why: 'nome idêntico' }, candidates: [] }\n }\n\n const near = all\n .map((c): SupplierCandidate | null => {\n const n = normalizeCompanyName(c.name)\n if (!n) return null\n if (n === wanted) return { ...c, why: 'nome idêntico' }\n if (n.startsWith(wanted) || wanted.startsWith(n)) return { ...c, why: 'nome contido' }\n const shared = n.split(' ').filter((w) => wanted.split(' ').includes(w))\n return shared.length ? { ...c, why: `parte do nome em comum (${shared.join(' ')})` } : null\n })\n .filter((c): c is SupplierCandidate => c !== null)\n .slice(0, 5)\n\n return { status: near.length ? 'ambiguous' : 'missing', candidates: near }\n}\n\n/**\n * A forma de pagamento do papel contra o catálogo do locatário.\n *\n * Duas listas respondem: os TIPOS (Pix, Dinheiro, Cartão de crédito) e os\n * MÉTODOS configurados (\"Visa 2x\"). O papel costuma nomear o tipo; a bandeira e\n * o final do cartão, quando impressos, apontam para o método ou para a conta.\n */\nasync function findMethod(\n provider: FinancialDataProvider,\n args: { paymentMethod?: unknown; cardBrand?: unknown; cardLast4?: unknown },\n): Promise<Record<string, unknown>> {\n const types = await paymentOptions(provider)\n const spoken = [args.paymentMethod, args.cardBrand]\n .filter((v): v is string => typeof v === 'string' && !!v.trim())\n const card = lastFour(args.cardLast4)\n // Uma bandeira ou um final de cartão impressos DIZEM cartão, mesmo que a\n // palavra \"crédito\" não apareça em lugar nenhum do papel.\n const looksLikeCard = !!(card || args.cardBrand)\n\n let match = matchPaymentOption(types, args.paymentMethod)\n if (!match && looksLikeCard) {\n match = types.find((t) => t.transactionType === 'credit_card') ?? null\n }\n\n const configured = (await provider.getPaymentMethods().catch(() => []))\n .filter((m) => m.isActive !== false)\n const namedMethod = configured.find((m) => {\n const n = normalizeCompanyName(m.name)\n return !!n && spoken.some((s) => {\n const w = normalizeCompanyName(s)\n return !!w && (n === w || n.includes(w) || w.includes(n))\n })\n })\n\n if (!match) {\n return {\n status: 'missing',\n spoken: spoken.join(' ') || undefined,\n cardLast4: card || undefined,\n available: types.map((t) => ({ id: t.id, label: t.label })),\n hint:\n 'This business has no payment method matching what the paper says. ASK which of the available ones it '\n + 'maps to, or offer to add it in Settings (createRecord on financial:payment-methods is the right tool '\n + 'for THAT, and only that). Never silently pick one.',\n }\n }\n return {\n status: 'found',\n id: match.id,\n label: match.label,\n transactionType: match.transactionType,\n ...(namedMethod ? { configuredMethod: { id: namedMethod.id, name: namedMethod.name } } : {}),\n ...(card ? { cardLast4: card } : {}),\n }\n}\n\n/** A conta de saída, e o cartão de quatro dígitos quando o papel o nomeia. */\nasync function findAccount(\n provider: FinancialDataProvider,\n method: Record<string, unknown>,\n rawLast4: unknown,\n): Promise<Record<string, unknown>> {\n if (method.status !== 'found') {\n return { status: 'blocked', hint: 'Resolve the payment method first — the eligible accounts depend on it.' }\n }\n if (method.transactionType === 'cash') {\n return {\n status: 'not_applicable',\n hint: 'Cash settles through the open cash session, not an account — nothing to choose.',\n }\n }\n const accounts = await eligibleAccounts(provider, {\n id: String(method.id),\n label: String(method.label),\n transactionType: method.transactionType as string | undefined,\n })\n const card = lastFour(rawLast4)\n const byCard = card\n ? accounts.find((a) => lastFour(a.accountNumber) === card || a.name.includes(card))\n : undefined\n if (byCard) return { status: 'found', id: byCard.id, name: byCard.name, why: `final ${card}` }\n if (!accounts.length) {\n return {\n status: 'missing',\n hint: `No account can settle a ${String(method.label)} payment. Say so — it has to be created in Settings.`,\n }\n }\n // O PAPEL NOMEOU UM CARTÃO QUE NÃO RECONHECEMOS.\n //\n // Mesmo havendo uma única conta elegível, aceitá-la em silêncio engoliria o\n // fato de que o recibo aponta um cartão específico — e \"final 4242\" pode ser\n // outro cartão da empresa que ninguém cadastrou. É exatamente a pergunta que\n // a pessoa precisa ver: \"final 4242: não achei — é este?\".\n if (card) {\n return {\n status: 'ambiguous',\n cardLast4: card,\n note: `o papel diz final ${card} e nenhuma conta cadastrada tem esse final`,\n options: accounts.map((a) => ({ id: a.id, name: a.name })),\n hint:\n `ASK whether the card ending ${card} is one of these accounts, or whether it still has to be `\n + 'registered. Do not assume it is the only eligible one.',\n }\n }\n if (accounts.length === 1) {\n return { status: 'found', id: accounts[0]!.id, name: accounts[0]!.name, why: 'única conta elegível' }\n }\n return {\n status: 'ambiguous',\n ...(card ? { cardLast4: card, note: `nenhuma conta bate com o final ${card}` } : {}),\n options: accounts.map((a) => ({ id: a.id, name: a.name })),\n hint: 'Ask which account the money left. Do not pick one.',\n }\n}\n\nconst RESOLVE_CONTEXT: PluginAITool = {\n id: 'financial.resolve-payable-context',\n name: 'resolvePayableContext',\n description:\n 'STEP 0, BEFORE writing anything: checks what a receipt names against what this business actually has. '\n + 'Call it as soon as you have read a receipt/photo/PDF, with EVERYTHING the paper says — supplier, its '\n + 'CNPJ/CPF if printed, the payment method, the card brand and last 4 digits if printed. '\n + 'Returns, for each dependency, whether it already exists here (fuzzy-matched on name and CNPJ, so the '\n + 'same supplier is never created twice), is ambiguous, or is missing — plus the candidates to choose from. '\n + 'Writes NOTHING. Report the result as a short checklist and then resolve the gaps IN ORDER: supplier '\n + 'first, then the payment method, then the bill (createPayable), then the payment.',\n icon: 'ListChecks',\n mode: 'read',\n execution: { plane: 'client' },\n category: 'Finance',\n role: 'finance',\n permission: { feature: 'financial', action: 'read' },\n parameters: {\n type: 'object',\n properties: {\n supplier: { type: 'string', description: 'O nome do fornecedor EXATAMENTE como está escrito no papel.' },\n supplierDocument: { type: 'string', description: 'O CNPJ ou CPF impresso, se houver. Copie os dígitos.' },\n paymentMethod: {\n type: 'string',\n description: 'Como o papel diz que foi pago (\"PIX\", \"cartão de crédito\", \"dinheiro\", \"boleto\").',\n },\n cardBrand: { type: 'string', description: 'A bandeira, se impressa (\"Visa\", \"Mastercard\", \"Nubank\").' },\n cardLast4: { type: 'string', description: 'Os quatro últimos dígitos do cartão, se impressos (\"4242\").' },\n // O DOCUMENTO INTEIRO, lido UMA VEZ.\n //\n // Não é zelo: é onde a fabricação entrava. Extrair no passo 0 e extrair de\n // novo no passo da conta são duas leituras do mesmo papel, e a segunda não\n // tem o papel na frente — ela tem a memória da primeira, que é onde os\n // números começam a escorregar. Lido aqui, normalizado aqui, conferido\n // aqui, e as ferramentas seguintes CONSOMEM o que ficou guardado.\n items: {\n type: 'array',\n description:\n 'As LINHAS da tabela do documento, uma por linha — leia linha a linha e copie TODAS.',\n items: {\n type: 'object',\n properties: {\n description: { type: 'string', description: 'O que é a linha, como está escrito.' },\n quantity: { type: 'number', description: 'A quantidade. 1 quando a tabela não diz.' },\n unitPrice: { type: 'string', description: 'Preço UNITÁRIO copiado (\"47,90\").' },\n },\n required: ['description', 'unitPrice'],\n },\n },\n shipping: { type: 'string', description: 'O FRETE cobrado à parte, copiado (\"52,19\").' },\n subtotal: { type: 'string', description: 'O subtotal impresso, se houver (\"1.437,00\").' },\n total: {\n type: 'string',\n description: 'O TOTAL do rodapé, copiado letra por letra (\"1.489,19\"). Com frete, sem converter.',\n },\n documentDate: { type: 'string', description: 'A data do documento (\"09/09/2026\").' },\n dueDate: {\n type: 'string',\n description:\n 'O VENCIMENTO, só se o papel disser. \"Expira em\" de um código Pix é a validade do CÓDIGO, '\n + 'não vencimento: um pedido pago à vista não tem, e aí se omite.',\n },\n paymentDate: { type: 'string', description: 'Quando foi pago, se o papel disser.' },\n orderRef: { type: 'string', description: 'O número do pedido ou documento (\"#164223\").' },\n deliveryDate: { type: 'string', description: 'A data de entrega, se impressa (\"11/09/2026\").' },\n },\n },\n}\n\nconst FILL_DRAFT: PluginAITool = {\n id: 'financial.fill-payable-draft',\n name: 'fillPayableDraft',\n description:\n 'Fills a field of the payable form ALREADY OPEN on screen (the draft the person is looking at). '\n + 'Use this — not createPayable — whenever that form is open: it is the bill in progress, and writing a '\n + 'new one instead would leave the person staring at a draft that means nothing. '\n + 'Looks the supplier up by name and offers to create it when it does not exist yet. Saves nothing.',\n icon: 'PenLine',\n mode: 'read',\n execution: { plane: 'client' },\n category: 'Finance',\n role: 'finance',\n parameters: {\n type: 'object',\n properties: {\n supplier: { type: 'string', description: 'O nome do fornecedor a colocar no rascunho.' },\n dueDate: { type: 'string', description: 'O vencimento, como foi dito (\"20/01/2026\").' },\n },\n },\n}\n\nconst SUBMIT_DRAFT: PluginAITool = {\n id: 'financial.submit-payable-draft',\n name: 'submitPayableDraft',\n description:\n 'SAVES the payable form open on screen — the same thing the screen\\'s save button does. '\n + 'This is how \"salva\", \"pode salvar\", \"confirma\" is answered while that form is open. '\n + 'Never call createPayable for a draft that is already on screen: that writes a second, duplicate bill.',\n icon: 'Check',\n mode: 'persist',\n execution: { plane: 'client' },\n requiresConfirmation: false,\n category: 'Finance',\n role: 'finance',\n permission: { feature: 'financial', action: 'create' },\n parameters: { type: 'object', properties: {} },\n}\n\n/**\n * O cadastro de conta a pagar, entregue ao assistente enquanto está na tela.\n *\n * Não desenha nada. Publica o ESTADO do rascunho (o Agent Surface Contract\n * existe para isto: o que só existe na tela, que o modelo precisa ver) e as\n * duas ferramentas que agem nele.\n */\nexport function PayableDraftSurface({ config, draft }: {\n config: ResolvedFinancialConfig\n draft: LivePayableDraft\n}) {\n const live = React.useRef(draft)\n live.current = draft\n\n const lookup = React.useMemo<EntityLookup>(\n () => config.contactLookup ?? createArchetypeLookup({\n archetype: 'person',\n kind: 'supplier',\n createKinds: ['supplier', 'staff', 'customer'],\n kindLabels: { supplier: 'Fornecedor', customer: 'Cliente', staff: 'Funcionário' },\n }),\n [config.contactLookup],\n )\n\n // Cada método DELEGA pelo ref, nunca é copiado.\n //\n // `{...live.current}` teria congelado o `submit` da primeira renderização —\n // um `handleSave` fechado sobre o estado vazio do formulário —, e salvar pelo\n // assistente responderia \"faltam dados\" com a tela cheia deles.\n React.useEffect(() => {\n liveDraft = {\n describe: () => live.current.describe(),\n setSupplier: (name, id) => live.current.setSupplier(name, id),\n setDueDate: (iso) => live.current.setDueDate(iso),\n submit: () => live.current.submit(),\n }\n return () => { liveDraft = null }\n }, [])\n\n const contribution = React.useMemo<AgentSurfaceContribution>(() => ({\n id: 'financial.payables.draft',\n pluginId: 'financial',\n role: 'finance',\n instructions:\n 'O cadastro de uma CONTA A PAGAR está aberto na tela, com um rascunho que a pessoa está conferindo. '\n + 'Enquanto ele estiver aí, ele É a conta em curso: use `fillPayableDraft` para completar o que falta e '\n + '`submitPayableDraft` para salvar. NÃO chame `createPayable` — ela criaria uma segunda conta e '\n + 'deixaria a pessoa num rascunho órfão. O estado do rascunho está em \"Tela aberta agora\".',\n describe: () => {\n const state = live.current.describe()\n return {\n title: 'Cadastro — Conta a pagar (rascunho não salvo)',\n state: { screen: '/financial/payables/new', draft: state },\n }\n },\n tools: [\n {\n tool: FILL_DRAFT,\n execute: async (args) => {\n const filled: string[] = []\n const dueDate = parseReceiptDate(args.dueDate)\n if (dueDate) { live.current.setDueDate(dueDate); filled.push('dueDate') }\n\n const name = text(args.supplier)\n if (name) {\n const step = await resolveSupplier(lookup, name)\n if (!step.ok) {\n return {\n ok: false,\n cancelled: true,\n reason: 'user_declined_supplier',\n message: 'The supplier was not created, so the draft still has none. Ask which supplier it is.',\n }\n }\n live.current.setSupplier(step.name, step.id)\n filled.push('supplier')\n }\n if (!filled.length) {\n return { ok: false, error: 'nothing_to_fill', message: 'Send a supplier or a dueDate to fill in.' }\n }\n return {\n ok: true,\n filled,\n draft: live.current.describe(),\n message:\n 'O rascunho na tela foi preenchido — nada foi salvo ainda. Diga em UMA frase o que entrou e '\n + 'que basta confirmar. Quando a pessoa mandar salvar, chame submitPayableDraft.',\n }\n },\n },\n {\n tool: SUBMIT_DRAFT,\n execute: async () => {\n const before = live.current.describe()\n if (!before.itemCount) {\n return {\n ok: false,\n error: 'empty_draft',\n message: 'NOTHING WAS SAVED. The draft has no line to bill. Say what is missing.',\n }\n }\n // O MESMO salvar do botão: validações, guard de plano, toasts e a\n // navegação para a ficha saem de lá. Um caminho paralelo teria de\n // repetir tudo isso e erraria numa delas.\n await live.current.submit()\n return {\n ok: true,\n saved: true,\n supplier: before.supplier,\n total: before.total,\n message:\n 'A conta a pagar foi salva a partir do rascunho que estava na tela, e a ficha dela já abriu. '\n + 'Diga isso em UMA frase e pare.',\n }\n },\n },\n ],\n }), [lookup])\n\n useAgentSurface(contribution)\n return null\n}\n\n/**\n * A superfície do Financeiro, montada no shell.\n *\n * Não desenha nada. Existe para que \"lançar uma conta a pagar\" seja uma porta\n * aberta em QUALQUER tela do app e não só dentro da lista de contas — que era\n * a razão de o assistente responder com a ferramenta errada.\n */\nexport function createFinancialAgentMount(deps: PayableAgentDeps): React.FC {\n const FinancialAgentMount: React.FC = () => {\n const contribution = React.useMemo<AgentSurfaceContribution>(() => ({\n id: 'financial.payables.global',\n pluginId: 'financial',\n role: 'finance',\n instructions: PAYABLE_INSTRUCTIONS,\n // Sem `describe`: esta superfície não é uma tela. O snapshot responde \"o\n // que está na tela agora\", e um mount de shell que dissesse \"Contas a\n // pagar\" mentiria em todas as outras rotas do app.\n tools: createPayableTools(deps),\n }), [])\n\n useAgentSurface(contribution)\n return null\n }\n FinancialAgentMount.displayName = 'FinancialAgentMount'\n return FinancialAgentMount\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createPluginContext } from '@fayz-ai/admin';
|
|
2
|
+
export { formatCurrency } from '@fayz-ai/admin';
|
|
3
|
+
|
|
4
|
+
// src/context.tsx
|
|
5
|
+
var ctx = createPluginContext("FinancialPage");
|
|
6
|
+
var FinancialContextProvider = ctx.ContextProvider;
|
|
7
|
+
var useFinancialConfig = ctx.useConfig;
|
|
8
|
+
var useFinancialProvider = ctx.useProvider;
|
|
9
|
+
var useFinancialStore = ctx.useStore;
|
|
10
|
+
|
|
11
|
+
export { FinancialContextProvider, useFinancialConfig, useFinancialProvider, useFinancialStore };
|
|
12
|
+
//# sourceMappingURL=chunk-CNXAVGSW.js.map
|
|
13
|
+
//# sourceMappingURL=chunk-CNXAVGSW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context.tsx"],"names":[],"mappings":";;;;AAwDA,IAAM,GAAA,GAAM,oBAAsF,eAAe,CAAA;AAE1G,IAAM,2BAA2B,GAAA,CAAI;AACrC,IAAM,qBAAqB,GAAA,CAAI;AAC/B,IAAM,uBAAuB,GAAA,CAAI;AACjC,IAAM,oBAAoB,GAAA,CAAI","file":"chunk-CNXAVGSW.js","sourcesContent":["import { createPluginContext, formatCurrency, type CurrencyConfig, type EntityLookupMap, type EntityLookup } from '@fayz-ai/admin'\nimport type { FinancialFiscalProviderConfig, FinancialPluginLabels, ItemTypeOption } from './index'\nimport type { FinancialDataProvider } from '@fayz-ai/financial/data/provider'\nimport type { FinancialUIState } from '@fayz-ai/financial/store'\n\n// ---------------------------------------------------------------------------\n// Resolved config — fully merged, no optionals\n// ---------------------------------------------------------------------------\n\nexport interface FinancialModules {\n payables: boolean\n receivables: boolean\n cashRegisters: boolean\n statements: boolean\n commissions: boolean\n cards: boolean\n /** Metas mensais de faturamento por unidade, em três degraus (025). */\n goals: boolean\n giftCards: boolean\n /** Bank reconciliation (conciliação). Opt-in — enable when a bank connector imports statements. */\n reconciliation: boolean\n /** Notas fiscais (NF-e/NFC-e/NFS-e). Opt-in — enable for fiscal-document tracking. */\n notasFiscais: boolean\n}\n\nexport type FinancialCurrency = CurrencyConfig\n\nexport interface LocationOption {\n id: string\n name: string\n isHQ?: boolean\n}\n\nexport interface ResolvedFinancialConfig {\n modules: FinancialModules\n labels: FinancialPluginLabels\n currency: FinancialCurrency\n itemTypes: ItemTypeOption[]\n enableServiceExecution: boolean\n contactEntity: { archetypeKind: string; label: string }\n locations: LocationOption[]\n entityLookups: EntityLookupMap\n contactLookup?: EntityLookup\n /** Provider capability advertised by an app-installed fiscal addon. */\n fiscalProvider?: FinancialFiscalProviderConfig\n /** Ver FinancialPluginOptions.moduleNav. */\n moduleNav?: 'rail' | 'tabs' | 'sidebar'\n onBookingClick?: (orderId: string) => void\n /** Internal nav item id → access feature id, exactly as the APP declared it\n * (`options.navFeatureMap`; empty when the app gates nothing — the plugin\n * ships no defaults). Drives BOTH the sub-module link paywall\n * (`useModuleNavAccess`) and the matching content gate, so the two can't\n * drift. Unmapped ids are ungated. */\n navFeatureMap: Record<string, string>\n}\n\nconst ctx = createPluginContext<ResolvedFinancialConfig, FinancialDataProvider, FinancialUIState>('FinancialPage')\n\nexport const FinancialContextProvider = ctx.ContextProvider\nexport const useFinancialConfig = ctx.useConfig\nexport const useFinancialProvider = ctx.useProvider\nexport const useFinancialStore = ctx.useStore\n\nexport { formatCurrency }\n"]}
|