@fayz-ai/plugin-financial 0.9.1 → 0.9.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.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +237 -77
- package/dist/index.js.map +1 -1
- package/dist/integrations/stripe/connectorDef.d.ts +14 -0
- package/dist/integrations/stripe/connectorDef.d.ts.map +1 -0
- package/dist/integrations/stripe/data.d.ts +43 -0
- package/dist/integrations/stripe/data.d.ts.map +1 -0
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React18 from 'react';
|
|
2
2
|
import React18__default, { useState, useEffect, useMemo, useCallback, useRef } from 'react';
|
|
3
|
-
import { createSafeDataProvider, registerTranslations, registerMessageDefaults, useTranslation, getSupabaseClientOptional, getActiveTenantId, exportCSV } from '@fayz-ai/core';
|
|
3
|
+
import { createConnectionStore, connectionSettings, connectionStatus, settingsStatus, createSafeDataProvider, registerTranslations, registerMessageDefaults, useTranslation, getSupabaseClientOptional, getActiveTenantId, exportCSV } from '@fayz-ai/core';
|
|
4
4
|
import { toast, defineKpiWidget, defineChartWidget, defineCustomWidget, defineTableWidget, DataTable, PageTransition, ModulePage, Button, Modal, ModalContent, DatePicker, DashboardCanvas, SubpageHeader, Skeleton, Card, FilterChip, Input, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, CurrencyInput, useSaveBar, SearchSelect, ListView, KpiCard, ChartWidget, CardHeader, CardTitle, CardContent, TableWidget, useDashboardNavigate, GoldCard } from '@fayz-ai/ui';
|
|
5
|
-
import { createPluginContext, PluginSettingsPanel, dedup, useModuleNavigation, usePermissionOptional, useModuleNavAccess, PermissionGate, ModuleActionBar, useTenantPluginSettings, SettingsGroup, ToggleRow, formatCurrency, parseViewId, EntitlementGate, UpgradePrompt, useLimitGuard, invalidateLimit, PersonLink, OrderFormSkeleton, OrderFormBlock, OrderFormView, OrderFormItemsCard, OrderFormItemRow, OrderFormAddItemStep, OrderDetailSkeleton, OrderDetailBlock, OrderDetailView } from '@fayz-ai/admin';
|
|
5
|
+
import { createPluginContext, fayzConnectorOAuth, PluginSettingsPanel, dedup, useModuleNavigation, usePermissionOptional, useModuleNavAccess, PermissionGate, ModuleActionBar, useTenantPluginSettings, SettingsGroup, ToggleRow, formatCurrency, parseViewId, EntitlementGate, UpgradePrompt, useLimitGuard, invalidateLimit, PersonLink, OrderFormSkeleton, OrderFormBlock, OrderFormView, OrderFormItemsCard, OrderFormItemRow, OrderFormAddItemStep, OrderDetailSkeleton, OrderDetailBlock, OrderDetailView } from '@fayz-ai/admin';
|
|
6
6
|
import { Wallet, Plus, DollarSign, Landmark, CreditCard, BookOpen, Check, ChevronRight, X, CalendarDays, Paperclip, Camera, Tag, Repeat, ChevronDown, FileText, FileCheck2, ExternalLink, Send, Ban, CalendarClock, RefreshCw, ArrowDownCircle, ArrowUpCircle, Sparkles, Link2, ArrowRightLeft, Search, Download, Receipt, Clock, ArrowLeftRight, CheckCheck, Calculator, StickyNote, Play, Square, ChevronUp, MoreVertical, CircleCheckBig, CircleDashed, CircleAlert, CircleEllipsis, Pencil, LayoutList, Layers, Building2, ShoppingCart, Car, Home, Utensils, Zap, Film, HeartPulse, Dumbbell, Music, ShoppingBag, CircleDollarSign, FileCheck, QrCode, Banknote, ArrowUpRight, ArrowDownRight, AlertTriangle, EyeOff, Eye } from 'lucide-react';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import { createPortal } from 'react-dom';
|
|
@@ -3793,7 +3793,7 @@ function buildNav(config, activeView, navigate, t2) {
|
|
|
3793
3793
|
}
|
|
3794
3794
|
return items;
|
|
3795
3795
|
}
|
|
3796
|
-
function FinancialPage({ config, provider, store, registries }) {
|
|
3796
|
+
function FinancialPage({ config, provider, store: store2, registries }) {
|
|
3797
3797
|
const { view, direction, navigate, previousView, back } = useModuleNavigation("/financial", {
|
|
3798
3798
|
summary: 0,
|
|
3799
3799
|
"payables-list": 0,
|
|
@@ -3891,10 +3891,10 @@ function FinancialPage({ config, provider, store, registries }) {
|
|
|
3891
3891
|
}
|
|
3892
3892
|
}
|
|
3893
3893
|
if (!onboardingComplete) {
|
|
3894
|
-
return /* @__PURE__ */ jsx(FinancialContextProvider, { config, provider, store, children: /* @__PURE__ */ jsx(FinancialOnboarding, { onComplete: handleOnboardingComplete }) });
|
|
3894
|
+
return /* @__PURE__ */ jsx(FinancialContextProvider, { config, provider, store: store2, children: /* @__PURE__ */ jsx(FinancialOnboarding, { onComplete: handleOnboardingComplete }) });
|
|
3895
3895
|
}
|
|
3896
3896
|
if (isSettings && registries && registries.length > 0) {
|
|
3897
|
-
return /* @__PURE__ */ jsx(FinancialContextProvider, { config, provider, store, children: /* @__PURE__ */ jsx(PageTransition, { transitionKey: "settings", direction, children: /* @__PURE__ */ jsx("div", { style: { padding: "24px" }, children: /* @__PURE__ */ jsx(
|
|
3897
|
+
return /* @__PURE__ */ jsx(FinancialContextProvider, { config, provider, store: store2, children: /* @__PURE__ */ jsx(PageTransition, { transitionKey: "settings", direction, children: /* @__PURE__ */ jsx("div", { style: { padding: "24px" }, children: /* @__PURE__ */ jsx(
|
|
3898
3898
|
PluginSettingsPanel,
|
|
3899
3899
|
{
|
|
3900
3900
|
title: t2("financial.settingsPage.title"),
|
|
@@ -3935,7 +3935,7 @@ function FinancialPage({ config, provider, store, registries }) {
|
|
|
3935
3935
|
if (!feature) return renderView();
|
|
3936
3936
|
return /* @__PURE__ */ jsx(EntitlementGate, { feature, fallback: /* @__PURE__ */ jsx(UpgradePrompt, { feature }), children: renderView() });
|
|
3937
3937
|
}
|
|
3938
|
-
return /* @__PURE__ */ jsx(FinancialContextProvider, { config, provider, store, children: /* @__PURE__ */ jsxs(
|
|
3938
|
+
return /* @__PURE__ */ jsx(FinancialContextProvider, { config, provider, store: store2, children: /* @__PURE__ */ jsxs(
|
|
3939
3939
|
ModulePage,
|
|
3940
3940
|
{
|
|
3941
3941
|
title: config.labels.pageTitle,
|
|
@@ -4445,7 +4445,7 @@ function createStore(options) {
|
|
|
4445
4445
|
};
|
|
4446
4446
|
}
|
|
4447
4447
|
function createMockFinancialProvider(options) {
|
|
4448
|
-
const
|
|
4448
|
+
const store2 = createStore(options);
|
|
4449
4449
|
const tenantId = "mock-tenant";
|
|
4450
4450
|
function recalcInvoiceStatus(invoice) {
|
|
4451
4451
|
if (invoice.paidAmount >= invoice.totalAmount) {
|
|
@@ -4453,7 +4453,7 @@ function createMockFinancialProvider(options) {
|
|
|
4453
4453
|
} else if (invoice.paidAmount > 0) {
|
|
4454
4454
|
invoice.status = "partial";
|
|
4455
4455
|
} else {
|
|
4456
|
-
const movements =
|
|
4456
|
+
const movements = store2.movements.filter((m) => m.invoiceId === invoice.id && m.movementKind === "bill");
|
|
4457
4457
|
const hasOverdue = movements.some((m) => m.status === "overdue" || m.status === "pending" && m.dueDate < today());
|
|
4458
4458
|
invoice.status = hasOverdue ? "overdue" : "open";
|
|
4459
4459
|
}
|
|
@@ -4462,16 +4462,16 @@ function createMockFinancialProvider(options) {
|
|
|
4462
4462
|
const provider = {
|
|
4463
4463
|
// --- Invoices ---
|
|
4464
4464
|
async getInvoices(query) {
|
|
4465
|
-
let results = [...
|
|
4465
|
+
let results = [...store2.invoices];
|
|
4466
4466
|
if (query.direction) results = results.filter((i) => i.direction === query.direction);
|
|
4467
4467
|
if (query.status) results = results.filter((i) => matchesStatus(i.status, query.status));
|
|
4468
4468
|
if (query.contactId) results = results.filter((i) => i.contactId === query.contactId);
|
|
4469
4469
|
if (query.accountId) {
|
|
4470
|
-
const invoiceIds = new Set(
|
|
4470
|
+
const invoiceIds = new Set(store2.invoiceItems.filter((item) => item.accountId === query.accountId).map((item) => item.invoiceId));
|
|
4471
4471
|
results = results.filter((invoice) => invoiceIds.has(invoice.id));
|
|
4472
4472
|
}
|
|
4473
4473
|
if (query.costCenterId) {
|
|
4474
|
-
const invoiceIds = new Set(
|
|
4474
|
+
const invoiceIds = new Set(store2.invoiceItems.filter((item) => item.costCenterId === query.costCenterId).map((item) => item.invoiceId));
|
|
4475
4475
|
results = results.filter((invoice) => invoiceIds.has(invoice.id));
|
|
4476
4476
|
}
|
|
4477
4477
|
if (query.dateRange) results = results.filter((i) => matchesDateRange(i.invoiceDate, query.dateRange));
|
|
@@ -4485,10 +4485,10 @@ function createMockFinancialProvider(options) {
|
|
|
4485
4485
|
return paginate(results, query.page, query.pageSize);
|
|
4486
4486
|
},
|
|
4487
4487
|
async getInvoiceById(id) {
|
|
4488
|
-
return
|
|
4488
|
+
return store2.invoices.find((i) => i.id === id) ?? null;
|
|
4489
4489
|
},
|
|
4490
4490
|
async getInvoiceItems(invoiceId) {
|
|
4491
|
-
return
|
|
4491
|
+
return store2.invoiceItems.filter((i) => i.invoiceId === invoiceId);
|
|
4492
4492
|
},
|
|
4493
4493
|
async createInvoice(input) {
|
|
4494
4494
|
const invoiceId = uid();
|
|
@@ -4517,7 +4517,7 @@ function createMockFinancialProvider(options) {
|
|
|
4517
4517
|
createdAt: now(),
|
|
4518
4518
|
updatedAt: now()
|
|
4519
4519
|
};
|
|
4520
|
-
|
|
4520
|
+
store2.invoices.push(invoice);
|
|
4521
4521
|
for (const itemInput of input.items) {
|
|
4522
4522
|
const itemTotal = itemInput.quantity * itemInput.unitPrice - (itemInput.discount ?? 0) + (itemInput.surcharge ?? 0);
|
|
4523
4523
|
const item = {
|
|
@@ -4536,7 +4536,7 @@ function createMockFinancialProvider(options) {
|
|
|
4536
4536
|
metadata: itemInput.metadata,
|
|
4537
4537
|
createdAt: now()
|
|
4538
4538
|
};
|
|
4539
|
-
|
|
4539
|
+
store2.invoiceItems.push(item);
|
|
4540
4540
|
}
|
|
4541
4541
|
for (const movInput of input.installments) {
|
|
4542
4542
|
const movement = {
|
|
@@ -4557,29 +4557,29 @@ function createMockFinancialProvider(options) {
|
|
|
4557
4557
|
createdAt: now(),
|
|
4558
4558
|
updatedAt: now()
|
|
4559
4559
|
};
|
|
4560
|
-
|
|
4560
|
+
store2.movements.push(movement);
|
|
4561
4561
|
}
|
|
4562
4562
|
return invoice;
|
|
4563
4563
|
},
|
|
4564
4564
|
async updateInvoice(id, data) {
|
|
4565
|
-
const invoice =
|
|
4565
|
+
const invoice = store2.invoices.find((i) => i.id === id);
|
|
4566
4566
|
if (!invoice) throw new Error(`Invoice ${id} not found`);
|
|
4567
4567
|
Object.assign(invoice, data, { updatedAt: now() });
|
|
4568
4568
|
return invoice;
|
|
4569
4569
|
},
|
|
4570
4570
|
async cancelInvoice(id) {
|
|
4571
|
-
const invoice =
|
|
4571
|
+
const invoice = store2.invoices.find((i) => i.id === id);
|
|
4572
4572
|
if (!invoice) throw new Error(`Invoice ${id} not found`);
|
|
4573
4573
|
invoice.status = "cancelled";
|
|
4574
4574
|
invoice.updatedAt = now();
|
|
4575
|
-
|
|
4575
|
+
store2.movements.filter((m) => m.invoiceId === id && m.status === "pending").forEach((m) => {
|
|
4576
4576
|
m.status = "cancelled";
|
|
4577
4577
|
m.updatedAt = now();
|
|
4578
4578
|
});
|
|
4579
4579
|
},
|
|
4580
4580
|
// --- Movements ---
|
|
4581
4581
|
async getMovements(query) {
|
|
4582
|
-
let results = [...
|
|
4582
|
+
let results = [...store2.movements];
|
|
4583
4583
|
if (query.direction) results = results.filter((m) => m.direction === query.direction);
|
|
4584
4584
|
if (query.status) results = results.filter((m) => matchesStatus(m.status, query.status));
|
|
4585
4585
|
if (query.bankAccountId) results = results.filter((m) => m.bankAccountId === query.bankAccountId);
|
|
@@ -4589,9 +4589,9 @@ function createMockFinancialProvider(options) {
|
|
|
4589
4589
|
return paginate(results, query.page, query.pageSize);
|
|
4590
4590
|
},
|
|
4591
4591
|
async payMovement(input) {
|
|
4592
|
-
const bill =
|
|
4592
|
+
const bill = store2.movements.find((m) => m.id === input.movementId);
|
|
4593
4593
|
if (!bill) throw new Error(`Movement ${input.movementId} not found`);
|
|
4594
|
-
const method = input.paymentMethodId ?
|
|
4594
|
+
const method = input.paymentMethodId ? store2.paymentMethods.find((pm) => pm.id === input.paymentMethodId) : void 0;
|
|
4595
4595
|
const feePct = bill.direction === "credit" ? method?.discountValue ?? 0 : 0;
|
|
4596
4596
|
const thisFee = round2(input.amount * (feePct / 100));
|
|
4597
4597
|
const payment = {
|
|
@@ -4617,14 +4617,14 @@ function createMockFinancialProvider(options) {
|
|
|
4617
4617
|
createdAt: now(),
|
|
4618
4618
|
updatedAt: now()
|
|
4619
4619
|
};
|
|
4620
|
-
|
|
4620
|
+
store2.movements.push(payment);
|
|
4621
4621
|
bill.paidAmount = round2(bill.paidAmount + input.amount);
|
|
4622
4622
|
bill.status = bill.paidAmount >= bill.amount ? "paid" : "partial";
|
|
4623
4623
|
bill.paymentDate = void 0;
|
|
4624
4624
|
bill.bankAccountId = void 0;
|
|
4625
4625
|
bill.updatedAt = now();
|
|
4626
4626
|
if (input.bankAccountId) {
|
|
4627
|
-
const account =
|
|
4627
|
+
const account = store2.bankAccounts.find((a) => a.id === input.bankAccountId);
|
|
4628
4628
|
if (account) {
|
|
4629
4629
|
if (bill.direction === "credit") {
|
|
4630
4630
|
account.currentBalance = round2(account.currentBalance + (input.amount - thisFee));
|
|
@@ -4635,9 +4635,9 @@ function createMockFinancialProvider(options) {
|
|
|
4635
4635
|
}
|
|
4636
4636
|
}
|
|
4637
4637
|
if (bill.invoiceId) {
|
|
4638
|
-
const invoice =
|
|
4638
|
+
const invoice = store2.invoices.find((i) => i.id === bill.invoiceId);
|
|
4639
4639
|
if (invoice) {
|
|
4640
|
-
const bills =
|
|
4640
|
+
const bills = store2.movements.filter((m) => m.invoiceId === invoice.id && m.movementKind === "bill");
|
|
4641
4641
|
invoice.paidAmount = bills.reduce((sum, m) => sum + m.paidAmount, 0);
|
|
4642
4642
|
recalcInvoiceStatus(invoice);
|
|
4643
4643
|
}
|
|
@@ -4645,7 +4645,7 @@ function createMockFinancialProvider(options) {
|
|
|
4645
4645
|
return payment;
|
|
4646
4646
|
},
|
|
4647
4647
|
async cancelMovement(id) {
|
|
4648
|
-
const movement =
|
|
4648
|
+
const movement = store2.movements.find((m) => m.id === id);
|
|
4649
4649
|
if (!movement) throw new Error(`Movement ${id} not found`);
|
|
4650
4650
|
movement.status = "cancelled";
|
|
4651
4651
|
movement.updatedAt = now();
|
|
@@ -4672,22 +4672,22 @@ function createMockFinancialProvider(options) {
|
|
|
4672
4672
|
createdAt: now(),
|
|
4673
4673
|
updatedAt: now()
|
|
4674
4674
|
};
|
|
4675
|
-
|
|
4675
|
+
store2.movements.push({
|
|
4676
4676
|
...base,
|
|
4677
4677
|
id: debitMovementId,
|
|
4678
4678
|
direction: "debit",
|
|
4679
4679
|
bankAccountId: input.fromAccountId,
|
|
4680
4680
|
metadata: { transferId, transferRole: "out", counterAccountId: input.toAccountId }
|
|
4681
4681
|
});
|
|
4682
|
-
|
|
4682
|
+
store2.movements.push({
|
|
4683
4683
|
...base,
|
|
4684
4684
|
id: creditMovementId,
|
|
4685
4685
|
direction: "credit",
|
|
4686
4686
|
bankAccountId: input.toAccountId,
|
|
4687
4687
|
metadata: { transferId, transferRole: "in", counterAccountId: input.fromAccountId }
|
|
4688
4688
|
});
|
|
4689
|
-
const from =
|
|
4690
|
-
const to =
|
|
4689
|
+
const from = store2.bankAccounts.find((a) => a.id === input.fromAccountId);
|
|
4690
|
+
const to = store2.bankAccounts.find((a) => a.id === input.toAccountId);
|
|
4691
4691
|
if (from) {
|
|
4692
4692
|
from.currentBalance = round2(from.currentBalance - input.amount);
|
|
4693
4693
|
from.updatedAt = now();
|
|
@@ -4700,7 +4700,7 @@ function createMockFinancialProvider(options) {
|
|
|
4700
4700
|
},
|
|
4701
4701
|
// --- Bank Accounts ---
|
|
4702
4702
|
async getBankAccounts() {
|
|
4703
|
-
return
|
|
4703
|
+
return store2.bankAccounts.filter((a) => a.isActive);
|
|
4704
4704
|
},
|
|
4705
4705
|
async createBankAccount(data) {
|
|
4706
4706
|
const account = {
|
|
@@ -4721,26 +4721,26 @@ function createMockFinancialProvider(options) {
|
|
|
4721
4721
|
createdAt: now(),
|
|
4722
4722
|
updatedAt: now()
|
|
4723
4723
|
};
|
|
4724
|
-
|
|
4724
|
+
store2.bankAccounts.push(account);
|
|
4725
4725
|
return account;
|
|
4726
4726
|
},
|
|
4727
4727
|
async updateBankAccount(id, data) {
|
|
4728
|
-
const account =
|
|
4728
|
+
const account = store2.bankAccounts.find((a) => a.id === id);
|
|
4729
4729
|
if (!account) throw new Error(`Bank account ${id} not found`);
|
|
4730
4730
|
Object.assign(account, data, { updatedAt: now() });
|
|
4731
4731
|
return account;
|
|
4732
4732
|
},
|
|
4733
4733
|
// --- Cash Sessions ---
|
|
4734
4734
|
async getCashSessions(bankAccountId) {
|
|
4735
|
-
let results = [...
|
|
4735
|
+
let results = [...store2.cashSessions];
|
|
4736
4736
|
if (bankAccountId) results = results.filter((s) => s.bankAccountId === bankAccountId);
|
|
4737
4737
|
return results.sort((a, b) => b.openedAt.localeCompare(a.openedAt));
|
|
4738
4738
|
},
|
|
4739
4739
|
async getOpenSession(bankAccountId) {
|
|
4740
|
-
return
|
|
4740
|
+
return store2.cashSessions.find((s) => s.bankAccountId === bankAccountId && s.status === "open") ?? null;
|
|
4741
4741
|
},
|
|
4742
4742
|
async openCashSession(input) {
|
|
4743
|
-
const account =
|
|
4743
|
+
const account = store2.bankAccounts.find((a) => a.id === input.bankAccountId);
|
|
4744
4744
|
const session = {
|
|
4745
4745
|
id: uid(),
|
|
4746
4746
|
bankAccountId: input.bankAccountId,
|
|
@@ -4754,13 +4754,13 @@ function createMockFinancialProvider(options) {
|
|
|
4754
4754
|
tenantId,
|
|
4755
4755
|
createdAt: now()
|
|
4756
4756
|
};
|
|
4757
|
-
|
|
4757
|
+
store2.cashSessions.push(session);
|
|
4758
4758
|
return session;
|
|
4759
4759
|
},
|
|
4760
4760
|
async closeCashSession(input) {
|
|
4761
|
-
const session =
|
|
4761
|
+
const session = store2.cashSessions.find((s) => s.id === input.sessionId);
|
|
4762
4762
|
if (!session) throw new Error(`Cash session ${input.sessionId} not found`);
|
|
4763
|
-
const sessionMovements =
|
|
4763
|
+
const sessionMovements = store2.movements.filter((m) => m.cashSessionId === session.id && m.status === "paid");
|
|
4764
4764
|
const inflow = sessionMovements.filter((m) => m.direction === "credit").reduce((s, m) => s + m.paidAmount, 0);
|
|
4765
4765
|
const outflow = sessionMovements.filter((m) => m.direction === "debit").reduce((s, m) => s + m.paidAmount, 0);
|
|
4766
4766
|
const expectedBalance = session.openingBalance + inflow - outflow;
|
|
@@ -4775,9 +4775,9 @@ function createMockFinancialProvider(options) {
|
|
|
4775
4775
|
return session;
|
|
4776
4776
|
},
|
|
4777
4777
|
async getCashSessionSummary(sessionId) {
|
|
4778
|
-
const session =
|
|
4778
|
+
const session = store2.cashSessions.find((s) => s.id === sessionId);
|
|
4779
4779
|
if (!session) throw new Error(`Cash session ${sessionId} not found`);
|
|
4780
|
-
const sessionMovements =
|
|
4780
|
+
const sessionMovements = store2.movements.filter((m) => m.cashSessionId === sessionId && m.status === "paid");
|
|
4781
4781
|
return {
|
|
4782
4782
|
session,
|
|
4783
4783
|
movementCount: sessionMovements.length,
|
|
@@ -4787,21 +4787,21 @@ function createMockFinancialProvider(options) {
|
|
|
4787
4787
|
},
|
|
4788
4788
|
// --- Payment Methods ---
|
|
4789
4789
|
async getPaymentMethods() {
|
|
4790
|
-
return
|
|
4790
|
+
return store2.paymentMethods.filter((pm) => pm.isActive);
|
|
4791
4791
|
},
|
|
4792
4792
|
async getPaymentMethodTypes() {
|
|
4793
|
-
return
|
|
4793
|
+
return store2.paymentMethodTypes.filter((t2) => t2.isActive);
|
|
4794
4794
|
},
|
|
4795
4795
|
// --- Chart of Accounts ---
|
|
4796
4796
|
async getChartOfAccounts() {
|
|
4797
|
-
return
|
|
4797
|
+
return store2.chartOfAccounts.filter((n) => n.isActive);
|
|
4798
4798
|
},
|
|
4799
4799
|
async getCostCenters() {
|
|
4800
|
-
return
|
|
4800
|
+
return store2.costCenters.filter((c) => c.isActive);
|
|
4801
4801
|
},
|
|
4802
4802
|
// --- Card Transactions ---
|
|
4803
4803
|
async getCardTransactions(dateRange) {
|
|
4804
|
-
let results = [...
|
|
4804
|
+
let results = [...store2.cardTransactions];
|
|
4805
4805
|
if (dateRange) results = results.filter((t2) => matchesDateRange(t2.expectedDate, dateRange));
|
|
4806
4806
|
return results.sort((a, b) => a.expectedDate.localeCompare(b.expectedDate));
|
|
4807
4807
|
},
|
|
@@ -4810,15 +4810,15 @@ function createMockFinancialProvider(options) {
|
|
|
4810
4810
|
const todayStr = today();
|
|
4811
4811
|
const isRealized = (m) => m.status !== "cancelled" && !!m.paymentDate;
|
|
4812
4812
|
const consolidated = !query.bankAccountId;
|
|
4813
|
-
const scopeAccounts = consolidated ?
|
|
4813
|
+
const scopeAccounts = consolidated ? store2.bankAccounts.filter((a) => a.isActive) : store2.bankAccounts.filter((a) => a.id === query.bankAccountId);
|
|
4814
4814
|
const accountIds = new Set(scopeAccounts.map((a) => a.id));
|
|
4815
|
-
const accountNameById = new Map(
|
|
4815
|
+
const accountNameById = new Map(store2.bankAccounts.map((a) => [a.id, a.name]));
|
|
4816
4816
|
const initialSum = scopeAccounts.reduce((s, a) => s + a.initialBalance, 0);
|
|
4817
4817
|
if (!consolidated && accountIds.size === 0) {
|
|
4818
4818
|
return { entries: [], openingBalance: 0, closingBalance: 0, totalCredits: 0, totalDebits: 0, totalFees: 0, net: 0, accountId: query.bankAccountId };
|
|
4819
4819
|
}
|
|
4820
4820
|
const netOf = (m) => m.direction === "credit" ? m.paidAmount - (m.feeAmount ?? 0) : -m.paidAmount;
|
|
4821
|
-
const inScope =
|
|
4821
|
+
const inScope = store2.movements.filter((m) => isRealized(m) && (consolidated || m.bankAccountId && accountIds.has(m.bankAccountId)));
|
|
4822
4822
|
const openingBalance = round2(initialSum + inScope.filter((m) => (m.paymentDate ?? "") < query.dateRange.from).reduce((s, m) => s + netOf(m), 0));
|
|
4823
4823
|
const rangeMovs = inScope.filter((m) => matchesDateRange(m.paymentDate, query.dateRange)).sort((a, b) => (a.paymentDate ?? "").localeCompare(b.paymentDate ?? "") || a.createdAt.localeCompare(b.createdAt));
|
|
4824
4824
|
let balance = openingBalance;
|
|
@@ -4840,7 +4840,7 @@ function createMockFinancialProvider(options) {
|
|
|
4840
4840
|
}
|
|
4841
4841
|
return {
|
|
4842
4842
|
movement,
|
|
4843
|
-
invoice: movement.invoiceId ?
|
|
4843
|
+
invoice: movement.invoiceId ? store2.invoices.find((i) => i.id === movement.invoiceId) : void 0,
|
|
4844
4844
|
runningBalance: balance,
|
|
4845
4845
|
gross,
|
|
4846
4846
|
fee,
|
|
@@ -4852,9 +4852,9 @@ function createMockFinancialProvider(options) {
|
|
|
4852
4852
|
});
|
|
4853
4853
|
for (const e of entries) {
|
|
4854
4854
|
const mid = e.movement.matchedMovementId;
|
|
4855
|
-
const mm = mid ?
|
|
4855
|
+
const mm = mid ? store2.movements.find((m) => m.id === mid) : void 0;
|
|
4856
4856
|
if (!mm) continue;
|
|
4857
|
-
const inv = mm.invoiceId ?
|
|
4857
|
+
const inv = mm.invoiceId ? store2.invoices.find((i) => i.id === mm.invoiceId) : void 0;
|
|
4858
4858
|
e.reconciledWith = {
|
|
4859
4859
|
movementId: mm.id,
|
|
4860
4860
|
description: mm.notes ?? void 0,
|
|
@@ -4878,11 +4878,11 @@ function createMockFinancialProvider(options) {
|
|
|
4878
4878
|
},
|
|
4879
4879
|
// --- Summary ---
|
|
4880
4880
|
async getSummary(dateRange) {
|
|
4881
|
-
const totalBalance =
|
|
4882
|
-
const pendingReceivable =
|
|
4881
|
+
const totalBalance = store2.bankAccounts.filter((a) => a.isActive).reduce((sum, a) => sum + a.currentBalance, 0);
|
|
4882
|
+
const pendingReceivable = store2.movements.filter(
|
|
4883
4883
|
(m) => m.direction === "credit" && m.movementKind === "bill" && ["pending", "partial"].includes(m.status)
|
|
4884
4884
|
);
|
|
4885
|
-
const pendingPayable =
|
|
4885
|
+
const pendingPayable = store2.movements.filter(
|
|
4886
4886
|
(m) => m.direction === "debit" && m.movementKind === "bill" && ["pending", "partial"].includes(m.status)
|
|
4887
4887
|
);
|
|
4888
4888
|
const todayStr = today();
|
|
@@ -4890,7 +4890,7 @@ function createMockFinancialProvider(options) {
|
|
|
4890
4890
|
monthAgo.setDate(monthAgo.getDate() - 30);
|
|
4891
4891
|
const monthStart = monthAgo.toISOString().slice(0, 10);
|
|
4892
4892
|
const monthEnd = todayStr;
|
|
4893
|
-
const monthMovements =
|
|
4893
|
+
const monthMovements = store2.movements.filter(
|
|
4894
4894
|
(m) => m.movementKind === "payment" && matchesDateRange(m.paymentDate, dateRange ?? { from: monthStart, to: monthEnd })
|
|
4895
4895
|
);
|
|
4896
4896
|
const overdueReceivable = pendingReceivable.filter((m) => m.dueDate < todayStr);
|
|
@@ -4911,12 +4911,12 @@ function createMockFinancialProvider(options) {
|
|
|
4911
4911
|
async importBankTransactions(input) {
|
|
4912
4912
|
let imported = 0, duplicates = 0;
|
|
4913
4913
|
for (const line of input.lines) {
|
|
4914
|
-
const dup =
|
|
4914
|
+
const dup = store2.movements.some((m) => m.externalSource === line.externalSource && m.externalId === line.externalId);
|
|
4915
4915
|
if (dup) {
|
|
4916
4916
|
duplicates++;
|
|
4917
4917
|
continue;
|
|
4918
4918
|
}
|
|
4919
|
-
|
|
4919
|
+
store2.movements.push({
|
|
4920
4920
|
id: uid(),
|
|
4921
4921
|
direction: line.direction,
|
|
4922
4922
|
movementKind: "payment",
|
|
@@ -4938,38 +4938,38 @@ function createMockFinancialProvider(options) {
|
|
|
4938
4938
|
return { imported, duplicates };
|
|
4939
4939
|
},
|
|
4940
4940
|
async getUnreconciled(query) {
|
|
4941
|
-
let results =
|
|
4941
|
+
let results = store2.movements.filter((m) => m.externalSource && !m.reconciledAt);
|
|
4942
4942
|
if (query?.bankAccountId) results = results.filter((m) => m.bankAccountId === query.bankAccountId);
|
|
4943
4943
|
if (query?.dateRange) results = results.filter((m) => matchesDateRange(m.paymentDate, query.dateRange));
|
|
4944
4944
|
return results.sort((a, b) => (b.paymentDate ?? "").localeCompare(a.paymentDate ?? ""));
|
|
4945
4945
|
},
|
|
4946
4946
|
async suggestReconciliation(bankMovementId) {
|
|
4947
|
-
const line =
|
|
4947
|
+
const line = store2.movements.find((m) => m.id === bankMovementId);
|
|
4948
4948
|
if (!line) return [];
|
|
4949
4949
|
const amount = line.amount;
|
|
4950
4950
|
const tol = Math.max(0.01, round2(amount * 0.02));
|
|
4951
4951
|
const lineDate = line.paymentDate ?? line.dueDate;
|
|
4952
|
-
return
|
|
4952
|
+
return store2.movements.filter((m) => !m.externalSource && !m.reconciledAt && m.direction === line.direction && m.id !== bankMovementId && Math.abs(m.amount - amount) <= tol).map((m) => {
|
|
4953
4953
|
const amtScore = amount > 0 ? Math.max(0, 1 - Math.abs(m.amount - amount) / amount) : 0;
|
|
4954
4954
|
const refDate = m.dueDate ?? m.paymentDate;
|
|
4955
4955
|
const days = lineDate && refDate ? Math.abs((new Date(lineDate).getTime() - new Date(refDate).getTime()) / 864e5) : 30;
|
|
4956
4956
|
const dateScore = Math.max(0, 1 - days / 30);
|
|
4957
4957
|
return {
|
|
4958
4958
|
movement: m,
|
|
4959
|
-
invoice: m.invoiceId ?
|
|
4959
|
+
invoice: m.invoiceId ? store2.invoices.find((i) => i.id === m.invoiceId) : void 0,
|
|
4960
4960
|
score: round2(0.7 * amtScore + 0.3 * dateScore)
|
|
4961
4961
|
};
|
|
4962
4962
|
}).sort((a, b) => b.score - a.score).slice(0, 25);
|
|
4963
4963
|
},
|
|
4964
4964
|
async reconcileMovement(input) {
|
|
4965
|
-
const line =
|
|
4965
|
+
const line = store2.movements.find((m) => m.id === input.bankMovementId);
|
|
4966
4966
|
if (line) {
|
|
4967
4967
|
line.reconciledAt = now();
|
|
4968
4968
|
line.matchedMovementId = input.matchedMovementId;
|
|
4969
4969
|
line.updatedAt = now();
|
|
4970
4970
|
}
|
|
4971
4971
|
if (input.matchedMovementId) {
|
|
4972
|
-
const internal =
|
|
4972
|
+
const internal = store2.movements.find((m) => m.id === input.matchedMovementId);
|
|
4973
4973
|
if (internal) {
|
|
4974
4974
|
internal.reconciledAt = now();
|
|
4975
4975
|
internal.updatedAt = now();
|
|
@@ -4977,14 +4977,14 @@ function createMockFinancialProvider(options) {
|
|
|
4977
4977
|
}
|
|
4978
4978
|
},
|
|
4979
4979
|
async unreconcileMovement(bankMovementId) {
|
|
4980
|
-
const line =
|
|
4980
|
+
const line = store2.movements.find((m) => m.id === bankMovementId);
|
|
4981
4981
|
if (!line) return;
|
|
4982
4982
|
const matchedId = line.matchedMovementId;
|
|
4983
4983
|
line.reconciledAt = void 0;
|
|
4984
4984
|
line.matchedMovementId = void 0;
|
|
4985
4985
|
line.updatedAt = now();
|
|
4986
4986
|
if (matchedId) {
|
|
4987
|
-
const internal =
|
|
4987
|
+
const internal = store2.movements.find((m) => m.id === matchedId);
|
|
4988
4988
|
if (internal) {
|
|
4989
4989
|
internal.reconciledAt = void 0;
|
|
4990
4990
|
internal.updatedAt = now();
|
|
@@ -4993,7 +4993,7 @@ function createMockFinancialProvider(options) {
|
|
|
4993
4993
|
},
|
|
4994
4994
|
// --- Notas fiscais (NF-e / NFC-e / NFS-e) ---
|
|
4995
4995
|
async getNotas(query) {
|
|
4996
|
-
let list = [...
|
|
4996
|
+
let list = [...store2.notas].sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
4997
4997
|
if (query.status) list = list.filter((n) => matchesStatus(n.status, query.status));
|
|
4998
4998
|
if (query.model) list = list.filter((n) => n.model === query.model);
|
|
4999
4999
|
if (query.orderId) list = list.filter((n) => n.orderId === query.orderId);
|
|
@@ -5004,7 +5004,7 @@ function createMockFinancialProvider(options) {
|
|
|
5004
5004
|
return paginate(list, query.page, query.pageSize);
|
|
5005
5005
|
},
|
|
5006
5006
|
async getNotaById(id) {
|
|
5007
|
-
return
|
|
5007
|
+
return store2.notas.find((n) => n.id === id) ?? null;
|
|
5008
5008
|
},
|
|
5009
5009
|
async createNota(input) {
|
|
5010
5010
|
const nota = {
|
|
@@ -5022,19 +5022,19 @@ function createMockFinancialProvider(options) {
|
|
|
5022
5022
|
createdAt: now(),
|
|
5023
5023
|
updatedAt: now()
|
|
5024
5024
|
};
|
|
5025
|
-
|
|
5025
|
+
store2.notas.unshift(nota);
|
|
5026
5026
|
return nota;
|
|
5027
5027
|
},
|
|
5028
5028
|
async updateNota(id, patch) {
|
|
5029
|
-
const nota =
|
|
5029
|
+
const nota = store2.notas.find((n) => n.id === id);
|
|
5030
5030
|
if (!nota) throw new Error("Nota fiscal not found");
|
|
5031
5031
|
Object.assign(nota, patch, { updatedAt: now() });
|
|
5032
5032
|
return nota;
|
|
5033
5033
|
},
|
|
5034
5034
|
async issueNota(id) {
|
|
5035
|
-
const nota =
|
|
5035
|
+
const nota = store2.notas.find((n) => n.id === id);
|
|
5036
5036
|
if (!nota) throw new Error("Nota fiscal not found");
|
|
5037
|
-
const issuedCount =
|
|
5037
|
+
const issuedCount = store2.notas.filter((n) => n.status === "issued").length;
|
|
5038
5038
|
nota.status = "issued";
|
|
5039
5039
|
nota.number = String(issuedCount + 1).padStart(6, "0");
|
|
5040
5040
|
nota.series = nota.series ?? "1";
|
|
@@ -5044,7 +5044,7 @@ function createMockFinancialProvider(options) {
|
|
|
5044
5044
|
return nota;
|
|
5045
5045
|
},
|
|
5046
5046
|
async cancelNota(id, reason) {
|
|
5047
|
-
const nota =
|
|
5047
|
+
const nota = store2.notas.find((n) => n.id === id);
|
|
5048
5048
|
if (!nota) throw new Error("Nota fiscal not found");
|
|
5049
5049
|
nota.status = "cancelled";
|
|
5050
5050
|
nota.errorMessage = reason;
|
|
@@ -7507,6 +7507,156 @@ var financialLocales = {
|
|
|
7507
7507
|
en,
|
|
7508
7508
|
"pt-BR": ptBR
|
|
7509
7509
|
};
|
|
7510
|
+
var STRIPE_CONNECTOR_ID = "stripe";
|
|
7511
|
+
var STRIPE_SETTINGS = [
|
|
7512
|
+
{
|
|
7513
|
+
key: "paymentMethods",
|
|
7514
|
+
label: "Formas de pagamento",
|
|
7515
|
+
description: "O que o cliente pode escolher para pagar a fatura.",
|
|
7516
|
+
type: "multi-select",
|
|
7517
|
+
options: [
|
|
7518
|
+
{ value: "card", label: "Cart\xE3o de cr\xE9dito" },
|
|
7519
|
+
{ value: "pix", label: "Pix" },
|
|
7520
|
+
{ value: "boleto", label: "Boleto" }
|
|
7521
|
+
],
|
|
7522
|
+
requiredToOperate: true
|
|
7523
|
+
},
|
|
7524
|
+
{
|
|
7525
|
+
key: "daysUntilDue",
|
|
7526
|
+
label: "Prazo de vencimento",
|
|
7527
|
+
description: "Dias entre a emiss\xE3o e o vencimento da fatura.",
|
|
7528
|
+
type: "text",
|
|
7529
|
+
placeholder: "7",
|
|
7530
|
+
pattern: "\\d{1,3}",
|
|
7531
|
+
patternHint: "S\xF3 n\xFAmeros, at\xE9 tr\xEAs d\xEDgitos.",
|
|
7532
|
+
defaultValue: "7"
|
|
7533
|
+
},
|
|
7534
|
+
{
|
|
7535
|
+
// The difference between "a fatura foi emitida" and "o cliente recebeu a
|
|
7536
|
+
// cobrança" is a decision, not a default: finalizing at Stripe sends the
|
|
7537
|
+
// e-mail, and a tenant that reviews before sending needs the draft.
|
|
7538
|
+
key: "finalizeAutomatically",
|
|
7539
|
+
label: "Enviar a cobran\xE7a automaticamente",
|
|
7540
|
+
description: "Desligado, a fatura fica como rascunho na Stripe at\xE9 voc\xEA enviar.",
|
|
7541
|
+
type: "toggle",
|
|
7542
|
+
defaultValue: true
|
|
7543
|
+
}
|
|
7544
|
+
];
|
|
7545
|
+
var store = createConnectionStore(STRIPE_CONNECTOR_ID, {
|
|
7546
|
+
settings: STRIPE_SETTINGS
|
|
7547
|
+
});
|
|
7548
|
+
var METHOD_LABELS = { card: "Cart\xE3o", pix: "Pix", boleto: "Boleto" };
|
|
7549
|
+
function methodsDetail(value) {
|
|
7550
|
+
const list = Array.isArray(value) ? value : [];
|
|
7551
|
+
const labels = list.map((v) => METHOD_LABELS[String(v)] ?? String(v)).filter(Boolean);
|
|
7552
|
+
return labels.length > 0 ? labels.join(", ") : void 0;
|
|
7553
|
+
}
|
|
7554
|
+
var stripeConnectorDef = {
|
|
7555
|
+
id: STRIPE_CONNECTOR_ID,
|
|
7556
|
+
hostPluginId: "financial",
|
|
7557
|
+
name: "Stripe",
|
|
7558
|
+
description: "Emita as faturas do Financeiro na Stripe e receba a baixa quando o cliente pagar.",
|
|
7559
|
+
icon: "CreditCard",
|
|
7560
|
+
category: "payments",
|
|
7561
|
+
authKind: "oauth",
|
|
7562
|
+
// Issuing the invoice is an effect that files a run; the settlement arrives by
|
|
7563
|
+
// webhook. Neither happens while a buyer waits, so nothing here is `request`.
|
|
7564
|
+
planes: ["sync"],
|
|
7565
|
+
direction: "outbound",
|
|
7566
|
+
docsUrl: "https://docs.stripe.com/invoicing",
|
|
7567
|
+
// Declared here and not as the legacy `entities`/`subscribesTo` pair: those are
|
|
7568
|
+
// mirrors this list already derives (connectorEntities/connectorSubscribesTo),
|
|
7569
|
+
// and two spellings of the same claim is one that can disagree with itself.
|
|
7570
|
+
//
|
|
7571
|
+
// `invoice_due_soon` and `invoice_overdue` are deliberately absent. Stripe has
|
|
7572
|
+
// its own dunning and neither fact changes anything we would send it; asking to
|
|
7573
|
+
// hear them would be asking for reach this connector does not use.
|
|
7574
|
+
permissions: [
|
|
7575
|
+
{
|
|
7576
|
+
kind: "data",
|
|
7577
|
+
resource: "invoice",
|
|
7578
|
+
actions: ["read", "write"],
|
|
7579
|
+
reason: "Ler a fatura a receber para emiti-la na Stripe, e gravar de volta o n\xFAmero da fatura e o link de pagamento. Nome do cliente e itens v\xE3o na cobran\xE7a.",
|
|
7580
|
+
sensitive: true
|
|
7581
|
+
},
|
|
7582
|
+
{
|
|
7583
|
+
kind: "data",
|
|
7584
|
+
resource: "payment",
|
|
7585
|
+
actions: ["write"],
|
|
7586
|
+
reason: "Lan\xE7ar a baixa no receb\xEDvel quando a Stripe confirmar que o cliente pagou.",
|
|
7587
|
+
sensitive: true
|
|
7588
|
+
},
|
|
7589
|
+
{
|
|
7590
|
+
kind: "event",
|
|
7591
|
+
resource: "financial.invoice_created",
|
|
7592
|
+
actions: ["listen"],
|
|
7593
|
+
reason: "Saber que uma fatura foi emitida, para criar a cobran\xE7a na Stripe."
|
|
7594
|
+
},
|
|
7595
|
+
{
|
|
7596
|
+
kind: "event",
|
|
7597
|
+
resource: "financial.invoice_cancelled",
|
|
7598
|
+
actions: ["listen"],
|
|
7599
|
+
reason: "Saber que uma fatura foi cancelada, para anular a cobran\xE7a na Stripe."
|
|
7600
|
+
},
|
|
7601
|
+
{
|
|
7602
|
+
// The connector is what makes this fact appear, so the tenant should agree
|
|
7603
|
+
// to it here: the app's own automations (recibo, mensagem) react to it.
|
|
7604
|
+
kind: "event",
|
|
7605
|
+
resource: "financial.invoice_paid",
|
|
7606
|
+
actions: ["emit"],
|
|
7607
|
+
reason: "Anunciar dentro do app que a fatura foi paga, para o que depende disso acontecer."
|
|
7608
|
+
}
|
|
7609
|
+
],
|
|
7610
|
+
// Consent is the whole form: an OAuth connector declares no fields, and the
|
|
7611
|
+
// grant never reaches this code.
|
|
7612
|
+
fields: [],
|
|
7613
|
+
settings: STRIPE_SETTINGS,
|
|
7614
|
+
invokedAt: [
|
|
7615
|
+
{
|
|
7616
|
+
key: "financial.invoice.issue",
|
|
7617
|
+
label: "Uma fatura a receber \xE9 emitida na Stripe com o link de pagamento",
|
|
7618
|
+
plane: "sync",
|
|
7619
|
+
trigger: "manual"
|
|
7620
|
+
},
|
|
7621
|
+
{
|
|
7622
|
+
key: "financial.payment.settle",
|
|
7623
|
+
label: "A Stripe avisa que o cliente pagou e a baixa \xE9 lan\xE7ada no receb\xEDvel",
|
|
7624
|
+
plane: "sync",
|
|
7625
|
+
trigger: "webhook"
|
|
7626
|
+
}
|
|
7627
|
+
],
|
|
7628
|
+
...connectionStatus(
|
|
7629
|
+
STRIPE_CONNECTOR_ID,
|
|
7630
|
+
(connection) => ({
|
|
7631
|
+
connected: !!connection?.active,
|
|
7632
|
+
detail: methodsDetail(connection?.settings?.paymentMethods),
|
|
7633
|
+
plane: "sync",
|
|
7634
|
+
...settingsStatus(STRIPE_SETTINGS, connection)
|
|
7635
|
+
}),
|
|
7636
|
+
{ store: () => store }
|
|
7637
|
+
),
|
|
7638
|
+
...connectionSettings(store),
|
|
7639
|
+
/**
|
|
7640
|
+
* The whole connect step, through the platform broker (FAY-1390).
|
|
7641
|
+
*
|
|
7642
|
+
* It used to call an edge function's `oauth_start` — a function that was
|
|
7643
|
+
* never written, so pressing Conectar reached a URL that did not exist and
|
|
7644
|
+
* the browser reported it as a CORS failure. The broker replaces it
|
|
7645
|
+
* end-to-end: consent starts at the platform, the callback lands there, and
|
|
7646
|
+
* the grant is stored in the platform vault.
|
|
7647
|
+
*
|
|
7648
|
+
* `saveConnection` is deliberately absent, like every other OAuth connector
|
|
7649
|
+
* here: `active = true` is written by the redirect route AFTER the grant.
|
|
7650
|
+
* Nothing in a browser is in a position to know an account was linked.
|
|
7651
|
+
*/
|
|
7652
|
+
startOAuth: fayzConnectorOAuth(STRIPE_CONNECTOR_ID),
|
|
7653
|
+
// Local only. Handing the grant back to Stripe is the platform's job — it
|
|
7654
|
+
// holds the client pair and the connected account id, and its deauthorize is
|
|
7655
|
+
// not the same call every other provider takes.
|
|
7656
|
+
disconnect: async () => {
|
|
7657
|
+
await store.disconnect();
|
|
7658
|
+
}
|
|
7659
|
+
};
|
|
7510
7660
|
var STATUS_STYLE = {
|
|
7511
7661
|
paid: "bg-success/15 text-success",
|
|
7512
7662
|
partial: "bg-warning/15 text-warning",
|
|
@@ -7665,6 +7815,7 @@ function resolveConfig(options) {
|
|
|
7665
7815
|
quickAdd: options?.quickAdd === true,
|
|
7666
7816
|
labels: { ...DEFAULT_LABELS, ...options?.labels },
|
|
7667
7817
|
currency: { ...DEFAULT_CURRENCY, ...options?.currency },
|
|
7818
|
+
moduleNav: options?.moduleNav,
|
|
7668
7819
|
itemTypes: options?.itemTypes ?? DEFAULT_ITEM_TYPES,
|
|
7669
7820
|
enableServiceExecution: options?.enableServiceExecution ?? false,
|
|
7670
7821
|
contactEntity: {
|
|
@@ -7683,12 +7834,12 @@ function createFinancialPlugin(options) {
|
|
|
7683
7834
|
registerTranslations(financialLocales);
|
|
7684
7835
|
registerMessageDefaults(buildFinancialMessageDefaults());
|
|
7685
7836
|
const provider = options?.dataProvider ?? createSafeFinancialProvider();
|
|
7686
|
-
const
|
|
7687
|
-
const dashboardWidgets = createFinancialDashboardWidgets({ config, provider, store });
|
|
7837
|
+
const store2 = createFinancialStore(provider);
|
|
7838
|
+
const dashboardWidgets = createFinancialDashboardWidgets({ config, provider, store: store2 });
|
|
7688
7839
|
const registries = [...financialRegistries, ...options?.settingsRegistries ?? []];
|
|
7689
7840
|
const PersonStatementBound = (props) => React18__default.createElement(PersonStatementWidget, { person: props.item, provider, config });
|
|
7690
7841
|
PersonStatementBound.displayName = "FinancialPersonStatement";
|
|
7691
|
-
const PageComponent = () => React18__default.createElement(FinancialPage, { config, provider, store, registries });
|
|
7842
|
+
const PageComponent = () => React18__default.createElement(FinancialPage, { config, provider, store: store2, registries });
|
|
7692
7843
|
return {
|
|
7693
7844
|
id: "financial",
|
|
7694
7845
|
name: config.labels.pageTitle,
|
|
@@ -7909,6 +8060,15 @@ function createFinancialPlugin(options) {
|
|
|
7909
8060
|
permission: { feature: "financial", action: "read" }
|
|
7910
8061
|
}
|
|
7911
8062
|
],
|
|
8063
|
+
// Stripe is the first connector this module implements rather than merely
|
|
8064
|
+
// shelves — it stays in `integrations` too, because the union is what the
|
|
8065
|
+
// catalogue row joins on.
|
|
8066
|
+
connectors: [stripeConnectorDef],
|
|
8067
|
+
// TecnoSpeed is live already — the openbanking addon's `plugbank`
|
|
8068
|
+
// connector IS this slug. AbacatePay and Pagar.me were named as what
|
|
8069
|
+
// having Financeiro should put on the shelf; Mercado Pago, Bling and Stone
|
|
8070
|
+
// come from the Fayz plugin page.
|
|
8071
|
+
integrations: ["tecnospeed", "abacatepay", "pagarme", "stripe", "mercadopago", "bling", "stone"],
|
|
7912
8072
|
locales: financialLocales
|
|
7913
8073
|
};
|
|
7914
8074
|
}
|