@hed-hog/finance 0.0.299 → 0.0.301
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/dto/create-bank-account.dto.d.ts +1 -0
- package/dist/dto/create-bank-account.dto.d.ts.map +1 -1
- package/dist/dto/create-bank-account.dto.js +7 -0
- package/dist/dto/create-bank-account.dto.js.map +1 -1
- package/dist/dto/update-bank-account.dto.d.ts +1 -0
- package/dist/dto/update-bank-account.dto.d.ts.map +1 -1
- package/dist/dto/update-bank-account.dto.js +7 -0
- package/dist/dto/update-bank-account.dto.js.map +1 -1
- package/dist/finance-bank-accounts.controller.d.ts +3 -0
- package/dist/finance-bank-accounts.controller.d.ts.map +1 -1
- package/dist/finance-data.controller.d.ts +1 -0
- package/dist/finance-data.controller.d.ts.map +1 -1
- package/dist/finance.contract-activated.subscriber.d.ts +24 -0
- package/dist/finance.contract-activated.subscriber.d.ts.map +1 -0
- package/dist/finance.contract-activated.subscriber.js +519 -0
- package/dist/finance.contract-activated.subscriber.js.map +1 -0
- package/dist/finance.contract-activated.subscriber.spec.d.ts +2 -0
- package/dist/finance.contract-activated.subscriber.spec.d.ts.map +1 -0
- package/dist/finance.contract-activated.subscriber.spec.js +302 -0
- package/dist/finance.contract-activated.subscriber.spec.js.map +1 -0
- package/dist/finance.module.d.ts.map +1 -1
- package/dist/finance.module.js +6 -1
- package/dist/finance.module.js.map +1 -1
- package/dist/finance.service.d.ts +4 -0
- package/dist/finance.service.d.ts.map +1 -1
- package/dist/finance.service.js +5 -0
- package/dist/finance.service.js.map +1 -1
- package/hedhog/data/dashboard.yaml +6 -0
- package/hedhog/data/dashboard_component.yaml +72 -17
- package/hedhog/data/dashboard_component_role.yaml +30 -0
- package/hedhog/data/dashboard_item.yaml +155 -0
- package/hedhog/data/dashboard_role.yaml +6 -0
- package/hedhog/data/role_menu.yaml +6 -0
- package/hedhog/data/role_route.yaml +127 -0
- package/hedhog/frontend/app/_components/finance-layout.tsx.ejs +108 -0
- package/hedhog/frontend/app/accounts-payable/approvals/page.tsx.ejs +91 -106
- package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +1306 -1145
- package/hedhog/frontend/app/accounts-receivable/collections-default/page.tsx.ejs +288 -268
- package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +491 -351
- package/hedhog/frontend/app/administration/audit-logs/page.tsx.ejs +157 -173
- package/hedhog/frontend/app/administration/categories/page.tsx.ejs +44 -62
- package/hedhog/frontend/app/administration/cost-centers/page.tsx.ejs +62 -80
- package/hedhog/frontend/app/administration/period-close/page.tsx.ejs +151 -170
- package/hedhog/frontend/app/cash-and-banks/bank-accounts/page.tsx.ejs +586 -224
- package/hedhog/frontend/app/cash-and-banks/bank-reconciliation/page.tsx.ejs +204 -226
- package/hedhog/frontend/app/cash-and-banks/statements/page.tsx.ejs +122 -140
- package/hedhog/frontend/app/cash-and-banks/transfers/page.tsx.ejs +32 -49
- package/hedhog/frontend/app/planning/cash-flow-forecast/page.tsx.ejs +84 -108
- package/hedhog/frontend/app/planning/receivables-calendar/page.tsx.ejs +53 -70
- package/hedhog/frontend/app/planning/scenarios/page.tsx.ejs +98 -95
- package/hedhog/frontend/app/reports/actual-vs-forecast/page.tsx.ejs +100 -125
- package/hedhog/frontend/app/reports/aging-default/page.tsx.ejs +77 -105
- package/hedhog/frontend/app/reports/cash-position/page.tsx.ejs +99 -134
- package/hedhog/frontend/app/reports/overview-results/page.tsx.ejs +147 -182
- package/hedhog/frontend/app/reports/top-customers/page.tsx.ejs +49 -61
- package/hedhog/frontend/app/reports/top-operational-expenses/page.tsx.ejs +49 -67
- package/hedhog/frontend/messages/en.json +224 -70
- package/hedhog/frontend/messages/pt.json +224 -70
- package/hedhog/frontend/widgets/alerts.tsx.ejs +1 -1
- package/hedhog/frontend/widgets/bank-reconciliation-status.tsx.ejs +142 -0
- package/hedhog/frontend/widgets/cash-balance-kpi.tsx.ejs +9 -9
- package/hedhog/frontend/widgets/cash-flow-chart.tsx.ejs +1 -1
- package/hedhog/frontend/widgets/default-kpi.tsx.ejs +9 -9
- package/hedhog/frontend/widgets/payable-30d-kpi.tsx.ejs +9 -9
- package/hedhog/frontend/widgets/pending-approvals-kpi.tsx.ejs +78 -0
- package/hedhog/frontend/widgets/pending-approvals-list.tsx.ejs +147 -0
- package/hedhog/frontend/widgets/pending-reconciliation-kpi.tsx.ejs +84 -0
- package/hedhog/frontend/widgets/receivable-30d-kpi.tsx.ejs +9 -9
- package/hedhog/frontend/widgets/receivable-aging-analysis.tsx.ejs +163 -0
- package/hedhog/frontend/widgets/upcoming-payable.tsx.ejs +1 -1
- package/hedhog/frontend/widgets/upcoming-receivable.tsx.ejs +1 -1
- package/hedhog/table/bank_account.yaml +8 -0
- package/package.json +7 -6
- package/src/dto/create-bank-account.dto.ts +7 -1
- package/src/dto/update-bank-account.dto.ts +7 -1
- package/src/finance.contract-activated.subscriber.spec.ts +392 -0
- package/src/finance.contract-activated.subscriber.ts +780 -0
- package/src/finance.module.ts +6 -1
- package/src/finance.service.ts +4 -0
|
@@ -38,8 +38,44 @@
|
|
|
38
38
|
"default": {
|
|
39
39
|
"title": "Inadimplência",
|
|
40
40
|
"description": "Títulos vencidos"
|
|
41
|
+
},
|
|
42
|
+
"pendingApprovals": {
|
|
43
|
+
"title": "Aprovações",
|
|
44
|
+
"countLabel": "abertas",
|
|
45
|
+
"description": "Em análise: {value}"
|
|
46
|
+
},
|
|
47
|
+
"pendingReconciliation": {
|
|
48
|
+
"title": "Conciliação",
|
|
49
|
+
"countLabel": "pendentes",
|
|
50
|
+
"description": "Contas ativas: {value}"
|
|
41
51
|
}
|
|
42
52
|
},
|
|
53
|
+
"bankReconciliation": {
|
|
54
|
+
"title": "Conciliação Bancária",
|
|
55
|
+
"description": "Extratos pendentes e diferenças por conta",
|
|
56
|
+
"pending": "Pendentes",
|
|
57
|
+
"reconciled": "Conciliados",
|
|
58
|
+
"accounts": "Contas",
|
|
59
|
+
"difference": "Diferença a revisar",
|
|
60
|
+
"allClear": "Todas as contas ativas estão conciliadas.",
|
|
61
|
+
"unnamedAccount": "Conta sem nome"
|
|
62
|
+
},
|
|
63
|
+
"approvalQueue": {
|
|
64
|
+
"title": "Fila de Aprovações",
|
|
65
|
+
"description": "Aprovações financeiras mais recentes aguardando ação",
|
|
66
|
+
"defaultPolicy": "Aprovação financeira",
|
|
67
|
+
"empty": "Não há aprovações pendentes no momento."
|
|
68
|
+
},
|
|
69
|
+
"aging": {
|
|
70
|
+
"title": "Aging de Recebíveis",
|
|
71
|
+
"description": "Inadimplência segmentada por faixa de atraso",
|
|
72
|
+
"totalLabel": "Total em atraso",
|
|
73
|
+
"clientsLabel": "Clientes impactados",
|
|
74
|
+
"range0to30": "0-30 dias",
|
|
75
|
+
"range31to60": "31-60 dias",
|
|
76
|
+
"range61to90": "61-90 dias",
|
|
77
|
+
"range90plus": "90+ dias"
|
|
78
|
+
},
|
|
43
79
|
"cashFlow": {
|
|
44
80
|
"title": "Fluxo de Caixa",
|
|
45
81
|
"description": "Previsto vs Realizado"
|
|
@@ -94,11 +130,12 @@
|
|
|
94
130
|
"actions": "Ações"
|
|
95
131
|
}
|
|
96
132
|
},
|
|
97
|
-
"empty": {
|
|
98
|
-
"title": "Tudo em dia!",
|
|
99
|
-
"description": "Não há aprovações pendentes."
|
|
100
|
-
|
|
101
|
-
|
|
133
|
+
"empty": {
|
|
134
|
+
"title": "Tudo em dia!",
|
|
135
|
+
"description": "Não há aprovações pendentes.",
|
|
136
|
+
"refresh": "Atualizar"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
102
139
|
"PersonFieldWithCreate": {
|
|
103
140
|
"sheet": {
|
|
104
141
|
"title": "Novo {entityLabel}",
|
|
@@ -233,33 +270,71 @@
|
|
|
233
270
|
"cash": "Dinheiro",
|
|
234
271
|
"check": "Cheque"
|
|
235
272
|
},
|
|
236
|
-
"header": {
|
|
237
|
-
"title": "Títulos a Pagar",
|
|
238
|
-
"description": "Gerencie suas contas a pagar"
|
|
239
|
-
},
|
|
240
|
-
"
|
|
241
|
-
"
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
273
|
+
"header": {
|
|
274
|
+
"title": "Títulos a Pagar",
|
|
275
|
+
"description": "Gerencie suas contas a pagar"
|
|
276
|
+
},
|
|
277
|
+
"summary": {
|
|
278
|
+
"cards": {
|
|
279
|
+
"visible": {
|
|
280
|
+
"title": "Títulos exibidos",
|
|
281
|
+
"description": "{total} registros no total"
|
|
282
|
+
},
|
|
283
|
+
"value": {
|
|
284
|
+
"title": "Valor visível",
|
|
285
|
+
"description": "Somatório da página atual"
|
|
286
|
+
},
|
|
287
|
+
"attention": {
|
|
288
|
+
"title": "Pendentes",
|
|
289
|
+
"description": "{overdue} com atraso"
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
"breadcrumbs": {
|
|
294
|
+
"home": "Início",
|
|
295
|
+
"finance": "Financeiro",
|
|
296
|
+
"current": "Títulos a Pagar"
|
|
297
|
+
},
|
|
245
298
|
"filters": {
|
|
246
299
|
"searchPlaceholder": "Buscar por documento ou fornecedor...",
|
|
247
300
|
"status": "Status"
|
|
248
301
|
},
|
|
249
|
-
"statuses": {
|
|
250
|
-
"all": "Todos",
|
|
251
|
-
"rascunho": "Rascunho",
|
|
252
|
-
"aprovado": "Aprovado",
|
|
253
|
-
"aberto": "Aberto",
|
|
302
|
+
"statuses": {
|
|
303
|
+
"all": "Todos",
|
|
304
|
+
"rascunho": "Rascunho",
|
|
305
|
+
"aprovado": "Aprovado",
|
|
306
|
+
"aberto": "Aberto",
|
|
254
307
|
"parcial": "Parcial",
|
|
255
308
|
"liquidado": "Liquidado",
|
|
256
|
-
"vencido": "Vencido",
|
|
257
|
-
"cancelado": "Cancelado"
|
|
258
|
-
},
|
|
259
|
-
"
|
|
260
|
-
"
|
|
261
|
-
|
|
262
|
-
|
|
309
|
+
"vencido": "Vencido",
|
|
310
|
+
"cancelado": "Cancelado"
|
|
311
|
+
},
|
|
312
|
+
"list": {
|
|
313
|
+
"title": "Carteira de títulos",
|
|
314
|
+
"description": "Acompanhe documentos, vencimentos e ações operacionais da página atual."
|
|
315
|
+
},
|
|
316
|
+
"sections": {
|
|
317
|
+
"main": {
|
|
318
|
+
"title": "Dados principais",
|
|
319
|
+
"description": "Informe documento, fornecedor, datas e valor total do título."
|
|
320
|
+
},
|
|
321
|
+
"installments": {
|
|
322
|
+
"title": "Parcelas",
|
|
323
|
+
"description": "Revise o cronograma de vencimentos e ajuste os valores antes de salvar."
|
|
324
|
+
},
|
|
325
|
+
"classification": {
|
|
326
|
+
"title": "Classificação financeira",
|
|
327
|
+
"description": "Associe categoria, centro de custo e forma de pagamento para organizar a operação."
|
|
328
|
+
},
|
|
329
|
+
"notes": {
|
|
330
|
+
"title": "Observações",
|
|
331
|
+
"description": "Use este campo para complementar o contexto do título quando necessário."
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
"table": {
|
|
335
|
+
"headers": {
|
|
336
|
+
"document": "Documento",
|
|
337
|
+
"supplier": "Fornecedor",
|
|
263
338
|
"competency": "Competência",
|
|
264
339
|
"dueDate": "Vencimento",
|
|
265
340
|
"value": "Valor",
|
|
@@ -297,12 +372,18 @@
|
|
|
297
372
|
"confirm": "Confirmar estorno"
|
|
298
373
|
}
|
|
299
374
|
},
|
|
300
|
-
"settleSheet": {
|
|
301
|
-
"title": "Registrar baixa",
|
|
302
|
-
"description": "Informe a parcela e o valor da baixa para o título {document}.",
|
|
303
|
-
"
|
|
304
|
-
|
|
305
|
-
|
|
375
|
+
"settleSheet": {
|
|
376
|
+
"title": "Registrar baixa",
|
|
377
|
+
"description": "Informe a parcela e o valor da baixa para o título {document}.",
|
|
378
|
+
"sections": {
|
|
379
|
+
"payment": {
|
|
380
|
+
"title": "Dados da baixa",
|
|
381
|
+
"description": "Selecione a parcela disponível e confirme o valor a ser liquidado."
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
"installmentLabel": "Parcela",
|
|
385
|
+
"installmentPlaceholder": "Selecione",
|
|
386
|
+
"installmentOption": "Parcela {number} - em aberto: {amount}",
|
|
306
387
|
"amountLabel": "Valor",
|
|
307
388
|
"descriptionLabel": "Descrição (opcional)",
|
|
308
389
|
"confirm": "Confirmar baixa"
|
|
@@ -635,31 +716,69 @@
|
|
|
635
716
|
"card": "Cartão",
|
|
636
717
|
"transfer": "Transferência"
|
|
637
718
|
},
|
|
638
|
-
"header": {
|
|
639
|
-
"title": "Títulos a Receber",
|
|
640
|
-
"description": "Gerencie suas contas a receber"
|
|
641
|
-
},
|
|
642
|
-
"
|
|
643
|
-
"
|
|
644
|
-
|
|
645
|
-
|
|
719
|
+
"header": {
|
|
720
|
+
"title": "Títulos a Receber",
|
|
721
|
+
"description": "Gerencie suas contas a receber"
|
|
722
|
+
},
|
|
723
|
+
"summary": {
|
|
724
|
+
"cards": {
|
|
725
|
+
"visible": {
|
|
726
|
+
"title": "Títulos exibidos",
|
|
727
|
+
"description": "{total} registros no total"
|
|
728
|
+
},
|
|
729
|
+
"value": {
|
|
730
|
+
"title": "Valor visível",
|
|
731
|
+
"description": "Somatório da página atual"
|
|
732
|
+
},
|
|
733
|
+
"attention": {
|
|
734
|
+
"title": "Pendentes",
|
|
735
|
+
"description": "{overdue} com atraso"
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
},
|
|
739
|
+
"breadcrumbs": {
|
|
740
|
+
"home": "Início",
|
|
741
|
+
"finance": "Financeiro",
|
|
742
|
+
"current": "Títulos a Receber"
|
|
646
743
|
},
|
|
647
744
|
"filters": {
|
|
648
745
|
"searchPlaceholder": "Buscar por documento ou cliente...",
|
|
649
746
|
"status": "Status"
|
|
650
747
|
},
|
|
651
|
-
"statuses": {
|
|
652
|
-
"all": "Todos",
|
|
653
|
-
"aberto": "Aberto",
|
|
654
|
-
"parcial": "Parcial",
|
|
655
|
-
"liquidado": "Liquidado",
|
|
656
|
-
"vencido": "Vencido",
|
|
657
|
-
"cancelado": "Cancelado"
|
|
658
|
-
},
|
|
659
|
-
"
|
|
660
|
-
"
|
|
661
|
-
|
|
662
|
-
|
|
748
|
+
"statuses": {
|
|
749
|
+
"all": "Todos",
|
|
750
|
+
"aberto": "Aberto",
|
|
751
|
+
"parcial": "Parcial",
|
|
752
|
+
"liquidado": "Liquidado",
|
|
753
|
+
"vencido": "Vencido",
|
|
754
|
+
"cancelado": "Cancelado"
|
|
755
|
+
},
|
|
756
|
+
"list": {
|
|
757
|
+
"title": "Carteira de recebíveis",
|
|
758
|
+
"description": "Acompanhe clientes, vencimentos e ações operacionais da página atual."
|
|
759
|
+
},
|
|
760
|
+
"sections": {
|
|
761
|
+
"main": {
|
|
762
|
+
"title": "Dados principais",
|
|
763
|
+
"description": "Informe documento, cliente, datas e valor total do título."
|
|
764
|
+
},
|
|
765
|
+
"installments": {
|
|
766
|
+
"title": "Parcelas",
|
|
767
|
+
"description": "Revise o cronograma de vencimentos e ajuste os valores antes de salvar."
|
|
768
|
+
},
|
|
769
|
+
"classification": {
|
|
770
|
+
"title": "Classificação financeira",
|
|
771
|
+
"description": "Associe categoria, centro de custo e canal de recebimento para organizar a operação."
|
|
772
|
+
},
|
|
773
|
+
"notes": {
|
|
774
|
+
"title": "Observações",
|
|
775
|
+
"description": "Use este campo para complementar o contexto do título quando necessário."
|
|
776
|
+
}
|
|
777
|
+
},
|
|
778
|
+
"table": {
|
|
779
|
+
"headers": {
|
|
780
|
+
"document": "Documento",
|
|
781
|
+
"client": "Cliente",
|
|
663
782
|
"competency": "Competência",
|
|
664
783
|
"dueDate": "Vencimento",
|
|
665
784
|
"value": "Valor",
|
|
@@ -674,15 +793,20 @@
|
|
|
674
793
|
"sendCollection": "Enviar Cobrança",
|
|
675
794
|
"openAttachment": "Abrir anexo"
|
|
676
795
|
}
|
|
677
|
-
},
|
|
678
|
-
"
|
|
679
|
-
"title": "
|
|
680
|
-
"
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
"
|
|
684
|
-
"
|
|
685
|
-
"
|
|
796
|
+
},
|
|
797
|
+
"empty": {
|
|
798
|
+
"title": "Nenhum título encontrado",
|
|
799
|
+
"description": "Cadastre o primeiro título para começar a gerenciar contas a receber."
|
|
800
|
+
},
|
|
801
|
+
"installmentsEditor": {
|
|
802
|
+
"title": "Parcelas",
|
|
803
|
+
"countLabel": "Quantidade de Parcelas",
|
|
804
|
+
"recalculate": "Recalcular automaticamente",
|
|
805
|
+
"autoRedistributeLabel": "Redistribuir automaticamente o restante ao editar parcela",
|
|
806
|
+
"autoRedistributeHint": "A redistribuição ocorre ao parar de digitar e ao sair do campo.",
|
|
807
|
+
"dueDateLabel": "Vencimento",
|
|
808
|
+
"amountLabel": "Valor",
|
|
809
|
+
"totalPrefix": "Soma das parcelas: {total}",
|
|
686
810
|
"adjustmentNeeded": "(ajuste necessário)"
|
|
687
811
|
},
|
|
688
812
|
"editTitle": {
|
|
@@ -837,7 +961,12 @@
|
|
|
837
961
|
"updateSuccess": "Conta bancária atualizada com sucesso",
|
|
838
962
|
"updateError": "Erro ao atualizar conta bancária",
|
|
839
963
|
"deleteSuccess": "Conta bancária inativada com sucesso",
|
|
840
|
-
"deleteError": "Erro ao inativar conta bancária"
|
|
964
|
+
"deleteError": "Erro ao inativar conta bancária",
|
|
965
|
+
"logoUploadSuccess": "Logo enviado com sucesso",
|
|
966
|
+
"logoUploadError": "Erro ao enviar logo",
|
|
967
|
+
"logoRemoveSuccess": "Logo removido com sucesso",
|
|
968
|
+
"logoInvalidType": "Selecione um arquivo de imagem válido",
|
|
969
|
+
"logoTooLarge": "O logo deve ter no máximo 5 MB"
|
|
841
970
|
},
|
|
842
971
|
"deleteDialog": {
|
|
843
972
|
"title": "Inativar conta bancária",
|
|
@@ -863,7 +992,12 @@
|
|
|
863
992
|
"type": "Tipo",
|
|
864
993
|
"description": "Descrição",
|
|
865
994
|
"descriptionPlaceholder": "Ex: Conta Principal",
|
|
866
|
-
"initialBalance": "Saldo Inicial"
|
|
995
|
+
"initialBalance": "Saldo Inicial",
|
|
996
|
+
"logo": "Logo",
|
|
997
|
+
"logoAction": "Enviar logo",
|
|
998
|
+
"logoRemove": "Remover logo",
|
|
999
|
+
"logoHint": "Opcional. Use preferencialmente uma imagem quadrada.",
|
|
1000
|
+
"logoUploading": "Enviando logo... {progress}%"
|
|
867
1001
|
},
|
|
868
1002
|
"header": {
|
|
869
1003
|
"title": "Contas Bancárias",
|
|
@@ -874,13 +1008,33 @@
|
|
|
874
1008
|
"finance": "Financeiro",
|
|
875
1009
|
"current": "Contas Bancárias"
|
|
876
1010
|
},
|
|
877
|
-
"cards": {
|
|
878
|
-
"totalBalance": "Saldo Total",
|
|
879
|
-
"activeAccounts": "{count} contas ativas",
|
|
880
|
-
"reconciledBalance": "Saldo Conciliado",
|
|
881
|
-
"difference": "Diferença"
|
|
882
|
-
|
|
883
|
-
|
|
1011
|
+
"cards": {
|
|
1012
|
+
"totalBalance": "Saldo Total",
|
|
1013
|
+
"activeAccounts": "{count} contas ativas",
|
|
1014
|
+
"reconciledBalance": "Saldo Conciliado",
|
|
1015
|
+
"difference": "Diferença",
|
|
1016
|
+
"accountsOverview": "Contas ativas",
|
|
1017
|
+
"inactiveAccounts": "{count} contas inativas"
|
|
1018
|
+
},
|
|
1019
|
+
"sections": {
|
|
1020
|
+
"accountData": {
|
|
1021
|
+
"title": "Dados da conta",
|
|
1022
|
+
"description": "Preencha os dados principais para identificar e classificar a conta bancária."
|
|
1023
|
+
},
|
|
1024
|
+
"logo": {
|
|
1025
|
+
"title": "Logo e identificação visual",
|
|
1026
|
+
"description": "Adicione uma imagem opcional para facilitar a identificação da conta nas listagens."
|
|
1027
|
+
}
|
|
1028
|
+
},
|
|
1029
|
+
"list": {
|
|
1030
|
+
"title": "Contas cadastradas",
|
|
1031
|
+
"description": "Acompanhe saldos, conciliação e acessos rápidos para cada conta bancária."
|
|
1032
|
+
},
|
|
1033
|
+
"empty": {
|
|
1034
|
+
"title": "Nenhuma conta bancária cadastrada",
|
|
1035
|
+
"description": "Crie a primeira conta para começar a registrar saldos, extratos e conciliações."
|
|
1036
|
+
},
|
|
1037
|
+
"status": { "inactive": "Inativa" },
|
|
884
1038
|
"accountCard": {
|
|
885
1039
|
"bankAccount": "Ag: {agency} | Cc: {account}",
|
|
886
1040
|
"currentBalance": "Saldo Atual",
|
|
@@ -5,7 +5,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
|
5
5
|
import { useWidgetData } from '@/hooks/use-widget-data';
|
|
6
6
|
import { AlertTriangle } from 'lucide-react';
|
|
7
7
|
import { useLocale, useTranslations } from 'next-intl';
|
|
8
|
-
import { WidgetWrapper } from '
|
|
8
|
+
import { WidgetWrapper } from '@/app/(app)/(libraries)/core/dashboard/components';
|
|
9
9
|
|
|
10
10
|
interface FinanceData {
|
|
11
11
|
titulosPagar?: Array<{
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { WidgetWrapper } from '@/app/(app)/(libraries)/core/dashboard/components';
|
|
4
|
+
import { Badge } from '@/components/ui/badge';
|
|
5
|
+
import {
|
|
6
|
+
Card,
|
|
7
|
+
CardContent,
|
|
8
|
+
CardDescription,
|
|
9
|
+
CardHeader,
|
|
10
|
+
CardTitle,
|
|
11
|
+
} from '@/components/ui/card';
|
|
12
|
+
import { Money } from '@/components/ui/money';
|
|
13
|
+
import { useWidgetData } from '@/hooks/use-widget-data';
|
|
14
|
+
import { Landmark } from 'lucide-react';
|
|
15
|
+
import { useTranslations } from 'next-intl';
|
|
16
|
+
|
|
17
|
+
interface ReconciliationWidgetProps {
|
|
18
|
+
widget?: { name?: string };
|
|
19
|
+
onRemove?: () => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface FinanceData {
|
|
23
|
+
extratos?: Array<{
|
|
24
|
+
statusConciliacao?: string | null;
|
|
25
|
+
}>;
|
|
26
|
+
contasBancarias?: Array<{
|
|
27
|
+
id: string;
|
|
28
|
+
banco?: string | null;
|
|
29
|
+
nome?: string | null;
|
|
30
|
+
saldoAtual?: number | null;
|
|
31
|
+
saldoConciliado?: number | null;
|
|
32
|
+
ativo?: boolean | null;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const normalize = (value?: string | null) =>
|
|
37
|
+
String(value || '')
|
|
38
|
+
.normalize('NFD')
|
|
39
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
40
|
+
.toLowerCase();
|
|
41
|
+
|
|
42
|
+
export default function BankReconciliationStatus({
|
|
43
|
+
widget,
|
|
44
|
+
onRemove,
|
|
45
|
+
}: ReconciliationWidgetProps) {
|
|
46
|
+
const t = useTranslations('finance.DashboardPage');
|
|
47
|
+
|
|
48
|
+
const { data, isLoading, isAccessDenied, isError } =
|
|
49
|
+
useWidgetData<FinanceData>({
|
|
50
|
+
endpoint: '/finance/data',
|
|
51
|
+
queryKey: 'finance-bank-reconciliation-status',
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const statements = data?.extratos || [];
|
|
55
|
+
const bankAccounts = (data?.contasBancarias || []).filter(
|
|
56
|
+
(account) => account?.ativo !== false
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const pendingCount = statements.filter((statement) =>
|
|
60
|
+
normalize(statement?.statusConciliacao).includes('pend')
|
|
61
|
+
).length;
|
|
62
|
+
const reconciledCount = Math.max(statements.length - pendingCount, 0);
|
|
63
|
+
|
|
64
|
+
const accountDiffs = bankAccounts
|
|
65
|
+
.map((account) => ({
|
|
66
|
+
id: account.id,
|
|
67
|
+
name: account.nome || account.banco || t('bankReconciliation.unnamedAccount'),
|
|
68
|
+
difference: Math.abs(
|
|
69
|
+
Number(account.saldoAtual || 0) - Number(account.saldoConciliado || 0)
|
|
70
|
+
),
|
|
71
|
+
}))
|
|
72
|
+
.sort((a, b) => b.difference - a.difference);
|
|
73
|
+
|
|
74
|
+
const totalDifference = accountDiffs.reduce(
|
|
75
|
+
(acc, account) => acc + account.difference,
|
|
76
|
+
0
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<WidgetWrapper
|
|
81
|
+
isLoading={isLoading}
|
|
82
|
+
isAccessDenied={isAccessDenied}
|
|
83
|
+
isError={isError}
|
|
84
|
+
widgetName={widget?.name || t('bankReconciliation.title')}
|
|
85
|
+
onRemove={onRemove}
|
|
86
|
+
>
|
|
87
|
+
<Card className="flex h-full flex-col">
|
|
88
|
+
<CardHeader className="pb-2">
|
|
89
|
+
<CardTitle className="flex items-center gap-2 text-base">
|
|
90
|
+
<Landmark className="h-4 w-4 text-sky-600" />
|
|
91
|
+
{t('bankReconciliation.title')}
|
|
92
|
+
</CardTitle>
|
|
93
|
+
<CardDescription>{t('bankReconciliation.description')}</CardDescription>
|
|
94
|
+
</CardHeader>
|
|
95
|
+
<CardContent className="flex flex-1 flex-col gap-3 pt-0">
|
|
96
|
+
<div className="flex flex-wrap gap-2">
|
|
97
|
+
<Badge variant="outline" className="border-amber-200 bg-amber-50 text-amber-700">
|
|
98
|
+
{t('bankReconciliation.pending')}: {pendingCount}
|
|
99
|
+
</Badge>
|
|
100
|
+
<Badge variant="outline" className="border-emerald-200 bg-emerald-50 text-emerald-700">
|
|
101
|
+
{t('bankReconciliation.reconciled')}: {reconciledCount}
|
|
102
|
+
</Badge>
|
|
103
|
+
<Badge variant="secondary" className="bg-slate-100 text-slate-700">
|
|
104
|
+
{t('bankReconciliation.accounts')}: {bankAccounts.length}
|
|
105
|
+
</Badge>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<div className="rounded-lg bg-muted/40 p-3">
|
|
109
|
+
<p className="text-[11px] font-medium uppercase tracking-[0.18em] text-muted-foreground">
|
|
110
|
+
{t('bankReconciliation.difference')}
|
|
111
|
+
</p>
|
|
112
|
+
<p className="text-lg font-semibold text-foreground">
|
|
113
|
+
<Money value={totalDifference} />
|
|
114
|
+
</p>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<div className="space-y-2">
|
|
118
|
+
{accountDiffs.slice(0, 3).map((account) => (
|
|
119
|
+
<div
|
|
120
|
+
key={account.id}
|
|
121
|
+
className="flex items-center justify-between rounded-md border border-border/60 px-3 py-2"
|
|
122
|
+
>
|
|
123
|
+
<span className="truncate pr-3 text-sm text-foreground">
|
|
124
|
+
{account.name}
|
|
125
|
+
</span>
|
|
126
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
127
|
+
<Money value={account.difference} />
|
|
128
|
+
</span>
|
|
129
|
+
</div>
|
|
130
|
+
))}
|
|
131
|
+
|
|
132
|
+
{accountDiffs.length === 0 && (
|
|
133
|
+
<div className="rounded-md border border-dashed border-emerald-200 bg-emerald-50 px-3 py-4 text-sm text-emerald-700">
|
|
134
|
+
{t('bankReconciliation.allClear')}
|
|
135
|
+
</div>
|
|
136
|
+
)}
|
|
137
|
+
</div>
|
|
138
|
+
</CardContent>
|
|
139
|
+
</Card>
|
|
140
|
+
</WidgetWrapper>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
@@ -4,7 +4,7 @@ import { Card, CardContent } from '@/components/ui/card';
|
|
|
4
4
|
import { useWidgetData } from '@/hooks/use-widget-data';
|
|
5
5
|
import { Wallet } from 'lucide-react';
|
|
6
6
|
import { useTranslations } from 'next-intl';
|
|
7
|
-
import { WidgetWrapper } from '
|
|
7
|
+
import { WidgetWrapper } from '@/app/(app)/(libraries)/core/dashboard/components';
|
|
8
8
|
|
|
9
9
|
interface CashBalanceKpiProps {
|
|
10
10
|
widget?: { name?: string };
|
|
@@ -43,19 +43,19 @@ export default function CashBalanceKpi({
|
|
|
43
43
|
widgetName={widget?.name || t('kpis.cashBalance.title')}
|
|
44
44
|
onRemove={onRemove}
|
|
45
45
|
>
|
|
46
|
-
<Card className="h-full overflow-hidden transition-all duration-300 hover:shadow-md">
|
|
47
|
-
<CardContent className="flex h-full items-center gap-
|
|
48
|
-
<div className="flex h-
|
|
49
|
-
<Wallet className="h-5 w-5 text-emerald-600" />
|
|
46
|
+
<Card className="h-full overflow-hidden border-border/60 bg-linear-to-br from-background to-emerald-50/40 shadow-sm transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md">
|
|
47
|
+
<CardContent className="flex h-full items-center gap-2.5 p-3">
|
|
48
|
+
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-emerald-100/80">
|
|
49
|
+
<Wallet className="h-4.5 w-4.5 text-emerald-600" />
|
|
50
50
|
</div>
|
|
51
|
-
<div className="flex min-w-0 flex-col">
|
|
52
|
-
<span className="text-[
|
|
51
|
+
<div className="flex min-w-0 flex-1 flex-col justify-center">
|
|
52
|
+
<span className="text-[9px] font-semibold uppercase tracking-[0.18em] text-muted-foreground">
|
|
53
53
|
{t('kpis.cashBalance.title')}
|
|
54
54
|
</span>
|
|
55
|
-
<span className="truncate text-
|
|
55
|
+
<span className="truncate text-base font-bold leading-none tracking-tight text-foreground sm:text-lg">
|
|
56
56
|
{formatted}
|
|
57
57
|
</span>
|
|
58
|
-
<span className="text-[
|
|
58
|
+
<span className="truncate text-[9px] text-muted-foreground">
|
|
59
59
|
{t('kpis.cashBalance.description')}
|
|
60
60
|
</span>
|
|
61
61
|
</div>
|
|
@@ -4,7 +4,7 @@ import { Card, CardContent } from '@/components/ui/card';
|
|
|
4
4
|
import { useWidgetData } from '@/hooks/use-widget-data';
|
|
5
5
|
import { AlertTriangle } from 'lucide-react';
|
|
6
6
|
import { useTranslations } from 'next-intl';
|
|
7
|
-
import { WidgetWrapper } from '
|
|
7
|
+
import { WidgetWrapper } from '@/app/(app)/(libraries)/core/dashboard/components';
|
|
8
8
|
|
|
9
9
|
interface DefaultKpiProps {
|
|
10
10
|
widget?: { name?: string };
|
|
@@ -40,19 +40,19 @@ export default function DefaultKpi({ widget, onRemove }: DefaultKpiProps) {
|
|
|
40
40
|
widgetName={widget?.name || t('kpis.default.title')}
|
|
41
41
|
onRemove={onRemove}
|
|
42
42
|
>
|
|
43
|
-
<Card className="h-full overflow-hidden transition-all duration-300 hover:shadow-md">
|
|
44
|
-
<CardContent className="flex h-full items-center gap-
|
|
45
|
-
<div className="flex h-
|
|
46
|
-
<AlertTriangle className="h-5 w-5 text-amber-600" />
|
|
43
|
+
<Card className="h-full overflow-hidden border-border/60 bg-linear-to-br from-background to-amber-50/50 shadow-sm transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md">
|
|
44
|
+
<CardContent className="flex h-full items-center gap-2.5 p-3">
|
|
45
|
+
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-amber-100/80">
|
|
46
|
+
<AlertTriangle className="h-4.5 w-4.5 text-amber-600" />
|
|
47
47
|
</div>
|
|
48
|
-
<div className="flex min-w-0 flex-col">
|
|
49
|
-
<span className="text-[
|
|
48
|
+
<div className="flex min-w-0 flex-1 flex-col justify-center">
|
|
49
|
+
<span className="text-[9px] font-semibold uppercase tracking-[0.18em] text-muted-foreground">
|
|
50
50
|
{t('kpis.default.title')}
|
|
51
51
|
</span>
|
|
52
|
-
<span className="truncate text-
|
|
52
|
+
<span className="truncate text-base font-bold leading-none tracking-tight text-foreground sm:text-lg">
|
|
53
53
|
{formatted}
|
|
54
54
|
</span>
|
|
55
|
-
<span className="text-[
|
|
55
|
+
<span className="truncate text-[9px] text-muted-foreground">
|
|
56
56
|
{t('kpis.default.description')}
|
|
57
57
|
</span>
|
|
58
58
|
</div>
|
|
@@ -4,7 +4,7 @@ import { Card, CardContent } from '@/components/ui/card';
|
|
|
4
4
|
import { useWidgetData } from '@/hooks/use-widget-data';
|
|
5
5
|
import { TrendingDown } from 'lucide-react';
|
|
6
6
|
import { useTranslations } from 'next-intl';
|
|
7
|
-
import { WidgetWrapper } from '
|
|
7
|
+
import { WidgetWrapper } from '@/app/(app)/(libraries)/core/dashboard/components';
|
|
8
8
|
|
|
9
9
|
interface Payable30dKpiProps {
|
|
10
10
|
widget?: { name?: string };
|
|
@@ -45,19 +45,19 @@ export default function Payable30dKpi({
|
|
|
45
45
|
widgetName={widget?.name || t('kpis.payable30.title')}
|
|
46
46
|
onRemove={onRemove}
|
|
47
47
|
>
|
|
48
|
-
<Card className="h-full overflow-hidden transition-all duration-300 hover:shadow-md">
|
|
49
|
-
<CardContent className="flex h-full items-center gap-
|
|
50
|
-
<div className="flex h-
|
|
51
|
-
<TrendingDown className="h-5 w-5 text-red-600" />
|
|
48
|
+
<Card className="h-full overflow-hidden border-border/60 bg-linear-to-br from-background to-red-50/50 shadow-sm transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md">
|
|
49
|
+
<CardContent className="flex h-full items-center gap-2.5 p-3">
|
|
50
|
+
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-red-100/80">
|
|
51
|
+
<TrendingDown className="h-4.5 w-4.5 text-red-600" />
|
|
52
52
|
</div>
|
|
53
|
-
<div className="flex min-w-0 flex-col">
|
|
54
|
-
<span className="text-[
|
|
53
|
+
<div className="flex min-w-0 flex-1 flex-col justify-center">
|
|
54
|
+
<span className="text-[9px] font-semibold uppercase tracking-[0.18em] text-muted-foreground">
|
|
55
55
|
{t('kpis.payable30.title')}
|
|
56
56
|
</span>
|
|
57
|
-
<span className="truncate text-
|
|
57
|
+
<span className="truncate text-base font-bold leading-none tracking-tight text-foreground sm:text-lg">
|
|
58
58
|
{formatted}
|
|
59
59
|
</span>
|
|
60
|
-
<span className="text-[
|
|
60
|
+
<span className="truncate text-[9px] text-muted-foreground">
|
|
61
61
|
{t('kpis.payable30.sevenDays', {
|
|
62
62
|
value: new Intl.NumberFormat('pt-BR', {
|
|
63
63
|
style: 'currency',
|