@fayz-ai/plugin-fiscal-br 0.13.4 → 0.13.6

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.
Files changed (38) hide show
  1. package/dist/GapScreens-RDPPFZMG.js +3 -0
  2. package/dist/GapScreens-RDPPFZMG.js.map +1 -0
  3. package/dist/InboundNotesPage-R72EC5E4.js +5 -0
  4. package/dist/InboundNotesPage-R72EC5E4.js.map +1 -0
  5. package/dist/InvoiceNotesButton-3SMNHWMQ.js +5 -0
  6. package/dist/InvoiceNotesButton-3SMNHWMQ.js.map +1 -0
  7. package/dist/NoteReconcileView-3KVXZLCG.js +4 -0
  8. package/dist/NoteReconcileView-3KVXZLCG.js.map +1 -0
  9. package/dist/OrderNoteCard-H6P66R4J.js +5 -0
  10. package/dist/OrderNoteCard-H6P66R4J.js.map +1 -0
  11. package/dist/UnitFiscalWidgets-KCHSISBS.js +503 -0
  12. package/dist/UnitFiscalWidgets-KCHSISBS.js.map +1 -0
  13. package/dist/chunk-2GHTB3Z2.js +66 -0
  14. package/dist/chunk-2GHTB3Z2.js.map +1 -0
  15. package/dist/chunk-7NW3EBOQ.js +101 -0
  16. package/dist/chunk-7NW3EBOQ.js.map +1 -0
  17. package/dist/chunk-G7T5YMNY.js +241 -0
  18. package/dist/chunk-G7T5YMNY.js.map +1 -0
  19. package/dist/chunk-JRP5AZFJ.js +64 -0
  20. package/dist/chunk-JRP5AZFJ.js.map +1 -0
  21. package/dist/chunk-OGXYHL3Z.js +590 -0
  22. package/dist/chunk-OGXYHL3Z.js.map +1 -0
  23. package/dist/chunk-RZT2BO6E.js +64 -0
  24. package/dist/chunk-RZT2BO6E.js.map +1 -0
  25. package/dist/chunk-UYGGBJCR.js +2314 -0
  26. package/dist/chunk-UYGGBJCR.js.map +1 -0
  27. package/dist/chunk-WID54RUV.js +498 -0
  28. package/dist/chunk-WID54RUV.js.map +1 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +146 -9391
  31. package/dist/index.js.map +1 -1
  32. package/dist/migrations/main.browser.js +39 -0
  33. package/dist/migrations/main.browser.js.map +1 -0
  34. package/dist/migrations/main.js +4912 -0
  35. package/dist/migrations/main.js.map +1 -0
  36. package/dist/views/InboundNotesPage.d.ts.map +1 -1
  37. package/dist/views/inventoryView.d.ts.map +1 -1
  38. package/package.json +11 -5
