@fayz-ai/plugin-fiscal-br 0.4.0 → 0.5.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/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { recordRailFields, RECORD_GROUP, activeFacet, getSupabaseClientOptional, connectionSettings, connectionStatus, definePlugin, createConnectionStore, settingsStatus, maskCpfCnpj } from '@fayz-ai/core';
2
2
  import React5, { useState, useCallback, useEffect, useMemo, useRef } from 'react';
3
- import { ModalHeader, ModalTitle, ModalBody, Skeleton, AiActionButton, Card, Button, EmBreve, SearchSelect, Input, DatePicker, Hint, ModalFooter, SubpageHeader, useFilterDraft, PageHeaderActions, FilterPanel, FilterPanelField, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SearchField, DataTable, ListFilterBar, Modal, ModalContent, ComingSoon, CardHeader, CardTitle, CardContent, toast, Badge, CardDescription, Switch } from '@fayz-ai/ui';
3
+ import { ModalHeader, ModalTitle, ModalBody, Skeleton, AiActionButton, Card, Button, EmBreve, SearchSelect, Input, DatePicker, Hint, ModalFooter, SubpageHeader, useFilterDraft, PageHeaderActions, FilterPanel, FilterPanelField, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SearchField, DataTable, ListFilterBar, Modal, ModalContent, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, ModalDescription, Badge, SegmentedControl, ComingSoon, toast, CardHeader, CardTitle, CardContent, CardDescription, Switch } from '@fayz-ai/ui';
4
4
  export { ComingSoon, EmBreve } from '@fayz-ai/ui';
5
- import { registerDocumentOpener, getActiveTenantId, useUnitFilter, UNIT_DETAIL_ZONES, adminNavigateTo } from '@fayz-ai/admin';
6
- import { Gift, RefreshCw, Loader2, FileDown, AlertTriangle, ChevronRight, Check, Trash2, Plus, Inbox, UploadCloud, ShieldCheck, FileText, ExternalLink, X, Info } from 'lucide-react';
5
+ import { registerDocumentOpener, getActiveTenantId, useUnitFilter, usePermissionOptional, UNIT_DETAIL_ZONES, adminNavigateTo } from '@fayz-ai/admin';
6
+ import { Gift, RefreshCw, Loader2, FileDown, AlertTriangle, ChevronRight, Check, Trash2, Plus, Inbox, UploadCloud, ShieldCheck, FileText, ExternalLink, CheckCircle2, FileCheck2, ChevronDown, XCircle, X, Info } from 'lucide-react';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
+ import { FINANCIAL_INVOICE_ZONES } from '@fayz-ai/plugin-financial';
8
9
 
9
10
  // src/index.ts
10
11
  var PLUGNOTAS_CONNECTOR_ID = "plugnotas";
@@ -3647,6 +3648,129 @@ CREATE POLICY plg_fiscalbr_emitter_settings_authz_write ON public.plg_fiscalbr_e
3647
3648
  WHERE le.id = plg_fiscalbr_emitter_settings.legal_entity_id
3648
3649
  AND le.tenant_id = plg_fiscalbr_emitter_settings.tenant_id));
