@fayz-ai/plugin-fiscal-br 0.13.1 → 0.13.2

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
@@ -3,7 +3,7 @@ import { createConnectionStore, recordRailFields, RECORD_GROUP, activeFacet, des
3
3
  import React, { useState, useCallback, useEffect, useMemo, useRef } from 'react';
4
4
  import { ModalHeader, ModalTitle, ModalBody, Skeleton, AiActionButton, Dropdown, DropdownTrigger, Button, DropdownContent, DropdownItem, Hint, Card, InlineLink, SearchSelect, Input, EmBreve, DatePicker, ModalFooter, SubpageHeader, Modal, ModalContent, ModalDescription, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, CardContent, CardHeader, CardTitle, CardDescription, Badge, Switch, useFilterDraft, RowActions, PageHeaderActions, FilterPanel, FilterPanelField, SearchField, TooltipProvider, DataTable, ChevronPager, Tooltip, TooltipTrigger, TooltipContent, SegmentedControl, toast, Textarea, ComingSoon } from '@fayz-ai/ui';
5
5
  export { ComingSoon, EmBreve } from '@fayz-ai/ui';
6
- import { Loader2, Download, ChevronDown, FileCode2, FileText, RefreshCw, UserPlus, Gift, AlertTriangle, ChevronRight, Check, Trash2, Plus, KeyRound, Image, UploadCloud, Paperclip, ScanLine, Eye, X, ShieldCheck, ListChecks, FileDown, CheckCircle2, FileCheck2, XCircle, Inbox, Info } from 'lucide-react';
6
+ import { Loader2, Download, ChevronDown, FileCode2, FileText, RefreshCw, UserPlus, Gift, AlertTriangle, ChevronRight, Check, Trash2, Plus, KeyRound, Image, UploadCloud, Paperclip, ScanLine, Eye, X, ShieldCheck, ListChecks, FileDown, CheckCircle2, FileCheck2, XCircle, AlertCircle, RotateCcw, Inbox, Info } from 'lucide-react';
7
7
  import { registerDocumentOpener, PersonLink, getActiveTenantId, useUnitFilter, PageActions, adminNavigateTo, usePermissionOptional, OrderDetailBlock, UNIT_DETAIL_ZONES, ORDER_DETAIL_ZONES, serviceBaseUrl } from '@fayz-ai/admin';
8
8
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
9
  import { FINANCIAL_INVOICE_ZONES } from '@fayz-ai/financial/views/zones';
@@ -8791,7 +8791,9 @@ var SENTENCES2 = {
8791
8791
  justification_too_short: `A justificativa precisa ter pelo menos ${CANCEL_MIN_JUSTIFICATION} caracteres.`,
8792
8792
  cancel_deadline_passed: "O prazo de cancelamento desta nota j\xE1 passou.",
8793
8793
  cancel_refused: "A SEFAZ recusou o cancelamento.",
8794
- plugnotas_refused: "A PlugNotas recusou o envio."
8794
+ plugnotas_refused: "A PlugNotas recusou o envio.",
8795
+ marketplace_intermediary: "Pedidos de marketplace (iFood, 99Food, Keeta) ainda n\xE3o emitem NFC-e por aqui.",
8796
+ not_ours: "Esta nota foi emitida pelo sistema anterior; cancele por l\xE1."
8795
8797
  };
8796
8798
  function noteErrorSentence(error) {
8797
8799
  if (error instanceof EmitterError) {
@@ -9367,13 +9369,16 @@ function OrderNoteCard({ orderId }) {
9367
9369
  };
9368
9370
  }, [processing?.documentId, processing?.status, processing?.cancellation]);
9369
9371
  if (!orderId) return null;
9370
- const live = notes?.find((n) => n.status === "processing" || n.status === "authorized");
9372
+ const current = notes?.[0] ?? null;
9373
+ const earlier = notes?.slice(1) ?? [];
9374
+ const failed = current?.status === "rejected" || current?.status === "error";
9375
+ const canIssue = notes !== null && !error && (!current || failed || current.status === "cancelled");
9371
9376
  const issue = async () => {
9372
9377
  setIssuing(true);
9373
9378
  try {
9374
9379
  const note = await orderNotes.issueNfce(orderId);
9375
9380
  setNotes((list) => [note, ...list ?? []]);
9376
- if (note.status === "rejected") toast.error("A NFC-e foi recusada", { description: note.rejection?.message ?? void 0 });
9381
+ if (note.status === "rejected") toast.error("A NFC-e foi recusada", { description: reasonOf(note) ?? void 0 });
9377
9382
  else toast.success("NFC-e enviada. Aguardando a SEFAZ\u2026");
9378
9383
  } catch (e) {
9379
9384
  toast.error("N\xE3o foi poss\xEDvel emitir a NFC-e", { description: noteErrorSentence(e) });
@@ -9385,7 +9390,7 @@ function OrderNoteCard({ orderId }) {
9385
9390
  OrderDetailBlock,
9386
9391
  {
9387
9392
  title: "Nota fiscal",
9388
- actions: !live && notes !== null && !error ? /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: () => void issue(), disabled: issuing, children: [
9393
+ actions: canIssue && !failed ? /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: () => void issue(), disabled: issuing, children: [
9389
9394
  /* @__PURE__ */ jsx(FileText, { className: "mr-1.5 h-4 w-4" }),
9390
9395
  issuing ? "Emitindo\u2026" : "Emitir NFC-e"
9391
9396
  ] }) : void 0,
@@ -9395,35 +9400,42 @@ function OrderNoteCard({ orderId }) {
9395
9400
  /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: () => void load(), children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" }) })
9396
9401
  ] }),
9397
9402
  !error && notes === null && /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" }),
9398
- !error && notes?.length === 0 && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Nenhuma nota emitida para este pedido." }),
9399
- !error && notes && notes.length > 0 && /* @__PURE__ */ jsx("ul", { className: "space-y-3", children: notes.map((n) => /* @__PURE__ */ jsxs("li", { className: "space-y-1.5 text-sm", children: [
9400
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
9401
- /* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
9402
- n.model === "nfce" ? "NFC-e" : "NF-e",
9403
- n.number ? ` n\xBA ${n.number}` : "",
9404
- n.series ? ` \xB7 s\xE9rie ${n.series}` : ""
9405
- ] }),
9406
- /* @__PURE__ */ jsx(Badge, { variant: "outline", className: tone(n.status), children: n.cancellation === "processing" ? "Cancelando\u2026" : n.uncertain ? "Aguardando a SEFAZ" : NOTE_STATUS_LABEL[n.status] }),
9407
- n.environment === "homologation" && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-muted-foreground", children: "Homologa\xE7\xE3o" })
9403
+ !error && current === null && notes !== null && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Nenhuma nota emitida para este pedido." }),
9404
+ !error && current && current.status === "processing" && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
9405
+ /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
9406
+ current.uncertain ? "Aguardando a resposta da SEFAZ\u2026" : "Enviando \xE0 SEFAZ\u2026"
9407
+ ] }),
9408
+ !error && current && failed && /* @__PURE__ */ jsxs("div", { className: "space-y-2 rounded-md border border-destructive/30 bg-destructive/5 p-3 text-sm", children: [
9409
+ /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-1.5 font-medium text-destructive", children: [
9410
+ /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
9411
+ current.status === "rejected" ? "A SEFAZ recusou a NFC-e" : "N\xE3o foi poss\xEDvel emitir a NFC-e"
9408
9412
  ] }),
9409
- n.accessKey && /* @__PURE__ */ jsx("p", { className: "break-all font-mono text-xs text-muted-foreground", children: n.accessKey.replace(/(\d{4})(?=\d)/g, "$1 ") }),
9410
- (n.status === "rejected" || n.status === "error") && n.rejection?.message && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: n.rejection.message }),
9411
- n.status === "cancelled" && n.cancelReason && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
9412
- "Cancelada: ",
9413
- n.cancelReason
9413
+ reasonOf(current) && /* @__PURE__ */ jsx("p", { children: reasonOf(current) }),
9414
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Nenhuma nota foi emitida: n\xE3o h\xE1 o que cancelar. Corrija o motivo e emita de novo." }),
9415
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: () => void issue(), disabled: issuing, children: [
9416
+ /* @__PURE__ */ jsx(RotateCcw, { className: "mr-1.5 h-4 w-4" }),
9417
+ issuing ? "Emitindo\u2026" : "Emitir novamente"
9418
+ ] }) })
9419
+ ] }),
9420
+ !error && current && (current.status === "authorized" || current.status === "cancelled" || current.status === "substituted") && /* @__PURE__ */ jsx(NoteDetails2, { note: current, onCancel: () => setCancelling(current) }),
9421
+ !error && earlier.length > 0 && /* @__PURE__ */ jsxs("details", { className: "mt-3 text-xs text-muted-foreground", children: [
9422
+ /* @__PURE__ */ jsxs("summary", { className: "cursor-pointer select-none", children: [
9423
+ "Tentativas anteriores (",
9424
+ earlier.length,
9425
+ ")"
9414
9426
  ] }),
9415
- (n.status === "authorized" || n.status === "cancelled") && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
9416
- /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: () => void orderNotes.pdf(n.documentId).then((b) => openFile(b, `nfce-${n.number ?? n.documentId}.pdf`, false)).catch((e) => toast.error("N\xE3o foi poss\xEDvel abrir o DANFE", { description: noteErrorSentence(e) })), children: [
9417
- /* @__PURE__ */ jsx(FileText, { className: "mr-1.5 h-4 w-4" }),
9418
- "DANFE"
9419
- ] }),
9420
- /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: () => void orderNotes.xml(n.documentId).then((b) => openFile(b, `nfce-${n.number ?? n.documentId}.xml`, true)).catch((e) => toast.error("N\xE3o foi poss\xEDvel baixar o XML", { description: noteErrorSentence(e) })), children: [
9421
- /* @__PURE__ */ jsx(Download, { className: "mr-1.5 h-4 w-4" }),
9422
- "XML"
9423
- ] }),
9424
- n.status === "authorized" && !n.cancellation && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", className: "text-destructive", onClick: () => setCancelling(n), children: "Cancelar nota" })
9425
- ] })
9426
- ] }, n.documentId)) }),
9427
+ /* @__PURE__ */ jsx("ul", { className: "mt-2 space-y-1.5", children: earlier.map((n) => /* @__PURE__ */ jsxs("li", { className: "flex flex-wrap items-baseline gap-x-2", children: [
9428
+ /* @__PURE__ */ jsx("span", { children: new Date(n.createdAt).toLocaleString("pt-BR", { dateStyle: "short", timeStyle: "short" }) }),
9429
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: NOTE_STATUS_LABEL[n.status] }),
9430
+ n.status === "authorized" || n.status === "cancelled" ? /* @__PURE__ */ jsxs("span", { children: [
9431
+ "n\xBA ",
9432
+ n.number,
9433
+ " \xB7 s\xE9rie ",
9434
+ n.series
9435
+ ] }) : null,
9436
+ reasonOf(n) && /* @__PURE__ */ jsx("span", { className: "basis-full", children: reasonOf(n) })
9437
+ ] }, n.documentId)) })
9438
+ ] }),
9427
9439
  cancelling && /* @__PURE__ */ jsx(
9428
9440
  CancelDialog,
9429
9441
  {
@@ -9439,6 +9451,48 @@ function OrderNoteCard({ orderId }) {
9439
9451
  }
9440
9452
  );
9441
9453
  }
