@fayz-ai/plugin-financial 0.26.4 → 0.27.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/{FinancialPage-NZFBBVY4.js → FinancialPage-HIVSEGJE.js} +3 -3
- package/dist/{FinancialPage-NZFBBVY4.js.map → FinancialPage-HIVSEGJE.js.map} +1 -1
- package/dist/{chunk-K37Q7SKX.js → chunk-IQHWMVUM.js} +112 -13
- package/dist/chunk-IQHWMVUM.js.map +1 -0
- package/dist/data/registries.d.ts.map +1 -1
- package/dist/index.js +122 -15
- package/dist/index.js.map +1 -1
- package/dist/locales/en.d.ts.map +1 -1
- package/dist/locales/pt-BR.d.ts.map +1 -1
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/main.browser.js +2 -1
- package/dist/migrations/main.browser.js.map +1 -1
- package/dist/migrations/main.js +286 -2
- package/dist/migrations/main.js.map +1 -1
- package/dist/views/InvoiceDetailView.d.ts.map +1 -1
- package/dist/views/InvoiceFormView.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/chunk-K37Q7SKX.js.map +0 -1
|
@@ -7,10 +7,10 @@ import React13__default, { useState, useRef, useEffect, useMemo } from 'react';
|
|
|
7
7
|
import { useTranslation, createPendingCommand, useUnitMode, useDataChanged, useActiveUnitId, appHref, resolveCurrency, getSupabaseClientOptional } from '@fayz-ai/core';
|
|
8
8
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
9
|
import { Landmark, CreditCard, Banknote, TriangleAlert, Loader2, Check, X, Paperclip, Image, FileText, ChevronRight, UploadCloud, ArrowLeft, ChevronLeft, ExternalLink, Ban, CircleDashed, CircleAlert, CircleCheckBig, CircleEllipsis, Pencil, Package, PackagePlus, Receipt, Gift, Briefcase, CalendarDays, DollarSign, LayoutList, Layers, Ticket, FileCheck, ArrowRightLeft, QrCode, Undo2, Building2, MoreVertical, Calendar, User, Wallet, Unlink, Trash2, ChevronDown, Search, Settings } from 'lucide-react';
|
|
10
|
-
import { INLINE_LINK_TONE, SearchSelect, Button, useInModalTaskHost, ModalTask, Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, ModalFooter, toast, Skeleton, SubpageHeader, DatePicker, Checkbox, Textarea, ChoiceSelect, useSaveBar, tourAnchor,
|
|
10
|
+
import { INLINE_LINK_TONE, SearchSelect, Button, useInModalTaskHost, ModalTask, Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, ModalFooter, toast, Skeleton, SubpageHeader, DatePicker, Checkbox, Textarea, ChoiceSelect, useSaveBar, tourAnchor, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Input, SegmentedControl, CurrencyInput, Badge, Hint, Popover, PopoverTrigger, PopoverContent } from '@fayz-ai/ui';
|
|
11
11
|
import { createPortal } from 'react-dom';
|
|
12
12
|
import { createIdempotencyKey } from '@fayz-ai/financial/data/idempotency';
|
|
13
|
-
import { useCurrency, useUnitStore, OrderDetailSkeleton, WidgetSlot, PageActions, OrderDetailBlock, TagChip, OrderDetailView, PersonLink, CurrencyScope, useUnitFilter, usePermissionOptional, adminNavigateTo, createArchetypeLookup, useLimitGuard, useLookupCreate, OrderFormSkeleton, OrderFormBlock, TagsField, OrderFormView, OrderFormItemsCard, OrderFormItemRow, OrderFormAddItemStep, RecordMetaFooter, invalidateLimit, useHouseCurrency } from '@fayz-ai/admin';
|
|
13
|
+
import { useCurrency, useUnitStore, OrderDetailSkeleton, WidgetSlot, PageActions, OrderDetailBlock, TagChip, OrderDetailView, PersonLink, CurrencyScope, useUnitFilter, usePermissionOptional, adminNavigateTo, createArchetypeLookup, listPickablePriceTables, withPriceTable, useLimitGuard, useLookupCreate, OrderFormSkeleton, OrderFormBlock, initialPriceTableId, TagsField, OrderFormView, OrderFormItemsCard, OrderFormItemRow, OrderFormAddItemStep, RecordMetaFooter, quotePriceTable, invalidateLimit, useHouseCurrency } from '@fayz-ai/admin';
|
|
14
14
|
import { T } from '@fayz-ai/financial/data/tables';
|
|
15
15
|
import { groupPaymentsByBill, reversiblePayments } from '@fayz-ai/financial/domain/movement';
|
|
16
16
|
import { describePayment, paymentHolderId } from '@fayz-ai/financial/domain/payment-method';
|
|
@@ -2512,9 +2512,19 @@ function InvoiceDetailView({ invoiceId, direction, onBack, onEdit, backLabel, em
|
|
|
2512
2512
|
itemsLabel: t("financial.invoice.items"),
|
|
2513
2513
|
totals: totalRows,
|
|
2514
2514
|
totalsLabel: t("financial.invoice.payment"),
|
|
2515
|
-
mainSections: (
|
|
2516
|
-
|
|
2517
|
-
|
|
2515
|
+
mainSections: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2516
|
+
/* @__PURE__ */ jsx(
|
|
2517
|
+
WidgetSlot,
|
|
2518
|
+
{
|
|
2519
|
+
zone: FINANCIAL_INVOICE_ZONES.notices,
|
|
2520
|
+
invoiceId: invoice.id,
|
|
2521
|
+
direction,
|
|
2522
|
+
cancelled,
|
|
2523
|
+
onChanged: () => {
|
|
2524
|
+
void loadData();
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
),
|
|
2518
2528
|
/* @__PURE__ */ jsx(
|
|
2519
2529
|
OrderDetailBlock,
|
|
2520
2530
|
{
|
|
@@ -2660,7 +2670,7 @@ function InvoiceDetailView({ invoiceId, direction, onBack, onEdit, backLabel, em
|
|
|
2660
2670
|
] })
|
|
2661
2671
|
}
|
|
2662
2672
|
)
|
|
2663
|
-
),
|
|
2673
|
+
] }),
|
|
2664
2674
|
extraSections: sideBlocks
|
|
2665
2675
|
}
|
|
2666
2676
|
),
|
|
@@ -3014,6 +3024,7 @@ var formId = 1;
|
|
|
3014
3024
|
function fid() {
|
|
3015
3025
|
return `f${formId++}`;
|
|
3016
3026
|
}
|
|
3027
|
+
var NO_PRICE_TABLE = "__none__";
|
|
3017
3028
|
function sourceMeta(inst) {
|
|
3018
3029
|
return {
|
|
3019
3030
|
payMethodTypeId: inst.payMethodTypeId || null,
|
|
@@ -3118,7 +3129,30 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
3118
3129
|
}
|
|
3119
3130
|
};
|
|
3120
3131
|
}, [giftCardsEnabled, provider, t]);
|
|
3121
|
-
const
|
|
3132
|
+
const [priceTables, setPriceTables] = useState([]);
|
|
3133
|
+
const [priceTableId, setPriceTableId] = useState();
|
|
3134
|
+
const [savedPriceTableId, setSavedPriceTableId] = useState();
|
|
3135
|
+
useEffect(() => {
|
|
3136
|
+
if (direction !== "credit") return;
|
|
3137
|
+
let alive = true;
|
|
3138
|
+
listPickablePriceTables().then((tables) => {
|
|
3139
|
+
if (alive) setPriceTables(tables);
|
|
3140
|
+
}).catch(() => {
|
|
3141
|
+
});
|
|
3142
|
+
return () => {
|
|
3143
|
+
alive = false;
|
|
3144
|
+
};
|
|
3145
|
+
}, [direction]);
|
|
3146
|
+
const pickedTable = priceTables.find((pt) => pt.id === priceTableId);
|
|
3147
|
+
const entityLookups = useMemo(() => {
|
|
3148
|
+
const base = giftCardLookup ? { ...config.entityLookups, gift_card: giftCardLookup } : config.entityLookups ?? {};
|
|
3149
|
+
if (!pickedTable) return base;
|
|
3150
|
+
return {
|
|
3151
|
+
...base,
|
|
3152
|
+
...base.product ? { product: withPriceTable(base.product, pickedTable.id, { kinds: ["good"] }) } : {},
|
|
3153
|
+
...base.service ? { service: withPriceTable(base.service, pickedTable.id, { kinds: ["service"] }) } : {}
|
|
3154
|
+
};
|
|
3155
|
+
}, [config.entityLookups, giftCardLookup, pickedTable]);
|
|
3122
3156
|
const translatedItemTypes = React13__default.useMemo(
|
|
3123
3157
|
() => itemTypesRaw.map((tp) => {
|
|
3124
3158
|
const traduzido = t(`financial.itemType.${tp.value}`);
|
|
@@ -3180,6 +3214,7 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
3180
3214
|
);
|
|
3181
3215
|
const [savedItemsKey, setSavedItemsKey] = useState("");
|
|
3182
3216
|
const [loaded, setLoaded] = useState(!editId);
|
|
3217
|
+
const [reloadTick, setReloadTick] = useState(0);
|
|
3183
3218
|
const [loading, setLoading] = useState(!!editId);
|
|
3184
3219
|
const [contactName, setContactName] = useState("");
|
|
3185
3220
|
const [contactId, setContactId] = useState();
|
|
@@ -3274,13 +3309,15 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
3274
3309
|
}, [menuOpen]);
|
|
3275
3310
|
const [recordMeta, setRecordMeta] = useState(null);
|
|
3276
3311
|
useEffect(() => {
|
|
3277
|
-
if (!editId || loaded) return;
|
|
3312
|
+
if (!editId || loaded && reloadTick === 0) return;
|
|
3278
3313
|
setLoading(true);
|
|
3279
3314
|
(async () => {
|
|
3280
3315
|
const invoice = await provider.getInvoiceById(editId);
|
|
3281
3316
|
if (!invoice) return;
|
|
3282
3317
|
setContactName(invoice.contactName ?? "");
|
|
3283
3318
|
setContactId(invoice.contactId);
|
|
3319
|
+
setPriceTableId(invoice.priceTableId ?? void 0);
|
|
3320
|
+
setSavedPriceTableId(invoice.priceTableId ?? void 0);
|
|
3284
3321
|
if (invoice.contactId) {
|
|
3285
3322
|
try {
|
|
3286
3323
|
const contact = await contactLookup.getById(invoice.contactId);
|
|
@@ -3359,7 +3396,7 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
3359
3396
|
setLoaded(true);
|
|
3360
3397
|
setLoading(false);
|
|
3361
3398
|
})();
|
|
3362
|
-
}, [editId]);
|
|
3399
|
+
}, [editId, reloadTick]);
|
|
3363
3400
|
const totalAmount = items.reduce((sum, it) => {
|
|
3364
3401
|
return sum + it.quantity * it.unitPrice - (it.discount ?? 0) + (it.surcharge ?? 0);
|
|
3365
3402
|
}, 0);
|
|
@@ -3457,6 +3494,27 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
3457
3494
|
setItems((current) => current.flatMap((it) => it._id === item._id ? novas : [it]));
|
|
3458
3495
|
setExpandedItemId(null);
|
|
3459
3496
|
}
|
|
3497
|
+
async function changePriceTable(next) {
|
|
3498
|
+
setPriceTableId(next);
|
|
3499
|
+
const table = priceTables.find((pt) => pt.id === next);
|
|
3500
|
+
if (!table || !canEditItems) return;
|
|
3501
|
+
const priced = items.filter((it) => it.referenceId && (it.itemKind === "product" || it.itemKind === "service"));
|
|
3502
|
+
if (priced.length === 0) return;
|
|
3503
|
+
try {
|
|
3504
|
+
const quotes = await quotePriceTable(table.id, priced.map((it) => ({ productId: it.referenceId, quantity: it.quantity })));
|
|
3505
|
+
const prices = /* @__PURE__ */ new Map();
|
|
3506
|
+
priced.forEach((it, i) => {
|
|
3507
|
+
const q = quotes[i];
|
|
3508
|
+
if (q) prices.set(it._id, q.price);
|
|
3509
|
+
});
|
|
3510
|
+
setItems((current) => current.map((it) => prices.has(it._id) ? { ...it, unitPrice: prices.get(it._id) } : it));
|
|
3511
|
+
if (prices.size > 0) toast.success(t("financial.invoiceForm.priceTableRepriced", { count: prices.size, table: table.name }));
|
|
3512
|
+
const missing = priced.length - prices.size;
|
|
3513
|
+
if (missing > 0) toast.warning(t("financial.invoiceForm.priceTableMissing", { count: missing, table: table.name }));
|
|
3514
|
+
} catch (err) {
|
|
3515
|
+
toast.error(err instanceof Error ? err.message : String(err));
|
|
3516
|
+
}
|
|
3517
|
+
}
|
|
3460
3518
|
function removeItem(id) {
|
|
3461
3519
|
setItems((current) => current.filter((it) => it._id !== id));
|
|
3462
3520
|
}
|
|
@@ -3614,7 +3672,8 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
3614
3672
|
// 110 abriu a CONTRAPARTE, com o mesmo limite: quem digita seis
|
|
3615
3673
|
// contas seguidas escolhe o fornecedor da linha de cima na quarta, e
|
|
3616
3674
|
// até aqui a correção era cancelar a conta e lançar outra.
|
|
3617
|
-
...contactId !== savedContactId ? { contactId, contactName } : {}
|
|
3675
|
+
...contactId !== savedContactId ? { contactId, contactName } : {},
|
|
3676
|
+
...priceTableId !== savedPriceTableId ? { priceTableId: priceTableId ?? null } : {}
|
|
3618
3677
|
});
|
|
3619
3678
|
const shapeChanged = itemsDirty || installments.length !== savedMovements.length || installments.some((inst, i) => Math.round(inst.amount * 100) !== Math.round((savedMovements[i]?.amount ?? 0) * 100));
|
|
3620
3679
|
if (canReschedule && provider.rescheduleInvoice && shapeChanged) {
|
|
@@ -3649,6 +3708,7 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
3649
3708
|
contactName: contactName || void 0,
|
|
3650
3709
|
unitId: unitId || void 0,
|
|
3651
3710
|
currency: documentCurrency,
|
|
3711
|
+
...priceTableId ? { priceTableId } : {},
|
|
3652
3712
|
tags,
|
|
3653
3713
|
fiscalNumber: fiscalNumber || void 0,
|
|
3654
3714
|
observations: observations || void 0,
|
|
@@ -3722,6 +3782,7 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
3722
3782
|
const fields = {
|
|
3723
3783
|
contactName,
|
|
3724
3784
|
contactId,
|
|
3785
|
+
priceTableId,
|
|
3725
3786
|
unitId,
|
|
3726
3787
|
invoiceDate,
|
|
3727
3788
|
fiscalNumber,
|
|
@@ -3966,6 +4027,11 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
3966
4027
|
setContactId(id || void 0);
|
|
3967
4028
|
setContactName(opt?.label ?? "");
|
|
3968
4029
|
setPendingContact(null);
|
|
4030
|
+
if (id && priceTables.length > 0) {
|
|
4031
|
+
const result = opt?.data ?? {};
|
|
4032
|
+
const next = initialPriceTableId(priceTables, result.data?.price_table_id);
|
|
4033
|
+
if (next !== priceTableId) void changePriceTable(next);
|
|
4034
|
+
}
|
|
3969
4035
|
const request = ++accountingPolicyRequest.current;
|
|
3970
4036
|
if (!id) {
|
|
3971
4037
|
setCounterpartyAccounting({ allowedAccountIds: [], limitAccounts: false, addItemsAutomatically: false });
|
|
@@ -4016,6 +4082,26 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
4016
4082
|
] }),
|
|
4017
4083
|
contactCreate.modal
|
|
4018
4084
|
] }) });
|
|
4085
|
+
const priceTableSection = direction === "credit" && priceTables.length > 0 ? /* @__PURE__ */ jsxs(OrderFormBlock, { title: t("financial.invoiceForm.priceTable"), children: [
|
|
4086
|
+
/* @__PURE__ */ jsxs(
|
|
4087
|
+
Select,
|
|
4088
|
+
{
|
|
4089
|
+
value: priceTableId ?? NO_PRICE_TABLE,
|
|
4090
|
+
onValueChange: (v) => {
|
|
4091
|
+
void changePriceTable(v === NO_PRICE_TABLE ? void 0 : v);
|
|
4092
|
+
},
|
|
4093
|
+
disabled: !canEditItems,
|
|
4094
|
+
children: [
|
|
4095
|
+
/* @__PURE__ */ jsx(SelectTrigger, { "aria-label": t("financial.invoiceForm.priceTable"), "data-testid": "invoice-price-table", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("financial.invoiceForm.priceTableNone") }) }),
|
|
4096
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
4097
|
+
/* @__PURE__ */ jsx(SelectItem, { value: NO_PRICE_TABLE, children: t("financial.invoiceForm.priceTableNone") }),
|
|
4098
|
+
priceTables.map((pt) => /* @__PURE__ */ jsx(SelectItem, { value: pt.id, children: pt.name }, pt.id))
|
|
4099
|
+
] })
|
|
4100
|
+
]
|
|
4101
|
+
}
|
|
4102
|
+
),
|
|
4103
|
+
pickedTable && /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-xs text-muted-foreground", children: t("financial.invoiceForm.priceTableHint") })
|
|
4104
|
+
] }) : null;
|
|
4019
4105
|
const sideSections = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4020
4106
|
/* @__PURE__ */ jsx(OrderFormBlock, { title: t("financial.invoice.details"), children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
4021
4107
|
showUnitField && /* @__PURE__ */ jsx(UnitField, { choices: unitChoices, value: unitId, onChange: setUnitId }),
|
|
@@ -4104,10 +4190,23 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
4104
4190
|
parentLabel: embedded ? void 0 : direction === "debit" ? t("financial.nav.payables") : t("financial.nav.receivables"),
|
|
4105
4191
|
onBack: embedded ? void 0 : () => onSaved?.(),
|
|
4106
4192
|
actions,
|
|
4107
|
-
banner: isEdit
|
|
4193
|
+
banner: isEdit ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4194
|
+
hasPayments && /* @__PURE__ */ jsx("p", { className: "rounded-card border border-warning/40 bg-warning-soft px-4 py-2.5 text-xs text-warning-soft-foreground", children: t("financial.invoiceForm.issuedLocked") }),
|
|
4195
|
+
/* @__PURE__ */ jsx(
|
|
4196
|
+
WidgetSlot,
|
|
4197
|
+
{
|
|
4198
|
+
zone: FINANCIAL_INVOICE_ZONES.notices,
|
|
4199
|
+
invoiceId: editId,
|
|
4200
|
+
direction,
|
|
4201
|
+
cancelled,
|
|
4202
|
+
onChanged: () => setReloadTick((n) => n + 1)
|
|
4203
|
+
}
|
|
4204
|
+
)
|
|
4205
|
+
] }) : void 0,
|
|
4108
4206
|
sideSections,
|
|
4109
4207
|
children: [
|
|
4110
4208
|
contactSection,
|
|
4209
|
+
priceTableSection,
|
|
4111
4210
|
/* @__PURE__ */ jsxs(
|
|
4112
4211
|
OrderFormItemsCard,
|
|
4113
4212
|
{
|
|
@@ -4336,5 +4435,5 @@ function InvoiceFormView({ direction, editId, onSaved, focusReceipt = false, fro
|
|
|
4336
4435
|
}
|
|
4337
4436
|
|
|
4338
4437
|
export { ACCOUNTS_ROUTE, AccountIcon, BankLogo, BankPicker, CancelInvoicesDialog, FinancialCounterpartySearchSelect, InvoiceAttachmentsModal, InvoiceDetailView, InvoiceFormView, PaymentModal, UnitField, createFinancialCounterpartyLookup, findBrBank, marcarItemParaAbrir, renderAccountAvatar, renderCardChip, useStockedItemTypes, useWritableUnits };
|
|
4339
|
-
//# sourceMappingURL=chunk-
|
|
4340
|
-
//# sourceMappingURL=chunk-
|
|
4438
|
+
//# sourceMappingURL=chunk-IQHWMVUM.js.map
|
|
4439
|
+
//# sourceMappingURL=chunk-IQHWMVUM.js.map
|