3649
3650
  `;
3651
+ var MIGRATION_018_A_NOTA_DO_V1_ALCANCA_A_CONTA = `-- A nota que veio do V1 alcan\xE7a a conta que a gerou.
3652
+ --
3653
+ -- A conta a receber pergunta "que notas eu tenho?" pelo pedido dela:
3654
+ -- plg_financial_invoices.order_id \u2192 plg_fiscalbr_document_orders \u2192 a nota.
3655
+ -- A importa\xE7\xE3o s\xF3 preencheu esse v\xEDnculo a partir da tabela N:N do V1
3656
+ -- (fiscal_document_invoice_sources). A NFS-e do V1 nunca usou essa tabela: ela
3657
+ -- aponta a conta por fiscal_documents.invoice_id, que chegou aqui apenas como
3658
+ -- metadata.v1.invoice_ref. Medido em 06-10-2026 no cluster do ChefControl: 488
3659
+ -- NFS-e e 122 NFC-e sem caminho at\xE9 a conta.
3660
+ --
3661
+ -- A conta importada guarda o pr\xF3prio id do V1 em
3662
+ -- metadata.migration.source_numeric_id, ent\xE3o o par se resolve sem adivinhar.
3663
+ -- Num pool sem dado do V1 isto n\xE3o casa nada. Aditivo e idempotente.
3664
+
3665
+ INSERT INTO public.plg_fiscalbr_document_orders (tenant_id, document_id, order_id)
3666
+ SELECT DISTINCT f.tenant_id, f.document_id, i.order_id
3667
+ FROM public.plg_fiscalbr_documents f
3668
+ JOIN public.plg_financial_invoices i
3669
+ ON i.tenant_id = f.tenant_id
3670
+ AND i.metadata -> 'migration' ->> 'source_table' = 'invoices'
3671
+ AND i.metadata -> 'migration' ->> 'source_numeric_id' = f.metadata -> 'v1' ->> 'invoice_ref'
3672
+ JOIN public.orders o ON o.id = i.order_id
3673
+ WHERE f.metadata -> 'v1' ->> 'invoice_ref' IS NOT NULL
3674
+ ON CONFLICT (document_id, order_id) DO NOTHING;
3675
+ `;
3676
+ var MIGRATION_019_A_NOTA_EMITIDA_SE_CANCELA_PELO_V2 = `-- A nota emitida se consulta e se cancela pelo V2.
3677
+ --
3678
+ -- Quem fala com a PlugNotas \xE9 a fun\xE7\xE3o \`fiscalbr-plugnotas\` (a chave s\xF3 existe
3679
+ -- no servidor), mas ela roda com o JWT de quem clicou e n\xE3o grava nada direto:
3680
+ -- pergunta aqui se a pessoa pode, e devolve o resultado aqui. Uma porta de
3681
+ -- leitura, uma de escrita, a permiss\xE3o conferida nas duas.
3682
+ --
3683
+ -- consultar e baixar o PDF \u2192 financial.read na unidade da nota
3684
+ -- cancelar \u2192 financial.edit na unidade da nota
3685
+ --
3686
+ -- A espelho em \`documents.status\` anda junto: as duas tabelas s\xE3o a mesma nota
3687
+ -- vista de dois lugares (005), e um status divergente entre elas \xE9 a nota
3688
+ -- dizendo duas coisas. Idempotente.
3689
+
3690
+ CREATE OR REPLACE FUNCTION public.fiscalbr_note_for_provider(p_document_id uuid, p_action text)
3691
+ RETURNS jsonb
3692
+ LANGUAGE plpgsql
3693
+ STABLE SECURITY DEFINER
3694
+ SET search_path TO ''
3695
+ AS $$
3696
+ DECLARE
3697
+ v public.plg_fiscalbr_documents%ROWTYPE;
3698
+ BEGIN
3699
+ SELECT * INTO v FROM public.plg_fiscalbr_documents
3700
+ WHERE document_id = p_document_id AND tenant_id = app.current_tenant_id();
3701
+ IF NOT FOUND THEN
3702
+ RAISE EXCEPTION 'fiscal: note not found' USING ERRCODE = 'P0002';
3703
+ END IF;
3704
+ PERFORM public.plg_financial_require_permission(
3705
+ CASE WHEN p_action = 'cancel' THEN 'financial.edit' ELSE 'financial.read' END, v.unit_id);
3706
+ RETURN jsonb_build_object(
3707
+ 'document_id', v.document_id, 'model', v.model, 'status', v.status,
3708
+ 'environment', v.environment, 'provider_document_id', v.provider_document_id,
3709
+ 'cancelled_at', v.cancelled_at, 'access_key', v.access_key, 'number', v.number);
3710
+ END $$;
3711
+
3712
+ CREATE OR REPLACE FUNCTION public.fiscalbr_note_apply(
3713
+ p_document_id uuid,
3714
+ p_action text,
3715
+ p_patch jsonb,
3716
+ p_event jsonb DEFAULT NULL
3717
+ )
3718
+ RETURNS void
3719
+ LANGUAGE plpgsql
3720
+ SECURITY DEFINER
3721
+ SET search_path TO ''
3722
+ AS $$
3723
+ DECLARE
3724
+ v public.plg_fiscalbr_documents%ROWTYPE;
3725
+ v_status text := p_patch ->> 'status';
3726
+ BEGIN
3727
+ SELECT * INTO v FROM public.plg_fiscalbr_documents
3728
+ WHERE document_id = p_document_id AND tenant_id = app.current_tenant_id()
3729
+ FOR UPDATE;
3730
+ IF NOT FOUND THEN
3731
+ RAISE EXCEPTION 'fiscal: note not found' USING ERRCODE = 'P0002';
3732
+ END IF;
3733
+ PERFORM public.plg_financial_require_permission(
3734
+ CASE WHEN p_action = 'cancel' THEN 'financial.edit' ELSE 'financial.read' END, v.unit_id);
3735
+ IF v_status IS NOT NULL AND v_status NOT IN ('processing','authorized','rejected','error','cancelled','substituted') THEN
3736
+ RAISE EXCEPTION 'fiscal: unknown status %', v_status USING ERRCODE = '22023';
3737
+ END IF;
3738
+
3739
+ -- Only what the provider answers; identity (model, unit, order) never moves.
3740
+ UPDATE public.plg_fiscalbr_documents SET
3741
+ status = COALESCE(v_status, status),
3742
+ number = COALESCE(p_patch ->> 'number', number),
3743
+ series = COALESCE(p_patch ->> 'series', series),
3744
+ access_key = COALESCE(p_patch ->> 'access_key', access_key),
3745
+ verification_code = COALESCE(p_patch ->> 'verification_code', verification_code),
3746
+ status_payload = COALESCE(p_patch -> 'status_payload', status_payload),
3747
+ rejection_payload = CASE WHEN p_patch ? 'rejection_payload' THEN p_patch -> 'rejection_payload' ELSE rejection_payload END,
3748
+ authorized_at = COALESCE((p_patch ->> 'authorized_at')::timestamptz, authorized_at),
3749
+ last_polled_at = CASE WHEN p_action = 'poll' THEN now() ELSE last_polled_at END,
3750
+ cancelled_at = CASE WHEN p_patch ? 'cancelled_at' THEN (p_patch ->> 'cancelled_at')::timestamptz ELSE cancelled_at END,
3751
+ cancel_reason = CASE WHEN p_patch ? 'cancel_reason' THEN p_patch ->> 'cancel_reason' ELSE cancel_reason END,
3752
+ cancelled_by_user_id = CASE WHEN p_action = 'cancel' THEN auth.uid()
3753
+ WHEN p_patch ? 'cancelled_at' AND p_patch -> 'cancelled_at' = 'null'::jsonb THEN NULL
3754
+ ELSE cancelled_by_user_id END
3755
+ WHERE document_id = p_document_id;
3756
+
3757
+ IF v_status IS NOT NULL THEN
3758
+ UPDATE public.documents SET status = v_status WHERE id = p_document_id AND status IS DISTINCT FROM v_status;
3759
+ END IF;
3760
+
3761
+ IF p_event IS NOT NULL THEN
3762
+ INSERT INTO public.plg_fiscalbr_document_events
3763
+ (tenant_id, unit_id, document_id, event_type, status, justification, response_payload, created_by_user_id)
3764
+ VALUES (v.tenant_id, v.unit_id, p_document_id, p_event ->> 'event_type', p_event ->> 'status',
3765
+ p_event ->> 'justification', p_event -> 'response_payload', auth.uid());
3766
+ END IF;
3767
+ END $$;
3768
+
3769
+ REVOKE ALL ON FUNCTION public.fiscalbr_note_for_provider(uuid, text) FROM PUBLIC, anon;
3770
+ REVOKE ALL ON FUNCTION public.fiscalbr_note_apply(uuid, text, jsonb, jsonb) FROM PUBLIC, anon;
3771
+ GRANT EXECUTE ON FUNCTION public.fiscalbr_note_for_provider(uuid, text) TO authenticated;
3772
+ GRANT EXECUTE ON FUNCTION public.fiscalbr_note_apply(uuid, text, jsonb, jsonb) TO authenticated;
3773
+ `;
3650
3774
  var MIGRATIONS = [
3651
3775
  { id: "000_baseline", sql: MIGRATION_000_BASELINE },
3652
3776
  { id: "001_preserve_terminal_results_and_recover_leases", sql: MIGRATION_001_PRESERVE_TERMINAL_RESULTS_AND_RECOVER_LEASES },
@@ -3665,7 +3789,9 @@ var MIGRATIONS = [
3665
3789
  { id: "014_a_descricao_da_nota_tem_lixo_no_meio", sql: MIGRATION_014_A_DESCRICAO_DA_NOTA_TEM_LIXO_NO_MEIO },
3666
3790
  { id: "015_o_movimento_diz_que_veio_da_nota", sql: MIGRATION_015_O_MOVIMENTO_DIZ_QUE_VEIO_DA_NOTA },
3667
3791
  { id: "016_a_nota_guarda_o_proprio_xml", sql: MIGRATION_016_A_NOTA_GUARDA_O_PROPRIO_XML },
3668
- { id: "017_quem_emite_e_o_cnpj_nao_a_loja", sql: MIGRATION_017_QUEM_EMITE_E_O_CNPJ_NAO_A_LOJA }
3792
+ { id: "017_quem_emite_e_o_cnpj_nao_a_loja", sql: MIGRATION_017_QUEM_EMITE_E_O_CNPJ_NAO_A_LOJA },
3793
+ { id: "018_a_nota_do_v1_alcanca_a_conta", sql: MIGRATION_018_A_NOTA_DO_V1_ALCANCA_A_CONTA },
3794
+ { id: "019_a_nota_emitida_se_cancela_pelo_v2", sql: MIGRATION_019_A_NOTA_EMITIDA_SE_CANCELA_PELO_V2 }
3669
3795
  ];
3670
3796
  var taxGroupEntity = {
3671
3797
  name: "Grupo fiscal",
@@ -6305,6 +6431,499 @@ function UnitFiscalWidget({ item }) {
6305
6431
  ] })