9454
+ function reasonOf(n) {
9455
+ const raw = n.rejection?.message?.trim();
9456
+ if (!raw) return null;
9457
+ const text = raw.replace(/^rejei[cç][aã]o\s*:?\s*/i, "").trim();
9458
+ return text ? text.charAt(0).toUpperCase() + text.slice(1) : null;
9459
+ }
9460
+ function NoteDetails2({ note, onCancel }) {
9461
+ const at2 = note.authorizedAt ? new Date(note.authorizedAt).toLocaleString("pt-BR", { dateStyle: "short", timeStyle: "short" }) : null;
9462
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5 text-sm", children: [
9463
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
9464
+ /* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
9465
+ note.model === "nfce" ? "NFC-e" : "NF-e",
9466
+ " n\xBA ",
9467
+ note.number,
9468
+ " \xB7 s\xE9rie ",
9469
+ note.series
9470
+ ] }),
9471
+ /* @__PURE__ */ jsx(Badge, { variant: "outline", className: tone(note.status), children: note.cancellation === "processing" ? "Cancelando\u2026" : NOTE_STATUS_LABEL[note.status] }),
9472
+ note.environment === "homologation" && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-muted-foreground", children: "Homologa\xE7\xE3o" })
9473
+ ] }),
9474
+ at2 && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
9475
+ "Autorizada em ",
9476
+ at2
9477
+ ] }),
9478
+ note.accessKey && /* @__PURE__ */ jsx("p", { className: "break-all font-mono text-xs text-muted-foreground", children: note.accessKey.replace(/(\d{4})(?=\d)/g, "$1 ") }),
9479
+ note.status === "cancelled" && note.cancelReason && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
9480
+ "Cancelada: ",
9481
+ note.cancelReason
9482
+ ] }),
9483
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2 pt-1", children: [
9484
+ /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: () => void orderNotes.pdf(note.documentId).then((b) => openFile(b, `nfce-${note.number ?? note.documentId}.pdf`, false)).catch((e) => toast.error("N\xE3o foi poss\xEDvel abrir o DANFE", { description: noteErrorSentence(e) })), children: [
9485
+ /* @__PURE__ */ jsx(FileText, { className: "mr-1.5 h-4 w-4" }),
9486
+ "DANFE"
9487
+ ] }),
9488
+ /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: () => void orderNotes.xml(note.documentId).then((b) => openFile(b, `nfce-${note.number ?? note.documentId}.xml`, true)).catch((e) => toast.error("N\xE3o foi poss\xEDvel baixar o XML", { description: noteErrorSentence(e) })), children: [
9489
+ /* @__PURE__ */ jsx(Download, { className: "mr-1.5 h-4 w-4" }),
9490
+ "XML"
9491
+ ] }),
9492
+ note.status === "authorized" && !note.cancellation && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", className: "text-destructive", onClick: onCancel, children: "Cancelar nota" })
9493
+ ] })
9494
+ ] });
9495
+ }
9442
9496
  function CancelDialog({ note, onClose, onDone }) {
9443
9497
  const [text, setText] = React.useState("");
9444
9498
  const [sending, setSending] = React.useState(false);