@hed-hog/finance 0.0.274 → 0.0.276
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/README.md +228 -126
- package/dist/dto/create-bank-reconciliation.dto.d.ts +8 -0
- package/dist/dto/create-bank-reconciliation.dto.d.ts.map +1 -0
- package/dist/dto/create-bank-reconciliation.dto.js +43 -0
- package/dist/dto/create-bank-reconciliation.dto.js.map +1 -0
- package/dist/finance-data.controller.d.ts +2 -0
- package/dist/finance-data.controller.d.ts.map +1 -1
- package/dist/finance-statements.controller.d.ts +42 -0
- package/dist/finance-statements.controller.d.ts.map +1 -1
- package/dist/finance-statements.controller.js +13 -0
- package/dist/finance-statements.controller.js.map +1 -1
- package/dist/finance.service.d.ts +44 -0
- package/dist/finance.service.d.ts.map +1 -1
- package/dist/finance.service.js +98 -9
- package/dist/finance.service.js.map +1 -1
- package/hedhog/data/route.yaml +9 -0
- package/hedhog/frontend/app/_components/person-field-with-create.tsx.ejs +126 -126
- package/hedhog/frontend/app/accounts-payable/approvals/page.tsx.ejs +373 -373
- package/hedhog/frontend/app/accounts-payable/installments/[id]/page.tsx.ejs +1270 -1270
- package/hedhog/frontend/app/accounts-receivable/installments/[id]/page.tsx.ejs +982 -982
- package/hedhog/frontend/app/cash-and-banks/bank-accounts/page.tsx.ejs +686 -686
- package/hedhog/frontend/app/cash-and-banks/bank-reconciliation/page.tsx.ejs +152 -32
- package/hedhog/frontend/app/cash-and-banks/statements/page.tsx.ejs +986 -986
- package/hedhog/frontend/app/cash-and-banks/transfers/page.tsx.ejs +492 -492
- package/hedhog/frontend/app/page.tsx.ejs +372 -372
- package/hedhog/frontend/app/planning/cash-flow-forecast/page.tsx.ejs +329 -329
- package/hedhog/frontend/app/planning/receivables-calendar/page.tsx.ejs +227 -227
- package/hedhog/frontend/app/planning/scenarios/page.tsx.ejs +408 -408
- package/hedhog/frontend/messages/en.json +15 -5
- package/hedhog/frontend/messages/pt.json +15 -5
- package/package.json +7 -7
- package/src/dto/create-bank-reconciliation.dto.ts +24 -0
- package/src/finance-statements.controller.ts +14 -0
- package/src/finance.module.ts +43 -43
- package/src/finance.service.ts +118 -0
- package/src/index.ts +14 -14
- package/dist/finance.controller.d.ts +0 -276
- package/dist/finance.controller.d.ts.map +0 -1
- package/dist/finance.controller.js +0 -110
- package/dist/finance.controller.js.map +0 -1
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { Page, PageHeader } from '@/components/entity-list';
|
|
4
|
+
import {
|
|
5
|
+
AlertDialog,
|
|
6
|
+
AlertDialogAction,
|
|
7
|
+
AlertDialogCancel,
|
|
8
|
+
AlertDialogContent,
|
|
9
|
+
AlertDialogDescription,
|
|
10
|
+
AlertDialogFooter,
|
|
11
|
+
AlertDialogHeader,
|
|
12
|
+
AlertDialogTitle,
|
|
13
|
+
} from '@/components/ui/alert-dialog';
|
|
4
14
|
import { Badge } from '@/components/ui/badge';
|
|
5
15
|
import { Button } from '@/components/ui/button';
|
|
6
16
|
import {
|
|
@@ -40,7 +50,7 @@ import {
|
|
|
40
50
|
import { StatusBadge } from '@/components/ui/status-badge';
|
|
41
51
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
42
52
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
43
|
-
import { Check, DollarSign, Link2, RefreshCw } from 'lucide-react';
|
|
53
|
+
import { Check, DollarSign, Link2, RefreshCw, Trash2 } from 'lucide-react';
|
|
44
54
|
import { useTranslations } from 'next-intl';
|
|
45
55
|
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
|
46
56
|
import { useEffect, useMemo, useState } from 'react';
|
|
@@ -60,6 +70,8 @@ type Statement = {
|
|
|
60
70
|
data: string;
|
|
61
71
|
descricao: string;
|
|
62
72
|
valor: number;
|
|
73
|
+
reconciliationId?: string | null;
|
|
74
|
+
settlementId?: string | null;
|
|
63
75
|
tipo: 'entrada' | 'saida';
|
|
64
76
|
statusConciliacao:
|
|
65
77
|
| 'importado'
|
|
@@ -290,6 +302,9 @@ export default function ConciliacaoPage() {
|
|
|
290
302
|
const [contaFilter, setContaFilter] = useState<string>('');
|
|
291
303
|
const [selectedExtrato, setSelectedExtrato] = useState<string | null>(null);
|
|
292
304
|
const [selectedTitulo, setSelectedTitulo] = useState<string | null>(null);
|
|
305
|
+
const [reconciliationToUndo, setReconciliationToUndo] = useState<
|
|
306
|
+
string | null
|
|
307
|
+
>(null);
|
|
293
308
|
|
|
294
309
|
const { data: contasBancarias = [] } = useQuery<BankAccount[]>({
|
|
295
310
|
queryKey: ['finance-bank-accounts'],
|
|
@@ -354,29 +369,30 @@ export default function ConciliacaoPage() {
|
|
|
354
369
|
},
|
|
355
370
|
});
|
|
356
371
|
|
|
357
|
-
const { data: reconciliationSummary } =
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
372
|
+
const { data: reconciliationSummary, refetch: refetchReconciliationSummary } =
|
|
373
|
+
useQuery<BankReconciliationSummary>({
|
|
374
|
+
queryKey: ['finance-bank-reconciliation-summary', contaFilter],
|
|
375
|
+
queryFn: async () => {
|
|
376
|
+
if (!contaFilter) {
|
|
377
|
+
return {
|
|
378
|
+
discrepancies: 0,
|
|
379
|
+
difference: 0,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
366
382
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
383
|
+
const response = await request<BankReconciliationSummary>({
|
|
384
|
+
url: `/finance/bank-reconciliation/summary?bank_account_id=${contaFilter}`,
|
|
385
|
+
method: 'GET',
|
|
386
|
+
});
|
|
371
387
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
388
|
+
return (
|
|
389
|
+
(response?.data as BankReconciliationSummary) || {
|
|
390
|
+
discrepancies: 0,
|
|
391
|
+
difference: 0,
|
|
392
|
+
}
|
|
393
|
+
);
|
|
394
|
+
},
|
|
395
|
+
});
|
|
380
396
|
|
|
381
397
|
const { data: titulosPagar = [], refetch: refetchTitulosPagar } = useQuery<
|
|
382
398
|
FinancialTitle[]
|
|
@@ -411,10 +427,16 @@ export default function ConciliacaoPage() {
|
|
|
411
427
|
(e) =>
|
|
412
428
|
e.statusConciliacao === 'pendente' || e.statusConciliacao === 'importado'
|
|
413
429
|
);
|
|
430
|
+
const extratosConciliados = extratos.filter(
|
|
431
|
+
(e) => e.statusConciliacao === 'conciliado' && !!e.reconciliationId
|
|
432
|
+
);
|
|
414
433
|
|
|
415
434
|
const extratosFiltered = extratosPendentes.filter(
|
|
416
435
|
(e) => e.contaBancariaId === contaFilter
|
|
417
436
|
);
|
|
437
|
+
const extratosConciliadosFiltered = extratosConciliados.filter(
|
|
438
|
+
(e) => e.contaBancariaId === contaFilter
|
|
439
|
+
);
|
|
418
440
|
|
|
419
441
|
const titulosAbertos = useMemo<OpenTitleItem[]>(() => {
|
|
420
442
|
const payables: OpenTitleItem[] = titulosPagar.flatMap((titulo) =>
|
|
@@ -492,6 +514,7 @@ export default function ConciliacaoPage() {
|
|
|
492
514
|
refetchExtratos(),
|
|
493
515
|
refetchTitulosPagar(),
|
|
494
516
|
refetchTitulosReceber(),
|
|
517
|
+
refetchReconciliationSummary(),
|
|
495
518
|
]);
|
|
496
519
|
};
|
|
497
520
|
|
|
@@ -500,23 +523,16 @@ export default function ConciliacaoPage() {
|
|
|
500
523
|
return;
|
|
501
524
|
}
|
|
502
525
|
|
|
503
|
-
const endpointBase =
|
|
504
|
-
selectedTituloItem.tipo === 'pagar'
|
|
505
|
-
? '/finance/accounts-payable/installments'
|
|
506
|
-
: '/finance/accounts-receivable/installments';
|
|
507
|
-
|
|
508
526
|
try {
|
|
509
527
|
await request({
|
|
510
|
-
url:
|
|
528
|
+
url: '/finance/bank-reconciliations',
|
|
511
529
|
method: 'POST',
|
|
512
530
|
data: {
|
|
531
|
+
title_id: Number(selectedTituloItem.titleId),
|
|
513
532
|
installment_id: Number(selectedTituloItem.installmentId),
|
|
514
|
-
|
|
515
|
-
settled_at: selectedExtratoItem.data,
|
|
516
|
-
bank_account_id: Number(contaFilter),
|
|
533
|
+
bank_statement_line_id: Number(selectedExtratoItem.id),
|
|
517
534
|
payment_channel: 'transferencia',
|
|
518
535
|
description: selectedExtratoItem.descricao,
|
|
519
|
-
bank_statement_line_id: Number(selectedExtratoItem.id),
|
|
520
536
|
},
|
|
521
537
|
});
|
|
522
538
|
|
|
@@ -529,6 +545,27 @@ export default function ConciliacaoPage() {
|
|
|
529
545
|
}
|
|
530
546
|
};
|
|
531
547
|
|
|
548
|
+
const handleUnreconcile = async () => {
|
|
549
|
+
if (!reconciliationToUndo) {
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
try {
|
|
554
|
+
await request({
|
|
555
|
+
url: `/finance/bank-reconciliations/${reconciliationToUndo}`,
|
|
556
|
+
method: 'DELETE',
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
setReconciliationToUndo(null);
|
|
560
|
+
setSelectedExtrato(null);
|
|
561
|
+
setSelectedTitulo(null);
|
|
562
|
+
await handleRefreshData();
|
|
563
|
+
showToastHandler?.('success', t('unreconcile.success'));
|
|
564
|
+
} catch {
|
|
565
|
+
showToastHandler?.('error', t('unreconcile.error'));
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
|
|
532
569
|
return (
|
|
533
570
|
<Page>
|
|
534
571
|
<PageHeader
|
|
@@ -713,6 +750,65 @@ export default function ConciliacaoPage() {
|
|
|
713
750
|
</p>
|
|
714
751
|
</div>
|
|
715
752
|
)}
|
|
753
|
+
|
|
754
|
+
{extratosConciliadosFiltered.length > 0 ? (
|
|
755
|
+
<>
|
|
756
|
+
<div className="mt-6 border-t pt-4">
|
|
757
|
+
<p className="text-sm font-medium">
|
|
758
|
+
{t('statement.reconciledTitle')}
|
|
759
|
+
</p>
|
|
760
|
+
<p className="text-xs text-muted-foreground">
|
|
761
|
+
{t('statement.reconciledDescription')}
|
|
762
|
+
</p>
|
|
763
|
+
</div>
|
|
764
|
+
|
|
765
|
+
{extratosConciliadosFiltered.map((extrato) => (
|
|
766
|
+
<div
|
|
767
|
+
key={`reconciled-${extrato.id}`}
|
|
768
|
+
className="flex items-center gap-3 rounded-lg border p-3"
|
|
769
|
+
>
|
|
770
|
+
<div className="flex-1">
|
|
771
|
+
<div className="flex items-center justify-between">
|
|
772
|
+
<span className="text-sm font-medium">
|
|
773
|
+
{extrato.descricao}
|
|
774
|
+
</span>
|
|
775
|
+
<span
|
|
776
|
+
className={`font-semibold ${
|
|
777
|
+
extrato.tipo === 'entrada'
|
|
778
|
+
? 'text-green-600'
|
|
779
|
+
: 'text-red-600'
|
|
780
|
+
}`}
|
|
781
|
+
>
|
|
782
|
+
{extrato.tipo === 'saida' && '-'}
|
|
783
|
+
{formatarMoeda(Math.abs(extrato.valor))}
|
|
784
|
+
</span>
|
|
785
|
+
</div>
|
|
786
|
+
<div className="flex items-center gap-2 text-xs text-muted-foreground">
|
|
787
|
+
<span>{formatarData(extrato.data)}</span>
|
|
788
|
+
<StatusBadge
|
|
789
|
+
status={extrato.statusConciliacao}
|
|
790
|
+
type="conciliacao"
|
|
791
|
+
/>
|
|
792
|
+
</div>
|
|
793
|
+
</div>
|
|
794
|
+
<Button
|
|
795
|
+
type="button"
|
|
796
|
+
variant="outline"
|
|
797
|
+
size="sm"
|
|
798
|
+
onClick={() =>
|
|
799
|
+
setReconciliationToUndo(
|
|
800
|
+
extrato.reconciliationId || null
|
|
801
|
+
)
|
|
802
|
+
}
|
|
803
|
+
disabled={!extrato.reconciliationId}
|
|
804
|
+
>
|
|
805
|
+
<Trash2 className="mr-2 h-4 w-4" />
|
|
806
|
+
{t('unreconcile.action')}
|
|
807
|
+
</Button>
|
|
808
|
+
</div>
|
|
809
|
+
))}
|
|
810
|
+
</>
|
|
811
|
+
) : null}
|
|
716
812
|
</div>
|
|
717
813
|
</CardContent>
|
|
718
814
|
</Card>
|
|
@@ -820,6 +916,30 @@ export default function ConciliacaoPage() {
|
|
|
820
916
|
</CardContent>
|
|
821
917
|
</Card>
|
|
822
918
|
)}
|
|
919
|
+
|
|
920
|
+
<AlertDialog
|
|
921
|
+
open={!!reconciliationToUndo}
|
|
922
|
+
onOpenChange={(open) => {
|
|
923
|
+
if (!open) {
|
|
924
|
+
setReconciliationToUndo(null);
|
|
925
|
+
}
|
|
926
|
+
}}
|
|
927
|
+
>
|
|
928
|
+
<AlertDialogContent>
|
|
929
|
+
<AlertDialogHeader>
|
|
930
|
+
<AlertDialogTitle>{t('unreconcile.title')}</AlertDialogTitle>
|
|
931
|
+
<AlertDialogDescription>
|
|
932
|
+
{t('unreconcile.description')}
|
|
933
|
+
</AlertDialogDescription>
|
|
934
|
+
</AlertDialogHeader>
|
|
935
|
+
<AlertDialogFooter>
|
|
936
|
+
<AlertDialogCancel>{t('common.cancel')}</AlertDialogCancel>
|
|
937
|
+
<AlertDialogAction onClick={() => void handleUnreconcile()}>
|
|
938
|
+
{t('unreconcile.confirm')}
|
|
939
|
+
</AlertDialogAction>
|
|
940
|
+
</AlertDialogFooter>
|
|
941
|
+
</AlertDialogContent>
|
|
942
|
+
</AlertDialog>
|
|
823
943
|
</Page>
|
|
824
944
|
);
|
|
825
945
|
}
|