@fayz-ai/plugin-financial 0.1.1

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 (98) hide show
  1. package/dist/FinancialContext.d.ts +44 -0
  2. package/dist/FinancialContext.d.ts.map +1 -0
  3. package/dist/FinancialPage.d.ts +18 -0
  4. package/dist/FinancialPage.d.ts.map +1 -0
  5. package/dist/components/FinancialGeneralSettings.d.ts +3 -0
  6. package/dist/components/FinancialGeneralSettings.d.ts.map +1 -0
  7. package/dist/components/FinancialOnboarding.d.ts +5 -0
  8. package/dist/components/FinancialOnboarding.d.ts.map +1 -0
  9. package/dist/components/FinancialSettings.d.ts +8 -0
  10. package/dist/components/FinancialSettings.d.ts.map +1 -0
  11. package/dist/components/PaymentModal.d.ts +8 -0
  12. package/dist/components/PaymentModal.d.ts.map +1 -0
  13. package/dist/data/index.d.ts +3 -0
  14. package/dist/data/index.d.ts.map +1 -0
  15. package/dist/data/mock.d.ts +9 -0
  16. package/dist/data/mock.d.ts.map +1 -0
  17. package/dist/data/supabase.d.ts +3 -0
  18. package/dist/data/supabase.d.ts.map +1 -0
  19. package/dist/data/types.d.ts +27 -0
  20. package/dist/data/types.d.ts.map +1 -0
  21. package/dist/index.cjs +4937 -0
  22. package/dist/index.cjs.map +1 -0
  23. package/dist/index.d.ts +91 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +4930 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/lib/tenant.d.ts +3 -0
  28. package/dist/lib/tenant.d.ts.map +1 -0
  29. package/dist/locales/en.d.ts +2 -0
  30. package/dist/locales/en.d.ts.map +1 -0
  31. package/dist/locales/index.d.ts +2 -0
  32. package/dist/locales/index.d.ts.map +1 -0
  33. package/dist/locales/pt-BR.d.ts +2 -0
  34. package/dist/locales/pt-BR.d.ts.map +1 -0
  35. package/dist/registries.d.ts +3 -0
  36. package/dist/registries.d.ts.map +1 -0
  37. package/dist/store.d.ts +38 -0
  38. package/dist/store.d.ts.map +1 -0
  39. package/dist/types.d.ts +302 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/views/CardsView.d.ts +3 -0
  42. package/dist/views/CardsView.d.ts.map +1 -0
  43. package/dist/views/CashRegistersView.d.ts +3 -0
  44. package/dist/views/CashRegistersView.d.ts.map +1 -0
  45. package/dist/views/CommissionsView.d.ts +3 -0
  46. package/dist/views/CommissionsView.d.ts.map +1 -0
  47. package/dist/views/InvoiceDetailView.d.ts +9 -0
  48. package/dist/views/InvoiceDetailView.d.ts.map +1 -0
  49. package/dist/views/InvoiceFormView.d.ts +13 -0
  50. package/dist/views/InvoiceFormView.d.ts.map +1 -0
  51. package/dist/views/InvoiceListView.d.ts +8 -0
  52. package/dist/views/InvoiceListView.d.ts.map +1 -0
  53. package/dist/views/PayablesView.d.ts +7 -0
  54. package/dist/views/PayablesView.d.ts.map +1 -0
  55. package/dist/views/ReceivablesView.d.ts +7 -0
  56. package/dist/views/ReceivablesView.d.ts.map +1 -0
  57. package/dist/views/StatementsView.d.ts +3 -0
  58. package/dist/views/StatementsView.d.ts.map +1 -0
  59. package/dist/views/SummaryView.d.ts +9 -0
  60. package/dist/views/SummaryView.d.ts.map +1 -0
  61. package/dist/views/dashboardWidgets.d.ts +11 -0
  62. package/dist/views/dashboardWidgets.d.ts.map +1 -0
  63. package/package.json +55 -0
  64. package/src/FinancialContext.tsx +47 -0
  65. package/src/FinancialPage.tsx +261 -0
  66. package/src/README.md +155 -0
  67. package/src/components/FinancialGeneralSettings.tsx +26 -0
  68. package/src/components/FinancialOnboarding.tsx +87 -0
  69. package/src/components/FinancialSettings.tsx +31 -0
  70. package/src/components/PaymentModal.tsx +322 -0
  71. package/src/data/index.ts +2 -0
  72. package/src/data/mock.ts +520 -0
  73. package/src/data/supabase.ts +509 -0
  74. package/src/data/types.ts +53 -0
  75. package/src/index.ts +307 -0
  76. package/src/lib/tenant.ts +3 -0
  77. package/src/locales/en.ts +331 -0
  78. package/src/locales/index.ts +7 -0
  79. package/src/locales/pt-BR.ts +331 -0
  80. package/src/migrations/001_financial_base.sql +109 -0
  81. package/src/migrations/002_chart_of_accounts.sql +28 -0
  82. package/src/migrations/003_card_brands.sql +12 -0
  83. package/src/migrations/004_order_to_cash.sql +164 -0
  84. package/src/migrations/005_seed_defaults.sql +38 -0
  85. package/src/registries.ts +305 -0
  86. package/src/store.ts +221 -0
  87. package/src/types.ts +359 -0
  88. package/src/views/CardsView.tsx +74 -0
  89. package/src/views/CashRegistersView.tsx +597 -0
  90. package/src/views/CommissionsView.tsx +18 -0
  91. package/src/views/InvoiceDetailView.tsx +595 -0
  92. package/src/views/InvoiceFormView.tsx +900 -0
  93. package/src/views/InvoiceListView.tsx +177 -0
  94. package/src/views/PayablesView.tsx +37 -0
  95. package/src/views/ReceivablesView.tsx +37 -0
  96. package/src/views/StatementsView.tsx +123 -0
  97. package/src/views/SummaryView.tsx +12 -0
  98. package/src/views/dashboardWidgets.tsx +191 -0
