@hed-hog/finance 0.0.279 → 0.0.286
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/finance-report-query.dto.d.ts +16 -0
- package/dist/dto/finance-report-query.dto.d.ts.map +1 -0
- package/dist/dto/finance-report-query.dto.js +59 -0
- package/dist/dto/finance-report-query.dto.js.map +1 -0
- package/dist/finance-reports.controller.d.ts +71 -0
- package/dist/finance-reports.controller.d.ts.map +1 -0
- package/dist/finance-reports.controller.js +61 -0
- package/dist/finance-reports.controller.js.map +1 -0
- package/dist/finance.module.d.ts.map +1 -1
- package/dist/finance.module.js +2 -0
- package/dist/finance.module.js.map +1 -1
- package/dist/finance.service.d.ts +93 -0
- package/dist/finance.service.d.ts.map +1 -1
- package/dist/finance.service.js +456 -0
- package/dist/finance.service.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/hedhog/data/route.yaml +27 -0
- package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +158 -125
- package/hedhog/frontend/app/accounts-receivable/collections-default/page.tsx.ejs +102 -88
- package/hedhog/frontend/app/cash-and-banks/statements/page.tsx.ejs +113 -89
- package/hedhog/frontend/app/reports/_lib/use-finance-reports.ts.ejs +238 -0
- package/hedhog/frontend/app/reports/overview-results/page.tsx.ejs +96 -78
- package/hedhog/frontend/app/reports/top-customers/page.tsx.ejs +239 -130
- package/hedhog/frontend/app/reports/top-operational-expenses/page.tsx.ejs +242 -135
- package/hedhog/frontend/messages/en.json +33 -2
- package/hedhog/frontend/messages/pt.json +33 -2
- package/package.json +7 -7
- package/src/dto/finance-report-query.dto.ts +49 -0
- package/src/finance-reports.controller.ts +28 -0
- package/src/finance.module.ts +2 -0
- package/src/finance.service.ts +645 -10
- package/src/index.ts +1 -0
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './finance-cost-centers.controller';
|
|
|
7
7
|
export * from './finance-data.controller';
|
|
8
8
|
export * from './finance-installments.controller';
|
|
9
9
|
export * from './finance-period-close.controller';
|
|
10
|
+
export * from './finance-reports.controller';
|
|
10
11
|
export * from './finance-statements.controller';
|
|
11
12
|
export * from './finance-transfers.controller';
|
|
12
13
|
export * from './finance.module';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC;AACnD,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC;AACnD,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC;AAClD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ __exportStar(require("./finance-cost-centers.controller"), exports);
|
|
|
23
23
|
__exportStar(require("./finance-data.controller"), exports);
|
|
24
24
|
__exportStar(require("./finance-installments.controller"), exports);
|
|
25
25
|
__exportStar(require("./finance-period-close.controller"), exports);
|
|
26
|
+
__exportStar(require("./finance-reports.controller"), exports);
|
|
26
27
|
__exportStar(require("./finance-statements.controller"), exports);
|
|
27
28
|
__exportStar(require("./finance-transfers.controller"), exports);
|
|
28
29
|
__exportStar(require("./finance.module"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mEAAiD;AACjD,kEAAgD;AAChD,qEAAmD;AACnD,kEAAgD;AAChD,mEAAiD;AACjD,oEAAkD;AAClD,4DAA0C;AAC1C,oEAAkD;AAClD,oEAAkD;AAClD,kEAAgD;AAChD,iEAA+C;AAC/C,mDAAiC;AACjC,oDAAkC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mEAAiD;AACjD,kEAAgD;AAChD,qEAAmD;AACnD,kEAAgD;AAChD,mEAAiD;AACjD,oEAAkD;AAClD,4DAA0C;AAC1C,oEAAkD;AAClD,oEAAkD;AAClD,+DAA6C;AAC7C,kEAAgD;AAChD,iEAA+C;AAC/C,mDAAiC;AACjC,oDAAkC"}
|
package/hedhog/data/route.yaml
CHANGED
|
@@ -7,6 +7,33 @@
|
|
|
7
7
|
- where:
|
|
8
8
|
slug: admin-finance
|
|
9
9
|
|
|
10
|
+
- url: /finance/reports/overview-results
|
|
11
|
+
method: GET
|
|
12
|
+
relations:
|
|
13
|
+
role:
|
|
14
|
+
- where:
|
|
15
|
+
slug: admin
|
|
16
|
+
- where:
|
|
17
|
+
slug: admin-finance
|
|
18
|
+
|
|
19
|
+
- url: /finance/reports/top-customers
|
|
20
|
+
method: GET
|
|
21
|
+
relations:
|
|
22
|
+
role:
|
|
23
|
+
- where:
|
|
24
|
+
slug: admin
|
|
25
|
+
- where:
|
|
26
|
+
slug: admin-finance
|
|
27
|
+
|
|
28
|
+
- url: /finance/reports/top-operational-expenses
|
|
29
|
+
method: GET
|
|
30
|
+
relations:
|
|
31
|
+
role:
|
|
32
|
+
- where:
|
|
33
|
+
slug: admin
|
|
34
|
+
- where:
|
|
35
|
+
slug: admin-finance
|
|
36
|
+
|
|
10
37
|
- url: /finance/scenarios/:cenario
|
|
11
38
|
method: PATCH
|
|
12
39
|
relations:
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from '@/app/(app)/(libraries)/finance/_components/finance-entity-field-with-create';
|
|
7
7
|
import { FinanceTitleActionsMenu } from '@/app/(app)/(libraries)/finance/_components/finance-title-actions-menu';
|
|
8
8
|
import { PersonFieldWithCreate } from '@/app/(app)/(libraries)/contact/person/_components/person-field-with-create';
|
|
9
|
-
import { Page, PageHeader } from '@/components/entity-list';
|
|
9
|
+
import { EmptyState, Page, PageHeader } from '@/components/entity-list';
|
|
10
10
|
import { Button } from '@/components/ui/button';
|
|
11
11
|
import { Checkbox } from '@/components/ui/checkbox';
|
|
12
12
|
import { FilterBar } from '@/components/ui/filter-bar';
|
|
@@ -55,7 +55,14 @@ import {
|
|
|
55
55
|
} from '@/components/ui/tooltip';
|
|
56
56
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
57
57
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
58
|
-
import {
|
|
58
|
+
import {
|
|
59
|
+
FileText,
|
|
60
|
+
Loader2,
|
|
61
|
+
Paperclip,
|
|
62
|
+
Plus,
|
|
63
|
+
Trash2,
|
|
64
|
+
Upload,
|
|
65
|
+
} from 'lucide-react';
|
|
59
66
|
import { useTranslations } from 'next-intl';
|
|
60
67
|
import Link from 'next/link';
|
|
61
68
|
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
|
@@ -244,6 +251,8 @@ function NovoTituloSheet({
|
|
|
244
251
|
onCreated,
|
|
245
252
|
onCategoriesUpdated,
|
|
246
253
|
onCostCentersUpdated,
|
|
254
|
+
open,
|
|
255
|
+
onOpenChange,
|
|
247
256
|
}: {
|
|
248
257
|
categorias: any[];
|
|
249
258
|
centrosCusto: any[];
|
|
@@ -251,9 +260,11 @@ function NovoTituloSheet({
|
|
|
251
260
|
onCreated: () => Promise<any> | void;
|
|
252
261
|
onCategoriesUpdated?: () => Promise<any> | void;
|
|
253
262
|
onCostCentersUpdated?: () => Promise<any> | void;
|
|
263
|
+
open?: boolean;
|
|
264
|
+
onOpenChange?: (open: boolean) => void;
|
|
254
265
|
}) {
|
|
255
266
|
const { request, showToastHandler } = useApp();
|
|
256
|
-
const [
|
|
267
|
+
const [internalOpen, setInternalOpen] = useState(false);
|
|
257
268
|
const [uploadedFileId, setUploadedFileId] = useState<number | null>(null);
|
|
258
269
|
const [uploadedFileName, setUploadedFileName] = useState('');
|
|
259
270
|
const [isUploadingFile, setIsUploadingFile] = useState(false);
|
|
@@ -270,6 +281,13 @@ function NovoTituloSheet({
|
|
|
270
281
|
const [extractionWarnings, setExtractionWarnings] = useState<string[]>([]);
|
|
271
282
|
const [uploadProgress, setUploadProgress] = useState(0);
|
|
272
283
|
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
|
284
|
+
const isOpen = open ?? internalOpen;
|
|
285
|
+
const handleOpenChange = (nextOpen: boolean) => {
|
|
286
|
+
onOpenChange?.(nextOpen);
|
|
287
|
+
if (open === undefined) {
|
|
288
|
+
setInternalOpen(nextOpen);
|
|
289
|
+
}
|
|
290
|
+
};
|
|
273
291
|
|
|
274
292
|
const normalizeFilenameForDisplay = (filename: string) => {
|
|
275
293
|
if (!filename) {
|
|
@@ -441,7 +459,7 @@ function NovoTituloSheet({
|
|
|
441
459
|
setExtractionWarnings([]);
|
|
442
460
|
setIsInstallmentsEdited(false);
|
|
443
461
|
setAutoRedistributeInstallments(true);
|
|
444
|
-
|
|
462
|
+
handleOpenChange(false);
|
|
445
463
|
showToastHandler?.('success', t('messages.createSuccess'));
|
|
446
464
|
} catch {
|
|
447
465
|
showToastHandler?.('error', t('messages.createError'));
|
|
@@ -457,7 +475,7 @@ function NovoTituloSheet({
|
|
|
457
475
|
setUploadProgress(0);
|
|
458
476
|
setIsInstallmentsEdited(false);
|
|
459
477
|
setAutoRedistributeInstallments(true);
|
|
460
|
-
|
|
478
|
+
handleOpenChange(false);
|
|
461
479
|
};
|
|
462
480
|
|
|
463
481
|
const clearUploadedFile = () => {
|
|
@@ -624,7 +642,7 @@ function NovoTituloSheet({
|
|
|
624
642
|
};
|
|
625
643
|
|
|
626
644
|
return (
|
|
627
|
-
<Sheet open={
|
|
645
|
+
<Sheet open={isOpen} onOpenChange={handleOpenChange}>
|
|
628
646
|
<SheetTrigger asChild>
|
|
629
647
|
<Button>
|
|
630
648
|
<Plus className="mr-2 h-4 w-4" />
|
|
@@ -2126,6 +2144,7 @@ export default function TitulosPagarPage() {
|
|
|
2126
2144
|
const [statusFilter, setStatusFilter] = useState<string>('');
|
|
2127
2145
|
const [page, setPage] = useState(1);
|
|
2128
2146
|
const pageSize = 10;
|
|
2147
|
+
const [isNewTitleSheetOpen, setIsNewTitleSheetOpen] = useState(false);
|
|
2129
2148
|
const [editingTitleId, setEditingTitleId] = useState<string | null>(null);
|
|
2130
2149
|
const [approvingTitleId, setApprovingTitleId] = useState<string | null>(null);
|
|
2131
2150
|
const [reversingTitleId, setReversingTitleId] = useState<string | null>(null);
|
|
@@ -2464,6 +2483,8 @@ export default function TitulosPagarPage() {
|
|
|
2464
2483
|
categorias={categorias}
|
|
2465
2484
|
centrosCusto={centrosCusto}
|
|
2466
2485
|
t={t}
|
|
2486
|
+
open={isNewTitleSheetOpen}
|
|
2487
|
+
onOpenChange={setIsNewTitleSheetOpen}
|
|
2467
2488
|
onCreated={async () => {
|
|
2468
2489
|
await Promise.all([refetchTitles(), refetchFinanceData()]);
|
|
2469
2490
|
}}
|
|
@@ -2637,126 +2658,138 @@ export default function TitulosPagarPage() {
|
|
|
2637
2658
|
</SheetContent>
|
|
2638
2659
|
</Sheet>
|
|
2639
2660
|
|
|
2640
|
-
|
|
2641
|
-
<
|
|
2642
|
-
<
|
|
2643
|
-
<
|
|
2644
|
-
<
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
<
|
|
2667
|
-
<
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
{titulo.documento}
|
|
2672
|
-
</Link>
|
|
2673
|
-
{titulo.anexos.length > 0 && (
|
|
2674
|
-
<Button
|
|
2675
|
-
type="button"
|
|
2676
|
-
variant="ghost"
|
|
2677
|
-
size="icon"
|
|
2678
|
-
className="ml-1 inline-flex h-5 w-5 align-middle text-muted-foreground"
|
|
2679
|
-
onClick={(event) => {
|
|
2680
|
-
event.preventDefault();
|
|
2681
|
-
event.stopPropagation();
|
|
2682
|
-
const firstAttachmentId =
|
|
2683
|
-
titulo.anexosDetalhes?.[0]?.id;
|
|
2684
|
-
void handleOpenAttachment(firstAttachmentId);
|
|
2685
|
-
}}
|
|
2686
|
-
aria-label={t('table.actions.openAttachment')}
|
|
2661
|
+
{titulosPagar.length > 0 ? (
|
|
2662
|
+
<div className="rounded-md border">
|
|
2663
|
+
<Table>
|
|
2664
|
+
<TableHeader>
|
|
2665
|
+
<TableRow>
|
|
2666
|
+
<TableHead>{t('table.headers.document')}</TableHead>
|
|
2667
|
+
<TableHead>{t('table.headers.supplier')}</TableHead>
|
|
2668
|
+
<TableHead>{t('table.headers.competency')}</TableHead>
|
|
2669
|
+
<TableHead>{t('table.headers.dueDate')}</TableHead>
|
|
2670
|
+
<TableHead className="text-right">
|
|
2671
|
+
{t('table.headers.value')}
|
|
2672
|
+
</TableHead>
|
|
2673
|
+
<TableHead>{t('table.headers.category')}</TableHead>
|
|
2674
|
+
<TableHead>{t('table.headers.status')}</TableHead>
|
|
2675
|
+
<TableHead className="w-[50px]" />
|
|
2676
|
+
</TableRow>
|
|
2677
|
+
</TableHeader>
|
|
2678
|
+
<TableBody>
|
|
2679
|
+
{titulosPagar.map((titulo) => {
|
|
2680
|
+
const fornecedor = getPessoaById(titulo.fornecedorId);
|
|
2681
|
+
const categoria = getCategoriaById(titulo.categoriaId);
|
|
2682
|
+
const proximaParcela = titulo.parcelas.find(
|
|
2683
|
+
(p: any) => p.status === 'aberto' || p.status === 'vencido'
|
|
2684
|
+
);
|
|
2685
|
+
|
|
2686
|
+
return (
|
|
2687
|
+
<TableRow key={titulo.id}>
|
|
2688
|
+
<TableCell className="font-medium">
|
|
2689
|
+
<Link
|
|
2690
|
+
href={`/finance/accounts-payable/installments/${titulo.id}`}
|
|
2691
|
+
className="hover:underline"
|
|
2687
2692
|
>
|
|
2688
|
-
|
|
2689
|
-
</
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
'
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2693
|
+
{titulo.documento}
|
|
2694
|
+
</Link>
|
|
2695
|
+
{titulo.anexos.length > 0 && (
|
|
2696
|
+
<Button
|
|
2697
|
+
type="button"
|
|
2698
|
+
variant="ghost"
|
|
2699
|
+
size="icon"
|
|
2700
|
+
className="ml-1 inline-flex h-5 w-5 align-middle text-muted-foreground"
|
|
2701
|
+
onClick={(event) => {
|
|
2702
|
+
event.preventDefault();
|
|
2703
|
+
event.stopPropagation();
|
|
2704
|
+
const firstAttachmentId =
|
|
2705
|
+
titulo.anexosDetalhes?.[0]?.id;
|
|
2706
|
+
void handleOpenAttachment(firstAttachmentId);
|
|
2707
|
+
}}
|
|
2708
|
+
aria-label={t('table.actions.openAttachment')}
|
|
2709
|
+
>
|
|
2710
|
+
<Paperclip className="h-3 w-3" />
|
|
2711
|
+
</Button>
|
|
2712
|
+
)}
|
|
2713
|
+
</TableCell>
|
|
2714
|
+
<TableCell>{fornecedor?.nome}</TableCell>
|
|
2715
|
+
<TableCell>{titulo.competencia}</TableCell>
|
|
2716
|
+
<TableCell>
|
|
2717
|
+
{proximaParcela
|
|
2718
|
+
? formatarData(proximaParcela.vencimento)
|
|
2719
|
+
: '-'}
|
|
2720
|
+
</TableCell>
|
|
2721
|
+
<TableCell className="text-right">
|
|
2722
|
+
<Money value={titulo.valorTotal} />
|
|
2723
|
+
</TableCell>
|
|
2724
|
+
<TableCell>{categoria?.nome}</TableCell>
|
|
2725
|
+
<TableCell>
|
|
2726
|
+
<StatusBadge status={titulo.status} />
|
|
2727
|
+
</TableCell>
|
|
2728
|
+
<TableCell>
|
|
2729
|
+
<FinanceTitleActionsMenu
|
|
2730
|
+
triggerVariant="ghost"
|
|
2731
|
+
detailHref={`/finance/accounts-payable/installments/${titulo.id}`}
|
|
2732
|
+
canEdit={canEditTitle(titulo.status)}
|
|
2733
|
+
canApprove={canApproveTitle(titulo.status)}
|
|
2734
|
+
canSettle={canSettleTitle(titulo.status)}
|
|
2735
|
+
canReverse={
|
|
2736
|
+
canReverseTitle(titulo.status) &&
|
|
2737
|
+
!!getFirstActiveSettlementId(titulo)
|
|
2738
|
+
}
|
|
2739
|
+
canCancel={canCancelTitle(titulo.status)}
|
|
2740
|
+
isApproving={approvingTitleId === titulo.id}
|
|
2741
|
+
isReversing={reversingTitleId === titulo.id}
|
|
2742
|
+
isCanceling={cancelingTitleId === titulo.id}
|
|
2743
|
+
labels={{
|
|
2744
|
+
menu: t.has('actions.title')
|
|
2745
|
+
? t('actions.title')
|
|
2746
|
+
: t('table.actions.srActions'),
|
|
2747
|
+
srActions: t('table.actions.srActions'),
|
|
2748
|
+
viewDetails: t('table.actions.viewDetails'),
|
|
2749
|
+
edit: t('table.actions.edit'),
|
|
2750
|
+
approve: t('table.actions.approve'),
|
|
2751
|
+
settle: t('table.actions.settle'),
|
|
2752
|
+
reverse: t('table.actions.reverse'),
|
|
2753
|
+
cancel: t('table.actions.cancel'),
|
|
2754
|
+
}}
|
|
2755
|
+
dialogs={{
|
|
2756
|
+
cancelTitle: t('dialogs.cancel.title'),
|
|
2757
|
+
cancelDescription: t('dialogs.cancel.description'),
|
|
2758
|
+
cancelButton: t('dialogs.cancel.cancel'),
|
|
2759
|
+
confirmCancelButton: t('dialogs.cancel.confirm'),
|
|
2760
|
+
reverseTitle: t('dialogs.reverse.title'),
|
|
2761
|
+
reverseDescription: t('dialogs.reverse.description'),
|
|
2762
|
+
reverseReasonLabel: t('dialogs.reverse.reasonLabel'),
|
|
2763
|
+
reverseReasonPlaceholder: t(
|
|
2764
|
+
'dialogs.reverse.reasonPlaceholder'
|
|
2765
|
+
),
|
|
2766
|
+
reverseButton: t('dialogs.reverse.cancel'),
|
|
2767
|
+
confirmReverseButton: t('dialogs.reverse.confirm'),
|
|
2768
|
+
}}
|
|
2769
|
+
onEdit={() => setEditingTitleId(titulo.id)}
|
|
2770
|
+
onApprove={() => void handleApproveTitle(titulo.id)}
|
|
2771
|
+
onSettle={() => handleSettleTitle(titulo)}
|
|
2772
|
+
onReverse={(reason) =>
|
|
2773
|
+
handleReverseTitle(titulo, reason)
|
|
2774
|
+
}
|
|
2775
|
+
onCancel={() => handleCancelTitle(titulo.id)}
|
|
2776
|
+
/>
|
|
2777
|
+
</TableCell>
|
|
2778
|
+
</TableRow>
|
|
2779
|
+
);
|
|
2780
|
+
})}
|
|
2781
|
+
</TableBody>
|
|
2782
|
+
</Table>
|
|
2783
|
+
</div>
|
|
2784
|
+
) : (
|
|
2785
|
+
<EmptyState
|
|
2786
|
+
icon={<FileText className="h-12 w-12" />}
|
|
2787
|
+
title={t('empty.title')}
|
|
2788
|
+
description={t('empty.description')}
|
|
2789
|
+
actionLabel={t('newTitle.action')}
|
|
2790
|
+
onAction={() => setIsNewTitleSheetOpen(true)}
|
|
2791
|
+
/>
|
|
2792
|
+
)}
|
|
2760
2793
|
|
|
2761
2794
|
<div className="flex items-center justify-between">
|
|
2762
2795
|
<p className="text-sm text-muted-foreground">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { Page, PageHeader } from '@/components/entity-list';
|
|
3
|
+
import { EmptyState, Page, PageHeader } from '@/components/entity-list';
|
|
4
4
|
import { RichTextEditor } from '@/components/rich-text-editor';
|
|
5
5
|
import { Button } from '@/components/ui/button';
|
|
6
6
|
import {
|
|
@@ -548,94 +548,108 @@ export default function CobrancaPage() {
|
|
|
548
548
|
<CardDescription>{t('table.description')}</CardDescription>
|
|
549
549
|
</CardHeader>
|
|
550
550
|
<CardContent>
|
|
551
|
-
|
|
552
|
-
<
|
|
553
|
-
<
|
|
554
|
-
<
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
</TableHeader>
|
|
575
|
-
<TableBody>
|
|
576
|
-
{agingInadimplencia.map((item) => (
|
|
577
|
-
<TableRow key={item.clienteId}>
|
|
578
|
-
<TableCell className="font-medium">{item.cliente}</TableCell>
|
|
579
|
-
<TableCell className="text-right">
|
|
580
|
-
{item.bucket0_30 > 0 ? (
|
|
581
|
-
<Money value={item.bucket0_30} />
|
|
582
|
-
) : (
|
|
583
|
-
'-'
|
|
584
|
-
)}
|
|
585
|
-
</TableCell>
|
|
586
|
-
<TableCell className="text-right">
|
|
587
|
-
{item.bucket31_60 > 0 ? (
|
|
588
|
-
<Money value={item.bucket31_60} />
|
|
589
|
-
) : (
|
|
590
|
-
'-'
|
|
591
|
-
)}
|
|
592
|
-
</TableCell>
|
|
593
|
-
<TableCell className="text-right">
|
|
594
|
-
{item.bucket61_90 > 0 ? (
|
|
595
|
-
<Money value={item.bucket61_90} />
|
|
596
|
-
) : (
|
|
597
|
-
'-'
|
|
598
|
-
)}
|
|
599
|
-
</TableCell>
|
|
600
|
-
<TableCell className="text-right">
|
|
601
|
-
{item.bucket90plus > 0 ? (
|
|
602
|
-
<span className="font-medium text-destructive">
|
|
603
|
-
<Money value={item.bucket90plus} />
|
|
604
|
-
</span>
|
|
605
|
-
) : (
|
|
606
|
-
'-'
|
|
607
|
-
)}
|
|
608
|
-
</TableCell>
|
|
609
|
-
<TableCell className="text-right font-semibold">
|
|
610
|
-
<Money value={item.total} />
|
|
611
|
-
</TableCell>
|
|
612
|
-
<TableCell>
|
|
613
|
-
<div className="flex justify-end gap-2">
|
|
614
|
-
<HistoricoContatosSheet
|
|
615
|
-
cliente={item.cliente}
|
|
616
|
-
historicoContatos={historicoContatos.filter(
|
|
617
|
-
(contato) => contato.clienteId === item.clienteId
|
|
618
|
-
)}
|
|
619
|
-
t={t}
|
|
620
|
-
/>
|
|
621
|
-
<EnviarCobrancaDialog
|
|
622
|
-
cliente={item.cliente}
|
|
623
|
-
clienteId={item.clienteId}
|
|
624
|
-
onSuccess={refetch}
|
|
625
|
-
t={t}
|
|
626
|
-
/>
|
|
627
|
-
<RegistrarAcordoDialog
|
|
628
|
-
cliente={item.cliente}
|
|
629
|
-
clienteId={item.clienteId}
|
|
630
|
-
onSuccess={refetch}
|
|
631
|
-
t={t}
|
|
632
|
-
/>
|
|
633
|
-
</div>
|
|
634
|
-
</TableCell>
|
|
551
|
+
{agingInadimplencia.length > 0 ? (
|
|
552
|
+
<Table>
|
|
553
|
+
<TableHeader>
|
|
554
|
+
<TableRow>
|
|
555
|
+
<TableHead>{t('table.headers.client')}</TableHead>
|
|
556
|
+
<TableHead className="text-right">
|
|
557
|
+
{t('table.headers.range0to30')}
|
|
558
|
+
</TableHead>
|
|
559
|
+
<TableHead className="text-right">
|
|
560
|
+
{t('table.headers.range31to60')}
|
|
561
|
+
</TableHead>
|
|
562
|
+
<TableHead className="text-right">
|
|
563
|
+
{t('table.headers.range61to90')}
|
|
564
|
+
</TableHead>
|
|
565
|
+
<TableHead className="text-right">
|
|
566
|
+
{t('table.headers.range90plus')}
|
|
567
|
+
</TableHead>
|
|
568
|
+
<TableHead className="text-right">
|
|
569
|
+
{t('table.headers.total')}
|
|
570
|
+
</TableHead>
|
|
571
|
+
<TableHead className="text-right">
|
|
572
|
+
{t('table.headers.actions')}
|
|
573
|
+
</TableHead>
|
|
635
574
|
</TableRow>
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
575
|
+
</TableHeader>
|
|
576
|
+
<TableBody>
|
|
577
|
+
{agingInadimplencia.map((item) => (
|
|
578
|
+
<TableRow key={item.clienteId}>
|
|
579
|
+
<TableCell className="font-medium">
|
|
580
|
+
{item.cliente}
|
|
581
|
+
</TableCell>
|
|
582
|
+
<TableCell className="text-right">
|
|
583
|
+
{item.bucket0_30 > 0 ? (
|
|
584
|
+
<Money value={item.bucket0_30} />
|
|
585
|
+
) : (
|
|
586
|
+
'-'
|
|
587
|
+
)}
|
|
588
|
+
</TableCell>
|
|
589
|
+
<TableCell className="text-right">
|
|
590
|
+
{item.bucket31_60 > 0 ? (
|
|
591
|
+
<Money value={item.bucket31_60} />
|
|
592
|
+
) : (
|
|
593
|
+
'-'
|
|
594
|
+
)}
|
|
595
|
+
</TableCell>
|
|
596
|
+
<TableCell className="text-right">
|
|
597
|
+
{item.bucket61_90 > 0 ? (
|
|
598
|
+
<Money value={item.bucket61_90} />
|
|
599
|
+
) : (
|
|
600
|
+
'-'
|
|
601
|
+
)}
|
|
602
|
+
</TableCell>
|
|
603
|
+
<TableCell className="text-right">
|
|
604
|
+
{item.bucket90plus > 0 ? (
|
|
605
|
+
<span className="font-medium text-destructive">
|
|
606
|
+
<Money value={item.bucket90plus} />
|
|
607
|
+
</span>
|
|
608
|
+
) : (
|
|
609
|
+
'-'
|
|
610
|
+
)}
|
|
611
|
+
</TableCell>
|
|
612
|
+
<TableCell className="text-right font-semibold">
|
|
613
|
+
<Money value={item.total} />
|
|
614
|
+
</TableCell>
|
|
615
|
+
<TableCell>
|
|
616
|
+
<div className="flex justify-end gap-2">
|
|
617
|
+
<HistoricoContatosSheet
|
|
618
|
+
cliente={item.cliente}
|
|
619
|
+
historicoContatos={historicoContatos.filter(
|
|
620
|
+
(contato) => contato.clienteId === item.clienteId
|
|
621
|
+
)}
|
|
622
|
+
t={t}
|
|
623
|
+
/>
|
|
624
|
+
<EnviarCobrancaDialog
|
|
625
|
+
cliente={item.cliente}
|
|
626
|
+
clienteId={item.clienteId}
|
|
627
|
+
onSuccess={refetch}
|
|
628
|
+
t={t}
|
|
629
|
+
/>
|
|
630
|
+
<RegistrarAcordoDialog
|
|
631
|
+
cliente={item.cliente}
|
|
632
|
+
clienteId={item.clienteId}
|
|
633
|
+
onSuccess={refetch}
|
|
634
|
+
t={t}
|
|
635
|
+
/>
|
|
636
|
+
</div>
|
|
637
|
+
</TableCell>
|
|
638
|
+
</TableRow>
|
|
639
|
+
))}
|
|
640
|
+
</TableBody>
|
|
641
|
+
</Table>
|
|
642
|
+
) : (
|
|
643
|
+
<EmptyState
|
|
644
|
+
icon={<FileText className="h-12 w-12" />}
|
|
645
|
+
title={t('empty.title')}
|
|
646
|
+
description={t('empty.description')}
|
|
647
|
+
actionLabel={t('empty.action')}
|
|
648
|
+
onAction={() => {
|
|
649
|
+
void refetch();
|
|
650
|
+
}}
|
|
651
|
+
/>
|
|
652
|
+
)}
|
|
639
653
|
</CardContent>
|
|
640
654
|
</Card>
|
|
641
655
|
</Page>
|