6306
6432
  ] });
6307
6433
  }
6434
+ function sb3() {
6435
+ const supabase = getSupabaseClientOptional();
6436
+ if (!supabase) throw new Error("Supabase not initialized");
6437
+ return supabase;
6438
+ }
6439
+ var NOTE_COLUMNS2 = `document_id, model, status, environment, number, series, access_key,
6440
+ verification_code, provider_integration_id, total_value, recipient_snapshot, rejection_payload,
6441
+ created_at, authorized_at, cancelled_at, cancel_reason`;
6442
+ function toNote(r) {
6443
+ return {
6444
+ documentId: r.document_id,
6445
+ model: r.model,
6446
+ status: r.status,
6447
+ environment: r.environment ?? null,
6448
+ number: r.number ?? null,
6449
+ series: r.series ?? null,
6450
+ accessKey: r.access_key ?? null,
6451
+ verificationCode: r.verification_code ?? null,
6452
+ integrationId: r.provider_integration_id ?? null,
6453
+ totalValue: r.total_value == null ? null : Number(r.total_value),
6454
+ recipient: r.recipient_snapshot ?? null,
6455
+ rejection: r.rejection_payload ?? null,
6456
+ createdAt: r.created_at,
6457
+ authorizedAt: r.authorized_at ?? null,
6458
+ cancelledAt: r.cancelled_at ?? null,
6459
+ cancelReason: r.cancel_reason ?? null
6460
+ };
6461
+ }
6462
+ async function listInvoiceNotes(invoiceId) {
6463
+ const db = sb3();
6464
+ const { data: inv, error: invError } = await db.from("plg_financial_invoices").select("order_id").eq("id", invoiceId).maybeSingle();
6465
+ if (invError) throw invError;
6466
+ const orderId = inv?.order_id ?? null;
6467
+ if (!orderId) return [];
6468
+ const [linked, direct] = await Promise.all([
6469
+ db.from("plg_fiscalbr_document_orders").select("document_id").eq("order_id", orderId),
6470
+ db.from("plg_fiscalbr_documents").select(NOTE_COLUMNS2).eq("order_id", orderId)
6471
+ ]);
6472
+ if (linked.error) throw linked.error;
6473
+ if (direct.error) throw direct.error;
6474
+ const byId = /* @__PURE__ */ new Map();
6475
+ for (const r of direct.data ?? []) byId.set(r.document_id, toNote(r));
6476
+ const missing = (linked.data ?? []).map((r) => r.document_id).filter((id) => !byId.has(id));
6477
+ if (missing.length) {
6478
+ const { data, error } = await db.from("plg_fiscalbr_documents").select(NOTE_COLUMNS2).in("document_id", missing);
6479
+ if (error) throw error;
6480
+ for (const r of data ?? []) byId.set(r.document_id, toNote(r));
6481
+ }
6482
+ return [...byId.values()].sort((a, b) => b.createdAt.localeCompare(a.createdAt));
6483
+ }
6484
+ async function listNoteEvents(documentId) {
6485
+ const { data, error } = await sb3().from("plg_fiscalbr_document_events").select("id, event_type, status, justification, created_at").eq("document_id", documentId).order("created_at", { ascending: false }).limit(30);
6486
+ if (error) throw error;
6487
+ return (data ?? []).map((e) => ({
6488
+ id: e.id,
6489
+ eventType: e.event_type,
6490
+ status: e.status ?? null,
6491
+ justification: e.justification ?? null,
6492
+ createdAt: e.created_at
6493
+ }));
6494
+ }
6495
+ async function callIssuer(body) {
6496
+ const { data, error } = await sb3().functions.invoke("fiscalbr-plugnotas", { body: { ...body, tenantId: getActiveTenantId() } });
6497
+ if (error) {
6498
+ const ctx = error?.context;
6499
+ let message = error.message || "Falha ao falar com o emissor fiscal.";
6500
+ if (ctx && typeof ctx.json === "function") {
6501
+ try {
6502
+ const b = await ctx.json();
6503
+ if (b?.error) message = String(b.error);
6504
+ } catch {
6505
+ }
6506
+ }
6507
+ throw new Error(message);
6508
+ }
6509
+ if (data?.error) throw new Error(String(data.error));
6510
+ return data;
6511
+ }
6512
+ async function refreshNote(documentId) {
6513
+ const r = await callIssuer({ action: "poll_status", document_id: documentId });
6514
+ return String(r?.status ?? "");
6515
+ }
6516
+ async function cancelNote(documentId, justification, code) {
6517
+ const r = await callIssuer({ action: "cancel", document_id: documentId, justification, code });
6518
+ return String(r?.status ?? "");
6519
+ }
6520
+ async function fetchNotePdf(documentId) {
6521
+ const data = await callIssuer({ action: "get_pdf", document_id: documentId });
6522
+ if (!(data instanceof Blob)) throw new Error("O emissor n\xE3o devolveu um PDF.");
6523
+ return new Blob([data], { type: "application/pdf" });
6524
+ }
6525
+
6526
+ // src/lib/issued-note.ts
6527
+ var MODEL_LABEL = { nfse: "NFS-e", nfce: "NFC-e", nfe: "NF-e" };
6528
+ var STATUS_META = {
6529
+ authorized: { label: "Autorizada", tone: "success" },
6530
+ draft: { label: "Enviando", tone: "warning" },
6531
+ processing: { label: "Processando", tone: "warning" },
6532
+ rejected: { label: "Rejeitada", tone: "danger" },
6533
+ denied: { label: "Denegada", tone: "danger" },
6534
+ error: { label: "Erro", tone: "danger" },
6535
+ cancelled: { label: "Cancelada", tone: "muted" },
6536
+ substituted: { label: "Substitu\xEDda", tone: "muted" }
6537
+ };
6538
+ var EVENT_LABEL = {
6539
+ emissao: "Emiss\xE3o enviada",
6540
+ consulta: "Consulta de status",
6541
+ cancelamento: "Cancelamento",
6542
+ substituicao: "Substitui\xE7\xE3o",
6543
+ cce: "Carta de corre\xE7\xE3o",
6544
+ inutilizacao: "Inutiliza\xE7\xE3o",
6545
+ webhook: "Notifica\xE7\xE3o do emissor fiscal",
6546
+ erro: "Erro"
6547
+ };
6548
+ var EVENT_STATUS_LABEL = {
6549
+ CRIADO: "Enviando",
6550
+ PROCESSANDO: "Processando",
6551
+ CONCLUIDO: "Autorizada",
6552
+ REJEITADO: "Rejeitada",
6553
+ DENEGADO: "Denegada",
6554
+ CANCELADO: "Cancelada",
6555
+ SUBSTITUIDO: "Substitu\xEDda",
6556
+ SOLICITADO: "Solicitado",
6557
+ ERRO: "Erro"
6558
+ };
6559
+ function eventStatusLabel(status) {
6560
+ return status ? EVENT_STATUS_LABEL[status.toUpperCase()] ?? null : null;
6561
+ }
6562
+ var IN_FLIGHT = ["draft", "processing"];
6563
+ var WITHOUT_EFFECT = ["rejected", "denied", "error", "cancelled", "substituted"];
6564
+ function isWithoutEffect(status) {
6565
+ return WITHOUT_EFFECT.includes(status);
6566
+ }
6567
+ function statusLabel(note) {
6568
+ if (IN_FLIGHT.includes(note.status) && note.cancelledAt) return "Cancelamento solicitado";
6569
+ return (STATUS_META[note.status] ?? STATUS_META.error).label;
6570
+ }
6571
+ function summarizeNotes(notes) {
6572
+ const s = { hasValid: false, withoutEffect: 0, inFlight: 0, validIsTest: false };
6573
+ for (const n of notes) {
6574
+ if (n.status === "authorized") {
6575
+ s.hasValid = true;
6576
+ if (n.environment === "homologacao") s.validIsTest = true;
6577
+ } else if (IN_FLIGHT.includes(n.status)) s.inFlight += 1;
6578
+ else if (WITHOUT_EFFECT.includes(n.status)) s.withoutEffect += 1;
6579
+ }
6580
+ return s;
6581
+ }
6582
+ function notesButtonState(s) {
6583
+ if (s.hasValid) return "authorized";
6584
+ if (s.inFlight > 0) return "processing";
6585
+ if (s.withoutEffect > 0) return "failed-only";
6586
+ return "none";
6587
+ }
6588
+ var SEFAZ_HINTS = [
6589
+ ["E0120", "no padr\xE3o nacional a Inscri\xE7\xE3o Municipal \xE9 opcional (a nota identifica pelo CNPJ). Apague a IM na configura\xE7\xE3o fiscal da unidade e emita de novo."],
6590
+ ["E0312", "geralmente falta o C\xD3DIGO DE TRIBUTA\xC7\xC3O DO MUNIC\xCDPIO (3 d\xEDgitos) na configura\xE7\xE3o fiscal da unidade \u2014 n\xE3o o nacional. Cada prefeitura tem a sua tabela; confirme o c\xF3digo com a contabilidade."],
6591
+ ["E0314", "o c\xF3digo de tributa\xE7\xE3o do munic\xEDpio n\xE3o existe na tabela daquela prefeitura. Confirme o valor com a contabilidade da unidade \u2014 ele n\xE3o \xE9 o mesmo em todo munic\xEDpio. Fora do Rio de Janeiro, o normal \xE9 deixar esse campo VAZIO."],
6592
+ ["E0084", "o CNPJ n\xE3o consta como estabelecido nesse munic\xEDpio no cadastro nacional. Isso se resolve FORA do sistema: a empresa precisa ter inscri\xE7\xE3o municipal ativa na prefeitura e o endere\xE7o do CNPJ na Receita Federal apontando para o mesmo munic\xEDpio. Fale com a contabilidade \u2014 n\xE3o h\xE1 o que ajustar aqui."]
6593
+ ];
6594
+ var FIELD_LABELS = {
6595
+ "prestador.cpfCnpj": "CNPJ do emitente",
6596
+ "tomador.cpfCnpj": "CPF/CNPJ do cliente",
6597
+ "tomador.razaoSocial": "Nome do cliente",
6598
+ "tomador.endereco.cep": "CEP do cliente",
6599
+ "tomador.endereco.codigoCidade": "Munic\xEDpio do cliente",
6600
+ "servico.codigo": "C\xF3digo de tributa\xE7\xE3o do servi\xE7o",
6601
+ "servico.iss.aliquota": "Al\xEDquota de ISS",
6602
+ "itens.ncm": "NCM do produto",
6603
+ "itens.cfop": "CFOP do produto",
6604
+ "pagamentos.meio": "Forma de pagamento (tPag)",
6605
+ "emitente.inscricaoMunicipal": "Inscri\xE7\xE3o municipal",
6606
+ "emitente.inscricaoEstadual": "Inscri\xE7\xE3o estadual"
6607
+ };
6608
+ function explainRejection(rejection) {
6609
+ if (!rejection) return { summary: "Nota rejeitada sem detalhe do motivo.", fields: [] };
6610
+ const r = Array.isArray(rejection) ? rejection[0] : rejection;
6611
+ const err = r?.error ?? r;
6612
+ let message = String(err?.message || r?.mensagem || r?.motivo || "Nota rejeitada.");
6613
+ const embedded = message.match(/\[\s*\{[\s\S]*\}\s*\]/);
6614
+ if (embedded) {
6615
+ try {
6616
+ const arr = JSON.parse(embedded[0]);
6617
+ const parts = (Array.isArray(arr) ? arr : [arr]).map((e) => [e.Codigo ?? e.codigo, e.Descricao ?? e.descricao ?? e.Mensagem ?? e.mensagem].filter(Boolean).join(" \u2014 ")).filter(Boolean);
6618
+ if (parts.length) message = parts.join("; ");
6619
+ } catch {
6620
+ }
6621
+ }
6622
+ const hint = SEFAZ_HINTS.find(([code]) => message.includes(code));
6623
+ if (hint) message = `${message} \u2014 ${hint[1]}`;
6624
+ const fieldsObj = err?.data?.fields ?? {};
6625
+ const fields = Object.entries(fieldsObj).map(([field, msg]) => {
6626
+ const normalized = field.replace(/\[\d+\]/g, "").replace(/\.\d+\./g, ".");
6627
+ return { field, label: FIELD_LABELS[normalized] ?? field, message: String(msg) };
6628
+ });
6629
+ return { summary: message, fields };
6630
+ }
6631
+ function recipientLabel(recipient) {
6632
+ if (!recipient) return "Consumidor final";
6633
+ if (recipient.consumidor) return "Consumidor final";
6634
+ return String(recipient.razaoSocial ?? recipient.nome ?? recipient.cpfCnpj ?? "Consumidor final");
6635
+ }
6636
+ var TONE_VARIANT = {
6637
+ success: "success",
6638
+ warning: "warning",
6639
+ danger: "destructive",
6640
+ muted: "default"
6641
+ };
6642
+ var dateTime = (v) => v ? new Date(v).toLocaleString("pt-BR", { dateStyle: "short", timeStyle: "short" }) : "\u2014";
6643
+ var dayOrDateTime = (v) => {
6644
+ if (!v) return "\u2014";
6645
+ const d = new Date(v);
6646
+ return d.getHours() === 0 && d.getMinutes() === 0 && d.getSeconds() === 0 ? d.toLocaleDateString("pt-BR") : dateTime(v);
6647
+ };
6648
+ var money4 = (v) => v == null ? "\u2014" : v.toLocaleString("pt-BR", { style: "currency", currency: "BRL" });
6649
+ function buttonHint(s) {
6650
+ const parts = [s.hasValid ? "Notas fiscais desta conta \u2014 h\xE1 uma nota v\xE1lida" : "Notas fiscais desta conta"];
6651
+ if (s.withoutEffect > 0) parts.push(`${s.withoutEffect} cancelada(s), rejeitada(s) ou com erro`);
6652
+ if (s.validIsTest) parts.push("a nota v\xE1lida \xE9 de TESTE, sem valor fiscal");
6653
+ return parts.join(" \xB7 ");
6654
+ }
6655
+ function InvoiceNotesButton({ invoiceId, direction, cancelled }) {
6656
+ const [notes, setNotes] = useState(null);
6657
+ const [open, setOpen] = useState(false);
6658
+ const can = usePermissionOptional();
6659
+ const canCancel = can("financial", "edit");
6660
+ const reload = useCallback(async () => {
6661
+ if (!invoiceId || direction !== "credit") return;
6662
+ try {
6663
+ setNotes(await listInvoiceNotes(invoiceId));
6664
+ } catch {
6665
+ setNotes((prev) => prev ?? []);
6666
+ }
6667
+ }, [invoiceId, direction]);
6668
+ useEffect(() => {
6669
+ void reload();
6670
+ }, [reload]);
6671
+ if (!notes || notes.length === 0) return null;
6672
+ const summary = summarizeNotes(notes);
6673
+ const state = notesButtonState(summary);
6674
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
6675
+ /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
6676
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "relative h-9 gap-1.5", "aria-label": "Nota Fiscal", onClick: () => setOpen(true), children: [
6677
+ state === "authorized" ? /* @__PURE__ */ jsx(CheckCircle2, { className: "h-4 w-4 text-success", "aria-hidden": true }) : state === "processing" ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-warning", "aria-hidden": true }) : /* @__PURE__ */ jsx(FileCheck2, { className: "h-4 w-4", "aria-hidden": true }),
6678
+ /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Nota Fiscal" }),
6679
+ summary.withoutEffect > 0 && /* @__PURE__ */ jsx("span", { className: "inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-destructive px-1 text-[10px] font-bold text-destructive-foreground", children: summary.withoutEffect }),
6680
+ summary.validIsTest && /* @__PURE__ */ jsx("span", { className: "rounded border border-destructive px-1 text-[10px] font-semibold text-destructive", children: "TESTE" })
6681
+ ] }) }),
6682
+ /* @__PURE__ */ jsx(TooltipContent, { children: buttonHint(summary) })
6683
+ ] }) }),
6684
+ /* @__PURE__ */ jsx(Modal, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(ModalContent, { size: "2xl", children: [
6685
+ /* @__PURE__ */ jsxs(ModalHeader, { children: [
6686
+ /* @__PURE__ */ jsx(ModalTitle, { children: "Nota Fiscal" }),
6687
+ /* @__PURE__ */ jsx(ModalDescription, { children: "Notas emitidas para esta conta." })
6688
+ ] }),
6689
+ /* @__PURE__ */ jsxs(ModalBody, { className: "gap-2", children: [
6690
+ notes.map((n) => /* @__PURE__ */ jsx(NoteRow, { note: n, canCancel, onChanged: reload }, n.documentId)),
6691
+ /* @__PURE__ */ jsx("p", { className: "pt-2 text-xs text-muted-foreground", children: "Emitir uma nota nova por aqui chega na pr\xF3xima etapa." })
6692
+ ] })
6693
+ ] }) })
6694
+ ] });
6695
+ }
6696
+ var POLL_DELAYS = [3e3, 5e3, 8e3, 12e3, 2e4];
6697
+ function NoteRow({ note, canCancel, onChanged }) {
6698
+ const [expanded, setExpanded] = useState(false);
6699
+ const [cancelling, setCancelling] = useState(false);
6700
+ const [busy, setBusy] = useState(null);
6701
+ const dimmed = isWithoutEffect(note.status);
6702
+ const tone = (STATUS_META[note.status] ?? STATUS_META.error).tone;
6703
+ const usable = note.status === "authorized" || note.status === "cancelled";
6704
+ const inFlight = note.status === "processing" || note.status === "draft";
6705
+ const cancellable = canCancel && note.status === "authorized" && !note.cancelledAt;
6706
+ const openPdf = async () => {
6707
+ const w = window.open("", "_blank");
6708
+ setBusy("pdf");
6709
+ try {
6710
+ const blob = await fetchNotePdf(note.documentId);
6711
+ const url = URL.createObjectURL(blob);
6712
+ if (w) w.location.href = url;
6713
+ else window.location.assign(url);
6714
+ } catch (e) {
6715
+ w?.close();
6716
+ toast.error("PDF indispon\xEDvel", { description: e instanceof Error ? e.message : String(e) });
6717
+ } finally {
6718
+ setBusy(null);
6719
+ }
6720
+ };
6721
+ const refresh = async () => {
6722
+ setBusy("refresh");
6723
+ try {
6724
+ const status = await refreshNote(note.documentId);
6725
+ await onChanged();
6726
+ toast(status === note.status ? "Ainda em processamento na SEFAZ/prefeitura" : `Nota ${statusLabel({ status, cancelledAt: null }).toLowerCase()}`);
6727
+ } catch (e) {
6728
+ toast.error("N\xE3o foi poss\xEDvel consultar", { description: e instanceof Error ? e.message : String(e) });
6729
+ } finally {
6730
+ setBusy(null);
6731
+ }
6732
+ };
6733
+ return /* @__PURE__ */ jsxs("div", { className: `rounded-lg border ${dimmed ? "bg-muted/30" : ""}`, children: [
6734
+ /* @__PURE__ */ jsxs(
6735
+ "button",
6736
+ {
6737
+ type: "button",
6738
+ className: "flex w-full items-center gap-2 p-3 text-left",
6739
+ onClick: () => setExpanded((v) => !v),
6740
+ "aria-expanded": expanded,
6741
+ children: [
6742
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-2", children: [
6743
+ /* @__PURE__ */ jsx(Badge, { variant: "outline", children: MODEL_LABEL[note.model] ?? note.model }),
6744
+ note.number && /* @__PURE__ */ jsxs("span", { className: "font-mono text-sm", children: [
6745
+ "n\xBA ",
6746
+ note.number
6747
+ ] }),
6748
+ /* @__PURE__ */ jsx(Badge, { variant: TONE_VARIANT[tone], children: statusLabel(note) }),
6749
+ note.environment === "homologacao" && /* @__PURE__ */ jsx("span", { className: "rounded border border-destructive px-1 text-[10px] font-semibold text-destructive", children: "TESTE" }),
6750
+ /* @__PURE__ */ jsx("span", { className: "ml-auto text-xs tabular-nums text-muted-foreground", children: dateTime(note.createdAt) })
6751
+ ] }),
6752
+ /* @__PURE__ */ jsx(ChevronDown, { className: `h-4 w-4 shrink-0 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}`, "aria-hidden": true })
6753
+ ]
6754
+ }
6755
+ ),
6756
+ note.cancelReason && !expanded && /* @__PURE__ */ jsxs("p", { className: "flex items-start gap-1.5 px-3 pb-2 text-xs text-muted-foreground", children: [
6757
+ /* @__PURE__ */ jsx(AlertTriangle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0", "aria-hidden": true }),
6758
+ /* @__PURE__ */ jsxs("span", { className: "break-words", children: [
6759
+ "Motivo: ",
6760
+ note.cancelReason
6761
+ ] })
6762
+ ] }),
6763
+ (usable || inFlight || note.cancelledAt) && !cancelling && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5 px-3 pb-3", children: [
6764
+ usable && /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className: "h-7 text-xs", disabled: busy === "pdf", onClick: openPdf, children: [
6765
+ busy === "pdf" ? /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin", "aria-hidden": true }) : /* @__PURE__ */ jsx(FileText, { className: "h-3.5 w-3.5", "aria-hidden": true }),
6766
+ "PDF"
6767
+ ] }),
6768
+ (inFlight || note.cancelledAt && note.status === "authorized") && /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className: "h-7 text-xs", disabled: busy === "refresh", onClick: refresh, children: [
6769
+ busy === "refresh" ? /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin", "aria-hidden": true }) : /* @__PURE__ */ jsx(RefreshCw, { className: "h-3.5 w-3.5", "aria-hidden": true }),
6770
+ "Atualizar"
6771
+ ] }),
6772
+ cancellable && /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", className: "ml-auto h-7 text-xs text-destructive hover:text-destructive", onClick: () => setCancelling(true), children: [
6773
+ /* @__PURE__ */ jsx(XCircle, { className: "h-3.5 w-3.5", "aria-hidden": true }),
6774
+ " Cancelar nota"
6775
+ ] })
6776
+ ] }),
6777
+ cancelling && /* @__PURE__ */ jsx(CancelNotePanel, { note, onClose: () => setCancelling(false), onDone: async () => {
6778
+ setCancelling(false);
6779
+ await onChanged();
6780
+ } }),
6781
+ expanded && /* @__PURE__ */ jsx(NoteDetails, { note })
6782
+ ] });
6783
+ }
6784
+ var NFSE_REASONS = [
6785
+ { value: "1", label: "Erro na emiss\xE3o" },
6786
+ { value: "2", label: "Servi\xE7o n\xE3o prestado" },
6787
+ { value: "9", label: "Outros" }
6788
+ ];
6789
+ function CancelNotePanel({ note, onClose, onDone }) {
6790
+ const isNfse = note.model === "nfse";
6791
+ const [code, setCode] = useState("2");
6792
+ const [text, setText] = useState("");
6793
+ const [working, setWorking] = useState(null);
6794
+ const [error, setError] = useState(null);
6795
+ const min = isNfse ? 10 : 15;
6796
+ const missing = Math.max(0, min - text.trim().length);
6797
+ const confirm = async () => {
6798
+ setError(null);
6799
+ setWorking("sending");
6800
+ try {
6801
+ let status = await cancelNote(note.documentId, text.trim(), isNfse ? code : void 0);
6802
+ setWorking("waiting");
6803
+ for (const delay of POLL_DELAYS) {
6804
+ if (status === "cancelled" || status === "authorized") break;
6805
+ await new Promise((r) => setTimeout(r, delay));
6806
+ try {
6807
+ status = await refreshNote(note.documentId);
6808
+ } catch {
6809
+ }
6810
+ }
6811
+ if (status === "cancelled") toast.success(`${MODEL_LABEL[note.model]} n\xBA ${note.number ?? ""} cancelada`);
6812
+ else if (status === "authorized") toast.error("A SEFAZ/prefeitura recusou o cancelamento", { description: "A nota continua v\xE1lida. Veja o hist\xF3rico nos detalhes." });
6813
+ else toast("Cancelamento solicitado", { description: "A SEFAZ/prefeitura ainda est\xE1 processando. Use \xABAtualizar\xBB para conferir." });
6814
+ await onDone();
6815
+ } catch (e) {
6816
+ setError(e instanceof Error ? e.message : String(e));
6817
+ setWorking(null);
6818
+ }
6819
+ };
6820
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3 border-t bg-destructive-soft/40 px-3 py-3", children: [
6821
+ /* @__PURE__ */ jsxs("p", { className: "text-sm font-semibold", children: [
6822
+ "Cancelar ",
6823
+ MODEL_LABEL[note.model],
6824
+ " ",
6825
+ note.number ? `n\xBA ${note.number}` : ""
6826
+ ] }),
6827
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
6828
+ isNfse ? "O prazo de cancelamento da NFS-e \xE9 definido pelo munic\xEDpio." : "O prazo de cancelamento da NFC-e \xE9 curto (em geral ~30 minutos ap\xF3s a autoriza\xE7\xE3o, conforme a UF). Fora do prazo, a SEFAZ recusa.",
6829
+ " ",
6830
+ "Cancelar n\xE3o pode ser desfeito."
6831
+ ] }),
6832
+ isNfse && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
6833
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-medium", children: "Motivo" }),
6834
+ /* @__PURE__ */ jsx(SegmentedControl, { size: "sm", "aria-label": "Motivo do cancelamento", options: NFSE_REASONS, value: code, onChange: setCode })
6835
+ ] }),
6836
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
6837
+ /* @__PURE__ */ jsx("label", { htmlFor: `cancel-${note.documentId}`, className: "text-xs font-medium", children: "Justificativa" }),
6838
+ /* @__PURE__ */ jsx(
6839
+ "textarea",
6840
+ {
6841
+ id: `cancel-${note.documentId}`,
6842
+ value: text,
6843
+ onChange: (e) => setText(e.target.value),
6844
+ maxLength: 255,
6845
+ rows: 3,
6846
+ disabled: !!working,
6847
+ placeholder: isNfse ? "Descreva o motivo\u2026" : "Ex.: Emiss\xE3o em duplicidade por erro operacional",
6848
+ className: "w-full resize-y rounded-md border bg-background px-3 py-2 text-sm",
6849
+ autoFocus: true
6850
+ }
6851
+ ),
6852
+ /* @__PURE__ */ jsx("p", { className: "text-[11px] text-muted-foreground", children: missing > 0 ? `Faltam ${missing} caractere(s) \u2014 a justificativa vai para a SEFAZ/prefeitura.` : "Vai para a SEFAZ/prefeitura junto do pedido." })
6853
+ ] }),
6854
+ error && /* @__PURE__ */ jsxs("p", { className: "flex items-start gap-1.5 rounded-md border border-destructive/40 bg-destructive-soft p-2 text-xs text-destructive-soft-foreground", children: [
6855
+ /* @__PURE__ */ jsx(AlertTriangle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0", "aria-hidden": true }),
6856
+ " ",
6857
+ /* @__PURE__ */ jsx("span", { className: "break-words", children: error })
6858
+ ] }),
6859
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap justify-end gap-2", children: [
6860
+ /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: onClose, disabled: !!working, children: "Voltar" }),
6861
+ /* @__PURE__ */ jsxs(Button, { variant: "destructive", size: "sm", onClick: confirm, disabled: !!working || missing > 0, children: [
6862
+ working ? /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin", "aria-hidden": true }) : /* @__PURE__ */ jsx(XCircle, { className: "h-3.5 w-3.5", "aria-hidden": true }),
6863
+ working === "waiting" ? "Aguardando a SEFAZ/prefeitura\u2026" : working ? "Enviando\u2026" : "Confirmar cancelamento"
6864
+ ] })
6865
+ ] })
6866
+ ] });
6867
+ }
6868
+ function NoteDetails({ note }) {
6869
+ const [events, setEvents] = useState(null);
6870
+ useEffect(() => {
6871
+ let alive = true;
6872
+ listNoteEvents(note.documentId).then((e) => {
6873
+ if (alive) setEvents(e);
6874
+ }).catch(() => {
6875
+ if (alive) setEvents([]);
6876
+ });
6877
+ return () => {
6878
+ alive = false;
6879
+ };
6880
+ }, [note.documentId]);
6881
+ const failed = ["rejected", "denied", "error"].includes(note.status);
6882
+ const rejection = failed ? explainRejection(note.rejection) : null;
6883
+ const rows = [
6884
+ ["Refer\xEAncia", note.integrationId && /* @__PURE__ */ jsx("span", { className: "break-all font-mono text-xs", children: note.integrationId })],
6885
+ ["Chave de acesso", note.accessKey && /* @__PURE__ */ jsx("span", { className: "break-all font-mono text-xs", children: note.accessKey })],
6886
+ ["C\xF3digo de verifica\xE7\xE3o", note.verificationCode],
6887
+ ["Valor", money4(note.totalValue)],
6888
+ ["Tomador", recipientLabel(note.recipient)],
6889
+ ["Criada em", dateTime(note.createdAt)],
6890
+ ["Autorizada em", note.authorizedAt && dayOrDateTime(note.authorizedAt)],
6891
+ ["Cancelada em", note.cancelledAt && `${dateTime(note.cancelledAt)}${note.cancelReason ? ` \u2014 ${note.cancelReason}` : ""}`]
6892
+ ];
6893
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3 border-t px-3 py-3", children: [
6894
+ /* @__PURE__ */ jsx("dl", { className: "text-sm", children: rows.filter(([, v]) => v).map(([label, value]) => /* @__PURE__ */ jsxs("div", { className: "flex gap-3 border-b py-1.5 last:border-0", children: [
6895
+ /* @__PURE__ */ jsx("dt", { className: "w-28 shrink-0 text-muted-foreground sm:w-36", children: label }),
6896
+ /* @__PURE__ */ jsx("dd", { className: "min-w-0 flex-1 break-words font-medium", children: value })
6897
+ ] }, label)) }),
6898
+ rejection && /* @__PURE__ */ jsxs("div", { className: "space-y-1.5 rounded-md border border-destructive/40 bg-destructive-soft p-3", children: [
6899
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-destructive-soft-foreground", children: "Por que foi rejeitada?" }),
6900
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", children: rejection.summary }),
6901
+ rejection.fields.length > 0 && /* @__PURE__ */ jsx("ul", { className: "space-y-1 text-xs text-foreground", children: rejection.fields.map((f) => /* @__PURE__ */ jsxs("li", { children: [
6902
+ /* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
6903
+ f.label,
6904
+ ":"
6905
+ ] }),
6906
+ " ",
6907
+ f.message
6908
+ ] }, f.field)) })
6909
+ ] }),
6910
+ events === null ? /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
6911
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
6912
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-2/3" })
6913
+ ] }) : events.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
6914
+ /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-sm font-semibold", children: "Hist\xF3rico" }),
6915
+ /* @__PURE__ */ jsx("ul", { className: "space-y-1", children: events.map((e) => /* @__PURE__ */ jsxs("li", { className: "flex flex-wrap items-center gap-2 text-xs", children: [
6916
+ /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap tabular-nums text-muted-foreground", children: dateTime(e.createdAt) }),
6917
+ /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-[10px]", children: EVENT_LABEL[e.eventType] ?? "Evento" }),
6918
+ eventStatusLabel(e.status) && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: eventStatusLabel(e.status) }),
6919
+ e.justification && /* @__PURE__ */ jsxs("span", { className: "min-w-0 truncate", children: [
6920
+ "\u2014 ",
6921
+ e.justification
6922
+ ] })
6923
+ ] }, e.id)) })
6924
+ ] })
6925
+ ] });
6926
+ }
6308
6927
 
6309
6928
  // src/lib/financial-provider.ts
6310
6929
  function fiscalReader(provider) {
@@ -6578,6 +7197,13 @@ function createPlugNotasPlugin(options = {}) {
6578
7197
  order: 0,
6579
7198
  permission: { feature: "financial", action: "read" }
6580
7199
  },
7200
+ {
7201
+ id: "fiscal-br-invoice-notes",
7202
+ zone: FINANCIAL_INVOICE_ZONES.headerActions,
7203
+ component: InvoiceNotesButton,
7204
+ order: 0,
7205
+ permission: { feature: "financial", action: "read" }
7206
+ },
6581
7207
  {
6582
7208
  id: "fiscal-br-unit-fiscal",
6583
7209
  zone: UNIT_DETAIL_ZONES.fiscal,
@@ -6657,6 +7283,6 @@ function createPlugNotasPlugin(options = {}) {
6657
7283
  });
6658
7284
  }
6659
7285
 
6660
- export { InboundNoteDocumentModal, InboundNotesPage, InboundNotesView, IssuedNotesView, ManifestView, NfeParseError, NoteReconcileView, PLUGNOTAS_CONNECTOR_ID, PLUGNOTAS_FIELDS, PLUGNOTAS_SETTINGS, ReturnedNotesView, STOCK_BEARING_ENTRY_TYPES, TaxGroupsView, acceptNote, createPlugNotasConnector, createPlugNotasFinancialProvider, createPlugNotasPlugin, findInboxNoteByNumber, findInboxNoteByOperation, getInboxNote, getInboxNoteXml, inboundNoteDocumentModal, inboundNotesInventoryView, isStockBearing, isValidCnpj, listChartAccounts, listInboxNotes, listMeasurementUnits, listProductsByIds, listStockLocations, listSupplierMap, markPlugNotasEmitterReady, onlyDigits, parseNfeXml, paymentLabel, paymentTypeFromCode, rejectNote, saveNoteDecision, searchProducts, stageNoteFromXml, suggestNoteItems, toStagePayload };
7286
+ export { EVENT_LABEL, InboundNoteDocumentModal, InboundNotesPage, InboundNotesView, InvoiceNotesButton, IssuedNotesView, MODEL_LABEL, ManifestView, NfeParseError, NoteReconcileView, PLUGNOTAS_CONNECTOR_ID, PLUGNOTAS_FIELDS, PLUGNOTAS_SETTINGS, ReturnedNotesView, STATUS_META, STOCK_BEARING_ENTRY_TYPES, TaxGroupsView, acceptNote, cancelNote, createPlugNotasConnector, createPlugNotasFinancialProvider, createPlugNotasPlugin, eventStatusLabel, explainRejection, fetchNotePdf, findInboxNoteByNumber, findInboxNoteByOperation, getInboxNote, getInboxNoteXml, inboundNoteDocumentModal, inboundNotesInventoryView, isStockBearing, isValidCnpj, isWithoutEffect, listChartAccounts, listInboxNotes, listInvoiceNotes, listMeasurementUnits, listNoteEvents, listProductsByIds, listStockLocations, listSupplierMap, markPlugNotasEmitterReady, notesButtonState, onlyDigits, parseNfeXml, paymentLabel, paymentTypeFromCode, recipientLabel, refreshNote, rejectNote, saveNoteDecision, searchProducts, stageNoteFromXml, statusLabel, suggestNoteItems, summarizeNotes, toStagePayload };
6661
7287
  //# sourceMappingURL=index.js.map
6662
7288
  //# sourceMappingURL=index.js.map