@@ -0,0 +1,3 @@
1
+ export { IssuedNotesView, ReturnedNotesView, TaxGroupsView } from './chunk-JRP5AZFJ.js';
2
+ //# sourceMappingURL=GapScreens-RDPPFZMG.js.map
3
+ //# sourceMappingURL=GapScreens-RDPPFZMG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"GapScreens-RDPPFZMG.js"}
@@ -0,0 +1,5 @@
1
+ export { InboundNotesPage, makeInboundNotesRoute } from './chunk-OGXYHL3Z.js';
2
+ import './chunk-UYGGBJCR.js';
3
+ import './chunk-5LI2FDOM.js';
4
+ //# sourceMappingURL=InboundNotesPage-R72EC5E4.js.map
5
+ //# sourceMappingURL=InboundNotesPage-R72EC5E4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"InboundNotesPage-R72EC5E4.js"}
@@ -0,0 +1,5 @@
1
+ export { InvoiceNotesButton } from './chunk-WID54RUV.js';
2
+ import './chunk-RZT2BO6E.js';
3
+ import './chunk-2GHTB3Z2.js';
4
+ //# sourceMappingURL=InvoiceNotesButton-3SMNHWMQ.js.map
5
+ //# sourceMappingURL=InvoiceNotesButton-3SMNHWMQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"InvoiceNotesButton-3SMNHWMQ.js"}
@@ -0,0 +1,4 @@
1
+ export { NoteReconcileView } from './chunk-UYGGBJCR.js';
2
+ import './chunk-5LI2FDOM.js';
3
+ //# sourceMappingURL=NoteReconcileView-3KVXZLCG.js.map
4
+ //# sourceMappingURL=NoteReconcileView-3KVXZLCG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"NoteReconcileView-3KVXZLCG.js"}
@@ -0,0 +1,5 @@
1
+ export { OrderNoteCard } from './chunk-G7T5YMNY.js';
2
+ import './chunk-RZT2BO6E.js';
3
+ import './chunk-2GHTB3Z2.js';
4
+ //# sourceMappingURL=OrderNoteCard-H6P66R4J.js.map
5
+ //# sourceMappingURL=OrderNoteCard-H6P66R4J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"OrderNoteCard-H6P66R4J.js"}
@@ -0,0 +1,503 @@
1
+ import { emitters, GATE_LABELS, emitterErrorSentence } from './chunk-7NW3EBOQ.js';
2
+ import { EmitterError } from './chunk-2GHTB3Z2.js';
3
+ import React from 'react';
4
+ import { Card, CardHeader, CardTitle, Button, CardContent, toast, Badge, Input, CardDescription, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Skeleton, Switch } from '@fayz-ai/ui';
5
+ import { maskCpfCnpj, getSupabaseClientOptional } from '@fayz-ai/core';
6
+ import { adminNavigateTo } from '@fayz-ai/admin';
7
+ import { Info, ShieldCheck, Check, X } from 'lucide-react';
8
+ import { jsx, jsxs } from 'react/jsx-runtime';
9
+
10
+ var COLUMNS = [
11
+ "id",
12
+ "legal_entity_id",
13
+ "nfse_enabled",
14
+ "nfse_production",
15
+ "nfse_national",
16
+ "nfse_service_code_national",
17
+ "nfse_service_code_municipal",
18
+ "nfse_nbs_code",
19
+ "nfse_cnae",
20
+ "nfse_iss_rate",
21
+ "nfse_iss_taxation",
22
+ "nfse_ibscbs_cst",
23
+ "nfse_ibscbs_classification",
24
+ "nfse_simples_regime",
25
+ "nfse_net_value",
26
+ "nfse_additional_info",
27
+ "nfce_enabled",
28
+ "nfce_production",
29
+ "nfce_series",
30
+ "nfce_csc_id",
31
+ "nfce_csc_token_set",
32
+ "nfce_generic_item",
33
+ "certificate_cn",
34
+ "certificate_expires_at",
35
+ "certificate_uploaded_at",
36
+ "dfe_sync_enabled",
37
+ "dfe_last_sync_at",
38
+ "dfe_last_error",
39
+ "provider_synced_at"
40
+ ].join(", ");
41
+ var sb = () => getSupabaseClientOptional();
42
+ async function uploadCertificate(legalEntityId, file, password) {
43
+ try {
44
+ const emitter = await emitters.certificate(legalEntityId, file, password);
45
+ return { cn: emitter.certificate?.holder ?? "", expiresAt: emitter.certificate?.expiresAt ?? "", warning: null };
46
+ } catch (error) {
47
+ throw new Error(emitterErrorSentence(error));
48
+ }
49
+ }
50
+ function useEmitterSettings(legalEntityId) {
51
+ const [row, setRow] = React.useState(null);
52
+ const [loading, setLoading] = React.useState(true);
53
+ React.useEffect(() => {
54
+ if (!legalEntityId) {
55
+ setLoading(false);
56
+ return;
57
+ }
58
+ let alive = true;
59
+ void sb()?.from("plg_fiscalbr_emitter_settings").select(COLUMNS).eq("legal_entity_id", legalEntityId).maybeSingle().then(({ data, error }) => {
60
+ if (!alive) return;
61
+ if (error) toast.error("N\xE3o foi poss\xEDvel ler a configura\xE7\xE3o fiscal", { description: error.message });
62
+ setRow(data ?? {});
63
+ setLoading(false);
64
+ });
65
+ return () => {
66
+ alive = false;
67
+ };
68
+ }, [legalEntityId]);
69
+ const save = React.useCallback(async (tenantId, patch) => {
70
+ if (!legalEntityId) return false;
71
+ const payload = { ...patch, tenant_id: tenantId, legal_entity_id: legalEntityId, updated_at: (/* @__PURE__ */ new Date()).toISOString() };
72
+ const { data, error } = await sb().from("plg_fiscalbr_emitter_settings").upsert(payload, { onConflict: "legal_entity_id" }).select(COLUMNS).single();
73
+ if (error) {
74
+ toast.error("N\xE3o foi poss\xEDvel salvar", { description: error.message });
75
+ return false;
76
+ }
77
+ setRow(data);
78
+ return true;
79
+ }, [legalEntityId]);
80
+ return { row, loading, save, setRow };
81
+ }
82
+ function NeedsLegalEntity({ item, what }) {
83
+ return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(CardContent, { className: "flex flex-col items-start gap-3 py-6", children: [
84
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Falta o CNPJ desta unidade" }),
85
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
86
+ what,
87
+ " pertence \xE0 pessoa jur\xEDdica. Preencha a raz\xE3o social e o CNPJ em Dados da empresa para configurar aqui."
88
+ ] }),
89
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => adminNavigateTo(`/settings/locations/${item.id}/edit`), children: "Preencher CNPJ" })
90
+ ] }) });
91
+ }
92
+ function LoadingCard() {
93
+ return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(CardContent, { className: "space-y-3 py-6", children: [
94
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-48" }),
95
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" }),
96
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" })
97
+ ] }) });
98
+ }
99
+ function ToggleRow({ title, description, checked, onChange, disabled, children }) {
100
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-4", children: [
101
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
102
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: title }),
103
+ description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: description })
104
+ ] }),
105
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
106
+ children,
107
+ /* @__PURE__ */ jsx(Switch, { checked, disabled, onCheckedChange: onChange })
108
+ ] })
109
+ ] });
110
+ }
111
+ function Field({ label, hint, children }) {
112
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
113
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: label }),
114
+ children,
115
+ hint && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: hint })
116
+ ] });
117
+ }
118
+ function SummaryCard({ title, lines, badge, onConfigure }) {
119
+ return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(CardHeader, { className: "flex-row items-start justify-between gap-3 space-y-0", children: [
120
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
121
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: title }),
122
+ /* @__PURE__ */ jsx("dl", { className: "mt-2 grid gap-x-6 gap-y-1 text-sm", style: { gridTemplateColumns: "auto 1fr" }, children: lines.map((l) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
123
+ /* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: l.label }),
124
+ /* @__PURE__ */ jsx("dd", { className: "text-foreground", children: l.value })
125
+ ] }, l.label)) })
126
+ ] }),
127
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
128
+ badge && /* @__PURE__ */ jsx(
129
+ Badge,
130
+ {
131
+ variant: badge.tone === "bad" ? "destructive" : "outline",
132
+ className: badge.tone === "ok" ? "border-emerald-500/40 bg-emerald-500/10 text-emerald-700 dark:text-emerald-400" : badge.tone === "muted" ? "text-muted-foreground" : void 0,
133
+ children: badge.text
134
+ }
135
+ ),
136
+ /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: onConfigure, children: "Configurar" })
137
+ ] })
138
+ ] }) });
139
+ }
140
+ var fmtDateTime = (v) => v ? new Date(v).toLocaleString("pt-BR") : null;
141
+ function UnitCertificateWidget({ item }) {
142
+ const { row, loading, save, setRow } = useEmitterSettings(item?.legalEntityId);
143
+ const [open, setOpen] = React.useState(false);
144
+ const [file, setFile] = React.useState(null);
145
+ const [password, setPassword] = React.useState("");
146
+ const [sending, setSending] = React.useState(false);
147
+ const expiredNow = !!row?.certificate_expires_at && Date.parse(row.certificate_expires_at) < Date.now();
148
+ React.useEffect(() => {
149
+ if (expiredNow) setOpen(true);
150
+ }, [expiredNow]);
151
+ if (!item?.id) return null;
152
+ if (!item.legalEntityId) return /* @__PURE__ */ jsx(NeedsLegalEntity, { item, what: "O certificado digital" });
153
+ if (loading || !row) return /* @__PURE__ */ jsx(LoadingCard, {});
154
+ const expires = row.certificate_expires_at ? new Date(row.certificate_expires_at) : null;
155
+ const expired = expires ? expires.getTime() < Date.now() : false;
156
+ const hasCertificate = !!row.certificate_uploaded_at;
157
+ if (!open) {
158
+ return /* @__PURE__ */ jsx(
159
+ SummaryCard,
160
+ {
161
+ title: "Certificado digital e DANFes",
162
+ lines: [
163
+ { label: "Certificado A1", value: hasCertificate ? [row.certificate_cn, expires ? `v\xE1lido at\xE9 ${expires.toLocaleDateString("pt-BR")}` : null].filter(Boolean).join(" \xB7 ") || "Enviado" : "Nenhum certificado enviado" },
164
+ { label: "Receber DANFes", value: row.dfe_sync_enabled ? `Ligado \xB7 \xFAltima sincroniza\xE7\xE3o ${fmtDateTime(row.dfe_last_sync_at) ?? "nunca"}` : "Desligado" }
165
+ ],
166
+ badge: hasCertificate ? { text: expired ? "Vencido" : "Ativo", tone: expired ? "bad" : "ok" } : { text: "Sem certificado", tone: "muted" },
167
+ onConfigure: () => setOpen(true)
168
+ }
169
+ );
170
+ }
171
+ return /* @__PURE__ */ jsxs(Card, { children: [
172
+ /* @__PURE__ */ jsxs(CardHeader, { className: "flex-row items-start justify-between gap-3 space-y-0", children: [
173
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: "Certificado digital e DANFes" }),
174
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: () => setOpen(false), children: "Fechar" })
175
+ ] }),
176
+ /* @__PURE__ */ jsxs(CardContent, { className: "space-y-5", children: [
177
+ /* @__PURE__ */ jsx(
178
+ ToggleRow,
179
+ {
180
+ title: "Receber DANFes automaticamente",
181
+ description: "Busca por hora as NF-e emitidas contra o CNPJ desta empresa.",
182
+ checked: !!row.dfe_sync_enabled,
183
+ onChange: (v) => void save(item.tenantId, { dfe_sync_enabled: v }).then((ok) => ok && toast.success(v ? "Recep\xE7\xE3o ligada" : "Recep\xE7\xE3o desligada"))
184
+ }
185
+ ),
186
+ /* @__PURE__ */ jsxs("div", { className: "rounded-md border bg-muted/40 p-3 text-sm", children: [
187
+ /* @__PURE__ */ jsxs("p", { className: "mb-1.5 flex items-center gap-1.5 font-medium", children: [
188
+ /* @__PURE__ */ jsx(Info, { className: "h-4 w-4" }),
189
+ " Como funciona"
190
+ ] }),
191
+ /* @__PURE__ */ jsxs("ul", { className: "ml-5 list-disc space-y-1 text-muted-foreground", children: [
192
+ /* @__PURE__ */ jsxs("li", { children: [
193
+ /* @__PURE__ */ jsx("strong", { className: "text-foreground", children: "O que faz:" }),
194
+ " consulta a SEFAZ e lista as NF-e emitidas contra o CNPJ, para voc\xEA aceitar ou rejeitar e gerar entrada de estoque ou conta a pagar."
195
+ ] }),
196
+ /* @__PURE__ */ jsxs("li", { children: [
197
+ /* @__PURE__ */ jsx("strong", { className: "text-foreground", children: "Requer certificado digital A1" }),
198
+ " (.pfx) v\xE1lido desta empresa. O arquivo vai direto ao servi\xE7o fiscal e n\xE3o fica armazenado no nosso sistema."
199
+ ] }),
200
+ /* @__PURE__ */ jsxs("li", { children: [
201
+ /* @__PURE__ */ jsx("strong", { className: "text-foreground", children: "N\xE3o faz manifesta\xE7\xE3o na SEFAZ" }),
202
+ " (ci\xEAncia, confirma\xE7\xE3o, desconhecimento) nem emite NF-e."
203
+ ] })
204
+ ] })
205
+ ] }),
206
+ /* @__PURE__ */ jsxs("div", { className: "rounded-md border p-4 space-y-4", children: [
207
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
208
+ /* @__PURE__ */ jsxs("div", { children: [
209
+ /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-1.5 text-sm font-medium", children: [
210
+ /* @__PURE__ */ jsx(ShieldCheck, { className: "h-4 w-4" }),
211
+ " Certificado digital A1"
212
+ ] }),
213
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: hasCertificate ? [row.certificate_cn, expires ? `v\xE1lido at\xE9 ${expires.toLocaleDateString("pt-BR")}` : null].filter(Boolean).join(" \xB7 ") : "Nenhum certificado enviado" })
214
+ ] }),
215
+ hasCertificate && /* @__PURE__ */ jsx(Badge, { variant: expired ? "destructive" : "secondary", children: expired ? "Vencido" : "Ativo" })
216
+ ] }),
217
+ /* @__PURE__ */ jsx("div", { className: "fz-container", children: /* @__PURE__ */ jsxs("div", { className: "fz-fields fz-fields-2 gap-4", children: [
218
+ /* @__PURE__ */ jsx(Field, { label: "Arquivo (.pfx)", children: /* @__PURE__ */ jsx(
219
+ Input,
220
+ {
221
+ type: "file",
222
+ accept: ".pfx,.p12,application/x-pkcs12",
223
+ "data-testid": "certificate-file",
224
+ onChange: (e) => setFile(e.target.files?.[0] ?? null)
225
+ }
226
+ ) }),
227
+ /* @__PURE__ */ jsx(Field, { label: "Senha do certificado", children: /* @__PURE__ */ jsx(
228
+ Input,
229
+ {
230
+ type: "password",
231
+ autoComplete: "new-password",
232
+ name: "pfx-password",
233
+ value: password,
234
+ "data-testid": "certificate-password",
235
+ onChange: (e) => setPassword(e.target.value)
236
+ }
237
+ ) })
238
+ ] }) }),
239
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
240
+ Button,
241
+ {
242
+ size: "sm",
243
+ "data-testid": "certificate-send",
244
+ disabled: !file || !password || sending,
245
+ onClick: () => {
246
+ if (!file) return;
247
+ setSending(true);
248
+ void uploadCertificate(item.legalEntityId, file, password).then(async (res) => {
249
+ setRow((r) => ({
250
+ ...r ?? {},
251
+ certificate_cn: res.cn,
252
+ certificate_expires_at: res.expiresAt,
253
+ certificate_uploaded_at: (/* @__PURE__ */ new Date()).toISOString(),
254
+ dfe_last_error: res.warning ?? null
255
+ }));
256
+ if (!row.dfe_sync_enabled) await save(item.tenantId, { dfe_sync_enabled: true });
257
+ setFile(null);
258
+ setPassword("");
259
+ if (res.warning) toast.warning("Certificado enviado, com um aviso", { description: res.warning });
260
+ else toast.success(`Certificado enviado \xB7 v\xE1lido at\xE9 ${new Date(res.expiresAt).toLocaleDateString("pt-BR")}`);
261
+ }).catch((e) => toast.error("N\xE3o foi poss\xEDvel enviar o certificado", { description: e.message })).finally(() => setSending(false));
262
+ },
263
+ children: sending ? "Enviando\u2026" : hasCertificate ? "Atualizar certificado" : "Enviar certificado"
264
+ }
265
+ ) }),
266
+ row.dfe_last_error && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: row.dfe_last_error })
267
+ ] }),
268
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
269
+ "\xDAltima sincroniza\xE7\xE3o: ",
270
+ fmtDateTime(row.dfe_last_sync_at) ?? "nunca"
271
+ ] })
272
+ ] })
273
+ ] });
274
+ }
275
+ var ISS_TAXATION = [
276
+ { value: "6", label: "Tribut\xE1vel no munic\xEDpio" },
277
+ { value: "7", label: "Tribut\xE1vel fora do munic\xEDpio" },
278
+ { value: "1", label: "Isento" },
279
+ { value: "2", label: "Imune" }
280
+ ];
281
+ var SIMPLES_REGIME = [
282
+ { value: "auto", label: "Autom\xE1tico (1 \u2014 tudo pelo Simples; excesso \u2192 3)" },
283
+ { value: "1", label: "1 \u2014 Federais e ISS pelo Simples (DAS)" },
284
+ { value: "2", label: "2 \u2014 Federais pelo Simples; ISS pela NFS-e (lei municipal)" },
285
+ { value: "3", label: "3 \u2014 Federais e ISS fora do Simples (sublimite)" }
286
+ ];
287
+ function EnvSelect({ value, onChange, disabled }) {
288
+ return /* @__PURE__ */ jsxs(Select, { value: value ? "prod" : "hom", onValueChange: (v) => onChange(v === "prod"), disabled, children: [
289
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 w-36", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
290
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
291
+ /* @__PURE__ */ jsx(SelectItem, { value: "hom", children: "Homologa\xE7\xE3o" }),
292
+ /* @__PURE__ */ jsx(SelectItem, { value: "prod", children: "Produ\xE7\xE3o" })
293
+ ] })
294
+ ] });
295
+ }
296
+ function UnitFiscalWidget({ item }) {
297
+ const { row, loading, save, setRow } = useEmitterSettings(item?.legalEntityId);
298
+ const [draft, setDraft] = React.useState({});
299
+ const [cscToken, setCscToken] = React.useState("");
300
+ const [saving, setSaving] = React.useState(false);
301
+ const [open, setOpen] = React.useState(false);
302
+ const [registering, setRegistering] = React.useState(false);
303
+ const [missing, setMissing] = React.useState([]);
304
+ React.useEffect(() => {
305
+ if (row) setDraft(row);
306
+ }, [row]);
307
+ if (!item?.id) return null;
308
+ if (!item.legalEntityId) return /* @__PURE__ */ jsx(NeedsLegalEntity, { item, what: "A emiss\xE3o fiscal" });
309
+ if (loading || !row) return /* @__PURE__ */ jsx(LoadingCard, {});
310
+ const set = (patch) => setDraft((d) => ({ ...d, ...patch }));
311
+ const generic = draft.nfce_generic_item ?? {};
312
+ const setGeneric = (patch) => set({ nfce_generic_item: { ...generic, ...patch } });
313
+ const isSimples = (item.taxRegime ?? "").startsWith("simples");
314
+ const checks = [
315
+ { ok: !!row.certificate_uploaded_at && !(row.certificate_expires_at && Date.parse(row.certificate_expires_at) < Date.now()), label: "Certificado A1 v\xE1lido" },
316
+ // Only what the switched-on documents need: NFS-e off does not block a restaurant that issues NFC-e.
317
+ ...draft.nfse_enabled ? [
318
+ { ok: !!draft.nfse_service_code_national, label: "C\xF3digo de tributa\xE7\xE3o do servi\xE7o" },
319
+ { ok: draft.nfse_iss_rate != null && draft.nfse_iss_rate !== "", label: "Al\xEDquota de ISS" }
320
+ ] : [],
321
+ ...draft.nfce_enabled ? [
322
+ { ok: !!item.stateRegistration && !!draft.nfce_csc_id && (!!row.nfce_csc_token_set || !!cscToken), label: "IE + CSC (NFC-e)" }
323
+ ] : [],
324
+ { ok: !!row.provider_synced_at, label: "Empresa registrada para emitir" }
325
+ ];
326
+ const ready = (draft.nfse_enabled || draft.nfce_enabled) && checks.every((c) => c.ok);
327
+ const saveNfce = async () => {
328
+ try {
329
+ await emitters.save(item.legalEntityId, {
330
+ nfce: {
331
+ enabled: !!draft.nfce_enabled,
332
+ production: !!draft.nfce_production,
333
+ series: draft.nfce_series ? Number(draft.nfce_series) : null,
334
+ cscId: draft.nfce_csc_id ? String(draft.nfce_csc_id).trim() : null,
335
+ ...cscToken ? { cscToken } : {}
336
+ }
337
+ });
338
+ return true;
339
+ } catch (error) {
340
+ toast.error("N\xE3o foi poss\xEDvel salvar a NFC-e", { description: emitterErrorSentence(error) });
341
+ return false;
342
+ }
343
+ };
344
+ const onSave = async () => {
345
+ setSaving(true);
346
+ if (!await saveNfce()) {
347
+ setSaving(false);
348
+ return;
349
+ }
350
+ const {
351
+ id: _id,
352
+ legal_entity_id: _le,
353
+ nfce_csc_token_set: _t,
354
+ certificate_cn: _cn,
355
+ certificate_expires_at: _e,
356
+ certificate_uploaded_at: _u,
357
+ dfe_last_sync_at: _d,
358
+ provider_synced_at: _p,
359
+ nfce_enabled: _ne,
360
+ nfce_production: _np,
361
+ nfce_series: _ns,
362
+ nfce_csc_id: _nc,
363
+ ...patch
364
+ } = draft;
365
+ const issRate = patch.nfse_iss_rate === "" || patch.nfse_iss_rate == null ? null : Number(String(patch.nfse_iss_rate).replace(",", "."));
366
+ const ok = await save(item.tenantId, {
367
+ ...patch,
368
+ nfse_iss_rate: Number.isFinite(issRate) ? issRate : null,
369
+ nfse_iss_taxation: patch.nfse_iss_taxation ? Number(patch.nfse_iss_taxation) : null,
370
+ nfse_simples_regime: patch.nfse_simples_regime && patch.nfse_simples_regime !== "auto" ? Number(patch.nfse_simples_regime) : null
371
+ });
372
+ setSaving(false);
373
+ if (ok) {
374
+ setCscToken("");
375
+ setOpen(false);
376
+ toast.success("Configura\xE7\xE3o fiscal salva");
377
+ }
378
+ };
379
+ const onRegister = async () => {
380
+ setRegistering(true);
381
+ setMissing([]);
382
+ try {
383
+ if (!await saveNfce()) return;
384
+ const after = await emitters.register(item.legalEntityId);
385
+ setRow((r) => ({ ...r ?? {}, provider_synced_at: after.providerSyncedAt }));
386
+ toast.success("Empresa cadastrada na PlugNotas");
387
+ } catch (error) {
388
+ if (error instanceof EmitterError) setMissing(error.gates.filter((g) => !g.ok).map((g) => GATE_LABELS[g.id] ?? g.id));
389
+ toast.error("N\xE3o foi poss\xEDvel cadastrar na PlugNotas", { description: emitterErrorSentence(error) });
390
+ } finally {
391
+ setRegistering(false);
392
+ }
393
+ };
394
+ if (!open) {
395
+ const env = (prod) => prod ? "Produ\xE7\xE3o" : "Homologa\xE7\xE3o";
396
+ return /* @__PURE__ */ jsx(
397
+ SummaryCard,
398
+ {
399
+ title: "Emiss\xE3o fiscal (NFS-e / NFC-e)",
400
+ lines: [
401
+ { label: "NFS-e", value: row.nfse_enabled ? `Ligada \xB7 ${env(!!row.nfse_production)}` : "Desligada" },
402
+ { label: "NFC-e", value: row.nfce_enabled ? `Ligada \xB7 ${env(!!row.nfce_production)}${row.nfce_series ? ` \xB7 s\xE9rie ${row.nfce_series}` : ""}` : "Desligada" }
403
+ ],
404
+ badge: ready ? { text: "Pronto para emitir", tone: "ok" } : { text: "Configura\xE7\xE3o incompleta", tone: "muted" },
405
+ onConfigure: () => setOpen(true)
406
+ }
407
+ );
408
+ }
409
+ return /* @__PURE__ */ jsxs(Card, { children: [
410
+ /* @__PURE__ */ jsxs(CardHeader, { className: "flex-row items-start justify-between gap-3 space-y-0", children: [
411
+ /* @__PURE__ */ jsxs("div", { children: [
412
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: "Emiss\xE3o fiscal (NFS-e / NFC-e)" }),
413
+ /* @__PURE__ */ jsxs(CardDescription, { children: [
414
+ item.legalName ?? "Pessoa jur\xEDdica",
415
+ item.cnpj ? ` \xB7 CNPJ ${maskCpfCnpj(item.cnpj)}` : ""
416
+ ] })
417
+ ] }),
418
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
419
+ /* @__PURE__ */ jsx(Badge, { variant: ready ? "default" : "secondary", children: ready ? "Pronto para emitir" : "Configura\xE7\xE3o incompleta" }),
420
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: () => {
421
+ setDraft(row);
422
+ setCscToken("");
423
+ setOpen(false);
424
+ }, children: "Cancelar" })
425
+ ] })
426
+ ] }),
427
+ /* @__PURE__ */ jsxs(CardContent, { className: "space-y-5", children: [
428
+ /* @__PURE__ */ jsxs("section", { className: "space-y-4 rounded-md border p-4", children: [
429
+ /* @__PURE__ */ jsx(
430
+ ToggleRow,
431
+ {
432
+ title: "NFS-e \u2014 Nota de Servi\xE7o",
433
+ description: "Padr\xE3o nacional (RJ, Vit\xF3ria e demais aderentes)",
434
+ checked: !!draft.nfse_enabled,
435
+ onChange: (v) => set({ nfse_enabled: v }),
436
+ children: /* @__PURE__ */ jsx(EnvSelect, { value: !!draft.nfse_production, onChange: (v) => set({ nfse_production: v }), disabled: !draft.nfse_enabled })
437
+ }
438
+ ),
439
+ draft.nfse_enabled && /* @__PURE__ */ jsxs("div", { className: "fz-container space-y-4", children: [
440
+ /* @__PURE__ */ jsxs("div", { className: "fz-fields fz-fields-2 gap-4", children: [
441
+ /* @__PURE__ */ jsx(Field, { label: "C\xF3d. tributa\xE7\xE3o nacional", children: /* @__PURE__ */ jsx(Input, { value: draft.nfse_service_code_national ?? "", placeholder: "ex.: 06.02.01", onChange: (e) => set({ nfse_service_code_national: e.target.value }) }) }),
442
+ /* @__PURE__ */ jsx(Field, { label: "C\xF3d. tributa\xE7\xE3o municipal", children: /* @__PURE__ */ jsx(Input, { value: draft.nfse_service_code_municipal ?? "", placeholder: "ex.: 001", onChange: (e) => set({ nfse_service_code_municipal: e.target.value }) }) }),
443
+ /* @__PURE__ */ jsx(Field, { label: "C\xF3digo NBS", children: /* @__PURE__ */ jsx(Input, { value: draft.nfse_nbs_code ?? "", placeholder: "ex.: 1.2602.90.00", onChange: (e) => set({ nfse_nbs_code: e.target.value }) }) }),
444
+ /* @__PURE__ */ jsx(Field, { label: "CNAE do servi\xE7o", children: /* @__PURE__ */ jsx(Input, { value: draft.nfse_cnae ?? "", placeholder: "ex.: 9602-5/02", onChange: (e) => set({ nfse_cnae: e.target.value }) }) }),
445
+ /* @__PURE__ */ jsx(Field, { label: "Al\xEDquota ISS (%)", children: /* @__PURE__ */ jsx(Input, { inputMode: "decimal", value: draft.nfse_iss_rate ?? "", placeholder: "ex.: 5", onChange: (e) => set({ nfse_iss_rate: e.target.value }) }) }),
446
+ /* @__PURE__ */ jsx(Field, { label: "Tributa\xE7\xE3o ISS", children: /* @__PURE__ */ jsxs(Select, { value: draft.nfse_iss_taxation != null ? String(draft.nfse_iss_taxation) : void 0, onValueChange: (v) => set({ nfse_iss_taxation: v }), children: [
447
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Selecione" }) }),
448
+ /* @__PURE__ */ jsx(SelectContent, { children: ISS_TAXATION.map((o) => /* @__PURE__ */ jsx(SelectItem, { value: o.value, children: o.label }, o.value)) })
449
+ ] }) }),
450
+ /* @__PURE__ */ jsx(Field, { label: "IBS/CBS \u2014 CST", children: /* @__PURE__ */ jsx(Input, { value: draft.nfse_ibscbs_cst ?? "", placeholder: "ex.: 000", onChange: (e) => set({ nfse_ibscbs_cst: e.target.value }) }) }),
451
+ /* @__PURE__ */ jsx(Field, { label: "IBS/CBS \u2014 Classifica\xE7\xE3o", children: /* @__PURE__ */ jsx(Input, { value: draft.nfse_ibscbs_classification ?? "", placeholder: "ex.: 000001", onChange: (e) => set({ nfse_ibscbs_classification: e.target.value }) }) }),
452
+ isSimples && /* @__PURE__ */ jsx(Field, { label: "Apura\xE7\xE3o dos tributos no Simples", children: /* @__PURE__ */ jsxs(Select, { value: draft.nfse_simples_regime != null ? String(draft.nfse_simples_regime) : "auto", onValueChange: (v) => set({ nfse_simples_regime: v }), children: [
453
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }),
454
+ /* @__PURE__ */ jsx(SelectContent, { children: SIMPLES_REGIME.map((o) => /* @__PURE__ */ jsx(SelectItem, { value: o.value, children: o.label }, o.value)) })
455
+ ] }) })
456
+ ] }),
457
+ /* @__PURE__ */ jsx(ToggleRow, { title: "Emitir pelo valor l\xEDquido", checked: !!draft.nfse_net_value, onChange: (v) => set({ nfse_net_value: v }) }),
458
+ /* @__PURE__ */ jsx(Field, { label: "Informa\xE7\xF5es complementares da nota", children: /* @__PURE__ */ jsx(Input, { value: draft.nfse_additional_info ?? "", placeholder: "ex.: Totais Aproximados dos Tributos cfe. Lei n\xBA 12.741/2012\u2026", onChange: (e) => set({ nfse_additional_info: e.target.value }) }) })
459
+ ] })
460
+ ] }),
461
+ /* @__PURE__ */ jsxs("section", { className: "space-y-4 rounded-md border p-4", children: [
462
+ /* @__PURE__ */ jsx(
463
+ ToggleRow,
464
+ {
465
+ title: "NFC-e \u2014 Cupom do Consumidor",
466
+ description: "Produtos / comanda",
467
+ checked: !!draft.nfce_enabled,
468
+ onChange: (v) => set({ nfce_enabled: v }),
469
+ children: /* @__PURE__ */ jsx(EnvSelect, { value: !!draft.nfce_production, onChange: (v) => set({ nfce_production: v }), disabled: !draft.nfce_enabled })
470
+ }
471
+ ),
472
+ draft.nfce_enabled && /* @__PURE__ */ jsxs("div", { className: "fz-container space-y-4", children: [
473
+ /* @__PURE__ */ jsxs("div", { className: "fz-fields fz-fields-2 gap-4", children: [
474
+ /* @__PURE__ */ jsx(Field, { label: "S\xE9rie", children: /* @__PURE__ */ jsx(Input, { inputMode: "numeric", value: draft.nfce_series ?? "", onChange: (e) => set({ nfce_series: e.target.value.replace(/\D/g, "") }) }) }),
475
+ /* @__PURE__ */ jsx(Field, { label: "CSC \u2014 ID", children: /* @__PURE__ */ jsx(Input, { value: draft.nfce_csc_id ?? "", onChange: (e) => set({ nfce_csc_id: e.target.value }) }) })
476
+ ] }),
477
+ /* @__PURE__ */ jsx(Field, { label: "CSC \u2014 Token", hint: "O CSC (id num\xE9rico + token) \xE9 gerado no portal da SEFAZ do estado \u2014 n\xE3o \xE9 o login de nenhum sistema.", children: /* @__PURE__ */ jsx(Input, { type: "password", value: cscToken, placeholder: row.nfce_csc_token_set ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022 (configurado \u2014 digite para trocar)" : "", onChange: (e) => setCscToken(e.target.value) }) }),
478
+ /* @__PURE__ */ jsxs("div", { className: "fz-fields fz-fields-2 gap-4", children: [
479
+ /* @__PURE__ */ jsx(Field, { label: "Item gen\xE9rico \u2014 NCM", children: /* @__PURE__ */ jsx(Input, { value: generic.ncm ?? "", onChange: (e) => setGeneric({ ncm: e.target.value }) }) }),
480
+ /* @__PURE__ */ jsx(Field, { label: "Item gen\xE9rico \u2014 CFOP", children: /* @__PURE__ */ jsx(Input, { value: generic.cfop ?? "", onChange: (e) => setGeneric({ cfop: e.target.value }) }) }),
481
+ /* @__PURE__ */ jsx(Field, { label: "Item gen\xE9rico \u2014 CSOSN/CST", children: /* @__PURE__ */ jsx(Input, { value: generic.csosn ?? "", onChange: (e) => setGeneric({ csosn: e.target.value }) }) })
482
+ ] })
483
+ ] })
484
+ ] }),
485
+ /* @__PURE__ */ jsx("ul", { className: "flex flex-wrap gap-2", children: checks.map((c) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: c.ok ? "gap-1 border-emerald-500/40 text-emerald-700 dark:text-emerald-400" : "gap-1 text-muted-foreground", children: [
486
+ c.ok ? /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(X, { className: "h-3 w-3" }),
487
+ c.label
488
+ ] }) }, c.label)) }),
489
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-end gap-3", children: [
490
+ missing.length > 0 && /* @__PURE__ */ jsxs("p", { className: "mr-auto text-xs text-destructive", children: [
491
+ "Falta: ",
492
+ missing.join(", ")
493
+ ] }),
494
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => void onRegister(), disabled: saving || registering, children: registering ? "Cadastrando\u2026" : row.provider_synced_at ? "Atualizar na PlugNotas" : "Cadastrar na PlugNotas" }),
495
+ /* @__PURE__ */ jsx(Button, { onClick: () => void onSave(), disabled: saving || registering, children: saving ? "Salvando\u2026" : "Salvar configura\xE7\xE3o" })
496
+ ] })
497
+ ] })
498
+ ] });
499
+ }
500
+
501
+ export { UnitCertificateWidget, UnitFiscalWidget };
502
+ //# sourceMappingURL=UnitFiscalWidgets-KCHSISBS.js.map
503
+ //# sourceMappingURL=UnitFiscalWidgets-KCHSISBS.js.map