package/src/types.ts ADDED
@@ -0,0 +1,359 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Financial Module — Pure TypeScript types
3
+ // Zero dependencies. Maps to beautyplace DB schema but with English names.
4
+ // ---------------------------------------------------------------------------
5
+
6
+ // ============================================================
7
+ // ENUMS / LITERALS
8
+ // ============================================================
9
+
10
+ /** Direction: debit (money going out / payable) or credit (money coming in / receivable) */
11
+ export type TransactionDirection = 'debit' | 'credit'
12
+
13
+ /** What kind of financial movement this is */
14
+ export type MovementKind = 'bill' | 'payment' | 'transfer'
15
+
16
+ /** Status of a financial movement */
17
+ export type MovementStatus = 'pending' | 'paid' | 'partial' | 'overdue' | 'cancelled'
18
+
19
+ /** Status of an invoice */
20
+ export type InvoiceStatus = 'draft' | 'open' | 'partial' | 'paid' | 'cancelled' | 'overdue'
21
+
22
+ /** Type of bank account */
23
+ export type BankAccountType = 'bank_account' | 'cash_register' | 'credit_card' | 'digital_wallet'
24
+
25
+ /** Cash session status */
26
+ export type CashSessionStatus = 'open' | 'closed'
27
+
28
+ /** Discount/interest application mode */
29
+ export type AdjustmentMode = 'percentage' | 'fixed'
30
+
31
+ /** Chart of accounts node type */
32
+ export type AccountNodeType = 'group' | 'leaf'
33
+
34
+ /** Item type on an invoice line — parametrizable per vertical */
35
+ export type InvoiceItemKind = string
36
+
37
+ // ============================================================
38
+ // CORE ENTITIES
39
+ // ============================================================
40
+
41
+ export interface Invoice {
42
+ id: string
43
+ direction: TransactionDirection
44
+ invoiceDate: string
45
+ fiscalNumber?: string
46
+ totalAmount: number
47
+ paidAmount: number
48
+ status: InvoiceStatus
49
+ totalInstallments: number
50
+ contactId?: string
51
+ contactName?: string
52
+ cashSessionId?: string
53
+ unitId?: string
54
+ observations?: string
55
+ /** Denormalized summary of item descriptions for list display */
56
+ itemsSummary?: string
57
+ /** If this order has a scheduled time (booking), the start time */
58
+ bookingStartsAt?: string
59
+ metadata?: Record<string, unknown>
60
+ tenantId: string
61
+ createdAt: string
62
+ updatedAt: string
63
+ }
64
+
65
+ export interface InvoiceItem {
66
+ id: string
67
+ invoiceId: string
68
+ itemKind: InvoiceItemKind
69
+ referenceId?: string
70
+ description: string
71
+ quantity: number
72
+ unitPrice: number
73
+ totalAmount: number
74
+ discount: number
75
+ surcharge: number
76
+ accountId?: string
77
+ costCenterId?: string
78
+ // Service execution tracking (opt-in per vertical)
79
+ isExecuted?: boolean
80
+ executionDate?: string
81
+ executedByProfessionalId?: string
82
+ metadata?: Record<string, unknown>
83
+ createdAt: string
84
+ }
85
+
86
+ export interface FinancialMovement {
87
+ id: string
88
+ invoiceId?: string
89
+ direction: TransactionDirection
90
+ movementKind: MovementKind
91
+ amount: number
92
+ paidAmount: number
93
+ status: MovementStatus
94
+ dueDate: string
95
+ paymentDate?: string
96
+ installmentNumber?: number
97
+ paymentMethodId?: string
98
+ paymentMethodTypeId?: string
99
+ bankAccountId?: string
100
+ cashSessionId?: string
101
+ cardBrand?: string
102
+ cardInstallments?: number
103
+ debitAccountId?: string
104
+ creditAccountId?: string
105
+ notes?: string
106
+ metadata?: Record<string, unknown>
107
+ tenantId: string
108
+ createdAt: string
109
+ updatedAt: string
110
+ }
111
+
112
+ export interface BankAccount {
113
+ id: string
114
+ name: string
115
+ accountType: BankAccountType
116
+ bankName?: string
117
+ accountNumber?: string
118
+ agencyNumber?: string
119
+ currentBalance: number
120
+ initialBalance: number
121
+ creditLimit?: number
122
+ dueDay?: number
123
+ closingDay?: number
124
+ isActive: boolean
125
+ unitId?: string
126
+ tenantId: string
127
+ createdAt: string
128
+ updatedAt: string
129
+ }
130
+
131
+ export interface CashSession {
132
+ id: string
133
+ bankAccountId: string
134
+ bankAccountName?: string
135
+ status: CashSessionStatus
136
+ openedAt: string
137
+ openedByUserId?: string
138
+ openedByName?: string
139
+ openingBalance: number
140
+ closedAt?: string
141
+ closedByUserId?: string
142
+ closedByName?: string
143
+ closingBalance?: number
144
+ expectedBalance?: number
145
+ difference?: number
146
+ notes?: string
147
+ unitId?: string
148
+ tenantId: string
149
+ createdAt: string
150
+ }
151
+
152
+ export interface PaymentMethod {
153
+ id: string
154
+ name: string
155
+ paymentMethodTypeId: string
156
+ isActive: boolean
157
+ discountMode?: AdjustmentMode
158
+ discountValue?: number
159
+ interestMode?: AdjustmentMode
160
+ interestValue?: number
161
+ minInstallments: number
162
+ maxInstallments: number
163
+ serviceFilterMode?: 'all' | 'include' | 'exclude'
164
+ serviceFilterIds?: string[]
165
+ tenantId: string
166
+ createdAt: string
167
+ updatedAt: string
168
+ }
169
+
170
+ export interface PaymentMethodType {
171
+ id: string
172
+ name: string
173
+ transactionType?: string
174
+ isActive: boolean
175
+ allowedAccountTypes?: BankAccountType[]
176
+ tenantId: string
177
+ createdAt: string
178
+ }
179
+
180
+ export interface ChartOfAccountsNode {
181
+ id: string
182
+ code: string
183
+ name: string
184
+ nodeType: AccountNodeType
185
+ parentId?: string
186
+ isActive: boolean
187
+ tenantId: string
188
+ createdAt: string
189
+ }
190
+
191
+ export interface CardTransaction {
192
+ id: string
193
+ movementId: string
194
+ cardBrand: string
195
+ totalAmount: number
196
+ installmentCount: number
197
+ currentInstallment: number
198
+ installmentAmount: number
199
+ expectedDate: string
200
+ receivedDate?: string
201
+ fee?: number
202
+ netAmount?: number
203
+ status: 'pending' | 'received' | 'cancelled'
204
+ tenantId: string
205
+ createdAt: string
206
+ }
207
+
208
+ // ============================================================
209
+ // INPUT TYPES (create / mutate)
210
+ // ============================================================
211
+
212
+ export interface CreateInvoiceInput {
213
+ direction: TransactionDirection
214
+ invoiceDate: string
215
+ fiscalNumber?: string
216
+ contactId?: string
217
+ contactName?: string
218
+ cashSessionId?: string
219
+ unitId?: string
220
+ observations?: string
221
+ metadata?: Record<string, unknown>
222
+ items: CreateInvoiceItemInput[]
223
+ installments: CreateMovementInput[]
224
+ }
225
+
226
+ export interface CreateInvoiceItemInput {
227
+ itemKind: InvoiceItemKind
228
+ referenceId?: string
229
+ description: string
230
+ quantity: number
231
+ unitPrice: number
232
+ discount?: number
233
+ surcharge?: number
234
+ accountId?: string
235
+ costCenterId?: string
236
+ metadata?: Record<string, unknown>
237
+ }
238
+
239
+ export interface CreateMovementInput {
240
+ direction: TransactionDirection
241
+ movementKind: MovementKind
242
+ amount: number
243
+ dueDate: string
244
+ installmentNumber?: number
245
+ paymentMethodId?: string
246
+ bankAccountId?: string
247
+ notes?: string
248
+ metadata?: Record<string, unknown>
249
+ }
250
+
251
+ export interface PayMovementInput {
252
+ movementId: string
253
+ amount: number
254
+ paymentDate: string
255
+ paymentMethodId?: string
256
+ paymentMethodTypeId?: string
257
+ bankAccountId?: string
258
+ cashSessionId?: string
259
+ cardBrand?: string
260
+ cardInstallments?: number
261
+ }
262
+
263
+ export interface OpenCashSessionInput {
264
+ bankAccountId: string
265
+ openingBalance: number
266
+ openedByUserId?: string
267
+ openedByName?: string
268
+ unitId?: string
269
+ notes?: string
270
+ }
271
+
272
+ export interface CloseCashSessionInput {
273
+ sessionId: string
274
+ closingBalance: number
275
+ closedByUserId?: string
276
+ closedByName?: string
277
+ notes?: string
278
+ }
279
+
280
+ export interface CreateBankAccountInput {
281
+ name: string
282
+ accountType: BankAccountType
283
+ bankName?: string
284
+ accountNumber?: string
285
+ agencyNumber?: string
286
+ initialBalance?: number
287
+ creditLimit?: number
288
+ dueDay?: number
289
+ closingDay?: number
290
+ unitId?: string
291
+ }
292
+
293
+ // ============================================================
294
+ // QUERY / FILTER TYPES
295
+ // ============================================================
296
+
297
+ export interface DateRange {
298
+ from: string
299
+ to: string
300
+ }
301
+
302
+ export interface InvoiceQuery {
303
+ direction?: TransactionDirection
304
+ status?: InvoiceStatus | InvoiceStatus[]
305
+ contactId?: string
306
+ dateRange?: DateRange
307
+ search?: string
308
+ page?: number
309
+ pageSize?: number
310
+ }
311
+
312
+ export interface MovementQuery {
313
+ direction?: TransactionDirection
314
+ status?: MovementStatus | MovementStatus[]
315
+ bankAccountId?: string
316
+ cashSessionId?: string
317
+ dateRange?: DateRange
318
+ page?: number
319
+ pageSize?: number
320
+ }
321
+
322
+ export interface StatementQuery {
323
+ bankAccountId: string
324
+ dateRange: DateRange
325
+ }
326
+
327
+ export interface PaginatedResult<T> {
328
+ data: T[]
329
+ total: number
330
+ }
331
+
332
+ // ============================================================
333
+ // AGGREGATION TYPES
334
+ // ============================================================
335
+
336
+ export interface FinancialSummary {
337
+ totalBalance: number
338
+ totalReceivable: number
339
+ totalPayable: number
340
+ monthlyInflow: number
341
+ monthlyOutflow: number
342
+ overdueReceivableCount: number
343
+ overdueReceivableAmount: number
344
+ overduePayableCount: number
345
+ overduePayableAmount: number
346
+ }
347
+
348
+ export interface StatementEntry {
349
+ movement: FinancialMovement
350
+ invoice?: Invoice
351
+ runningBalance: number
352
+ }
353
+
354
+ export interface CashSessionSummary {
355
+ session: CashSession
356
+ movementCount: number
357
+ totalInflow: number
358
+ totalOutflow: number
359
+ }
@@ -0,0 +1,74 @@
1
+ import React, { useEffect } from 'react'
2
+ import { CreditCard, Check } from 'lucide-react'
3
+ import { useFinancialConfig, useFinancialStore, formatCurrency } from '../FinancialContext'
4
+ import { SubpageHeader } from '@fayz-ai/ui'
5
+ import { useTranslation } from '@fayz-ai/core'
6
+
7
+ export function CardsView() {
8
+ const t = useTranslation()
9
+ const { currency, labels } = useFinancialConfig()
10
+ const cardTransactions = useFinancialStore((s) => s.cardTransactions)
11
+ const cardsLoading = useFinancialStore((s) => s.cardsLoading)
12
+ const fetchCardTransactions = useFinancialStore((s) => s.fetchCardTransactions)
13
+
14
+ useEffect(() => { fetchCardTransactions() }, [])
15
+
16
+ // Group by card brand
17
+ const byBrand: Record<string, typeof cardTransactions> = {}
18
+ for (const tx of cardTransactions) {
19
+ const brand = tx.cardBrand || 'Other'
20
+ if (!byBrand[brand]) byBrand[brand] = []
21
+ byBrand[brand].push(tx)
22
+ }
23
+
24
+ return (
25
+ <div className="space-y-4">
26
+ <SubpageHeader title={t('financial.cards.title')} subtitle={t('financial.cards.subtitle')} />
27
+ {cardsLoading ? (
28
+ <div className="text-center py-12 text-sm text-muted-foreground">Loading...</div>
29
+ ) : cardTransactions.length === 0 ? (
30
+ <div className="flex flex-col items-center justify-center py-12 text-center rounded-lg border-2 border-dashed border-muted">
31
+ <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-indigo-50 dark:bg-indigo-500/20 mb-2">
32
+ <CreditCard className="h-5 w-5 text-indigo-500" />
33
+ </div>
34
+ <p className="text-sm text-muted-foreground">{t('financial.cards.noTransactions')}</p>
35
+ <p className="text-xs text-muted-foreground mt-0.5">{t('financial.cards.transactionsAppear')}</p>
36
+ </div>
37
+ ) : (
38
+ Object.entries(byBrand).map(([brand, txs]) => (
39
+ <div key={brand} className="rounded-lg border bg-card shadow-sm">
40
+ <div className="flex items-center gap-2 px-4 py-3 border-b">
41
+ <CreditCard className="h-4 w-4 text-indigo-500" />
42
+ <h3 className="text-sm font-semibold">{brand}</h3>
43
+ <span className="text-xs text-muted-foreground">({txs.length} transactions)</span>
44
+ </div>
45
+ <div className="divide-y">
46
+ {txs.map((tx) => (
47
+ <div key={tx.id} className="px-4 py-3 flex items-center justify-between">
48
+ <div>
49
+ <p className="text-sm font-medium">
50
+ Installment {tx.currentInstallment}/{tx.installmentCount}
51
+ </p>
52
+ <p className="text-xs text-muted-foreground">Due: {tx.expectedDate}</p>
53
+ </div>
54
+ <div className="flex items-center gap-3">
55
+ <span className="text-sm font-medium">{formatCurrency(tx.installmentAmount, currency)}</span>
56
+ {tx.status === 'received' ? (
57
+ <span className="inline-flex items-center gap-1 rounded-full bg-success/15 px-2 py-0.5 text-[10px] font-medium text-success dark:bg-success/20">
58
+ <Check className="h-2.5 w-2.5" /> Received
59
+ </span>
60
+ ) : (
61
+ <span className="inline-flex items-center rounded-full bg-warning/15 px-2 py-0.5 text-[10px] font-medium text-warning dark:bg-warning/20">
62
+ Pending
63
+ </span>
64
+ )}
65
+ </div>
66
+ </div>
67
+ ))}
68
+ </div>
69
+ </div>
70
+ ))
71
+ )}
72
+ </div>
73
+ )
74
+ }