@hed-hog/finance 0.0.252 → 0.0.256
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/reverse-settlement.dto.d.ts +1 -0
- package/dist/dto/reverse-settlement.dto.d.ts.map +1 -1
- package/dist/dto/reverse-settlement.dto.js +5 -0
- package/dist/dto/reverse-settlement.dto.js.map +1 -1
- package/dist/finance-installments.controller.d.ts +106 -4
- package/dist/finance-installments.controller.d.ts.map +1 -1
- package/dist/finance-installments.controller.js +38 -2
- package/dist/finance-installments.controller.js.map +1 -1
- package/dist/finance.service.d.ts +104 -2
- package/dist/finance.service.d.ts.map +1 -1
- package/dist/finance.service.js +366 -121
- package/dist/finance.service.js.map +1 -1
- package/hedhog/data/route.yaml +27 -0
- package/hedhog/frontend/app/_components/finance-entity-field-with-create.tsx.ejs +572 -0
- package/hedhog/frontend/app/_components/finance-title-actions-menu.tsx.ejs +244 -0
- package/hedhog/frontend/app/_components/person-field-with-create.tsx.ejs +143 -51
- package/hedhog/frontend/app/_lib/title-action-rules.ts.ejs +36 -0
- package/hedhog/frontend/app/accounts-payable/installments/[id]/page.tsx.ejs +449 -293
- package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +1189 -545
- package/hedhog/frontend/app/accounts-receivable/installments/[id]/page.tsx.ejs +176 -133
- package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +1459 -312
- package/hedhog/frontend/app/page.tsx.ejs +15 -4
- package/hedhog/frontend/messages/en.json +294 -5
- package/hedhog/frontend/messages/pt.json +294 -5
- package/hedhog/query/settlement-auditability.sql +175 -0
- package/hedhog/table/bank_reconciliation.yaml +11 -0
- package/hedhog/table/settlement.yaml +17 -1
- package/hedhog/table/settlement_allocation.yaml +3 -0
- package/package.json +7 -7
- package/src/dto/reverse-settlement.dto.ts +4 -0
- package/src/finance-installments.controller.ts +45 -12
- package/src/finance.service.ts +521 -146
|
@@ -1,17 +1,6 @@
|
|
|
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
|
-
AlertDialogTrigger,
|
|
14
|
-
} from '@/components/ui/alert-dialog';
|
|
15
4
|
import { AuditTimeline } from '@/components/ui/audit-timeline';
|
|
16
5
|
import { Badge } from '@/components/ui/badge';
|
|
17
6
|
import { Button } from '@/components/ui/button';
|
|
@@ -38,6 +27,7 @@ import {
|
|
|
38
27
|
} from '@/components/ui/form';
|
|
39
28
|
import { Input } from '@/components/ui/input';
|
|
40
29
|
import { InputMoney } from '@/components/ui/input-money';
|
|
30
|
+
import { Label } from '@/components/ui/label';
|
|
41
31
|
import { Money } from '@/components/ui/money';
|
|
42
32
|
import {
|
|
43
33
|
Select,
|
|
@@ -78,19 +68,17 @@ import {
|
|
|
78
68
|
import { useTranslations } from 'next-intl';
|
|
79
69
|
import Link from 'next/link';
|
|
80
70
|
import { useParams } from 'next/navigation';
|
|
81
|
-
import { useEffect, useState } from 'react';
|
|
71
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
82
72
|
import { useForm } from 'react-hook-form';
|
|
83
73
|
import { z } from 'zod';
|
|
84
74
|
import { formatarData } from '../../../_lib/formatters';
|
|
85
75
|
import { useFinanceData } from '../../../_lib/use-finance-data';
|
|
86
76
|
|
|
87
|
-
|
|
88
|
-
installmentId:
|
|
89
|
-
amount:
|
|
90
|
-
description
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
type SettleFormValues = z.infer<typeof settleSchema>;
|
|
77
|
+
type SettleFormValues = {
|
|
78
|
+
installmentId: string;
|
|
79
|
+
amount: number;
|
|
80
|
+
description?: string;
|
|
81
|
+
};
|
|
94
82
|
|
|
95
83
|
export default function TituloReceberDetalhePage() {
|
|
96
84
|
const t = useTranslations('finance.ReceivableInstallmentDetailPage');
|
|
@@ -117,6 +105,16 @@ export default function TituloReceberDetalhePage() {
|
|
|
117
105
|
parcela.status === 'vencido'
|
|
118
106
|
);
|
|
119
107
|
|
|
108
|
+
const settleSchema = useMemo(
|
|
109
|
+
() =>
|
|
110
|
+
z.object({
|
|
111
|
+
installmentId: z.string().min(1, t('validation.installmentRequired')),
|
|
112
|
+
amount: z.number().min(0.01, t('validation.amountGreaterThanZero')),
|
|
113
|
+
description: z.string().optional(),
|
|
114
|
+
}),
|
|
115
|
+
[t]
|
|
116
|
+
);
|
|
117
|
+
|
|
120
118
|
const settleForm = useForm<SettleFormValues>({
|
|
121
119
|
resolver: zodResolver(settleSchema),
|
|
122
120
|
defaultValues: {
|
|
@@ -132,6 +130,10 @@ export default function TituloReceberDetalhePage() {
|
|
|
132
130
|
const [isApproving, setIsApproving] = useState(false);
|
|
133
131
|
const [isSettling, setIsSettling] = useState(false);
|
|
134
132
|
const [isSettleDialogOpen, setIsSettleDialogOpen] = useState(false);
|
|
133
|
+
const [isReverseSheetOpen, setIsReverseSheetOpen] = useState(false);
|
|
134
|
+
const [selectedSettlementIdToReverse, setSelectedSettlementIdToReverse] =
|
|
135
|
+
useState<string | null>(null);
|
|
136
|
+
const [reverseReason, setReverseReason] = useState('');
|
|
135
137
|
const [reversingSettlementId, setReversingSettlementId] = useState<
|
|
136
138
|
string | null
|
|
137
139
|
>(null);
|
|
@@ -273,11 +275,6 @@ export default function TituloReceberDetalhePage() {
|
|
|
273
275
|
window.open(url, '_blank', 'noopener,noreferrer');
|
|
274
276
|
};
|
|
275
277
|
|
|
276
|
-
const tTagSelector = (key: string, fallback: string) => {
|
|
277
|
-
const fullKey = `tagSelector.${key}`;
|
|
278
|
-
return t.has(fullKey) ? t(fullKey) : fallback;
|
|
279
|
-
};
|
|
280
|
-
|
|
281
278
|
const toTagSlug = (value: string) => {
|
|
282
279
|
return value
|
|
283
280
|
.normalize('NFD')
|
|
@@ -325,10 +322,7 @@ export default function TituloReceberDetalhePage() {
|
|
|
325
322
|
return [...current, newTag];
|
|
326
323
|
});
|
|
327
324
|
|
|
328
|
-
showToastHandler?.(
|
|
329
|
-
'success',
|
|
330
|
-
tTagSelector('messages.createSuccess', 'Tag criada com sucesso')
|
|
331
|
-
);
|
|
325
|
+
showToastHandler?.('success', t('tagSelector.messages.createSuccess'));
|
|
332
326
|
|
|
333
327
|
return {
|
|
334
328
|
id: newTag.id,
|
|
@@ -336,10 +330,7 @@ export default function TituloReceberDetalhePage() {
|
|
|
336
330
|
color: newTag.cor,
|
|
337
331
|
};
|
|
338
332
|
} catch {
|
|
339
|
-
showToastHandler?.(
|
|
340
|
-
'error',
|
|
341
|
-
tTagSelector('messages.createError', 'Não foi possível criar a tag')
|
|
342
|
-
);
|
|
333
|
+
showToastHandler?.('error', t('tagSelector.messages.createError'));
|
|
343
334
|
return null;
|
|
344
335
|
} finally {
|
|
345
336
|
setIsCreatingTag(false);
|
|
@@ -366,18 +357,12 @@ export default function TituloReceberDetalhePage() {
|
|
|
366
357
|
setSelectedTagIds(nextTagIds);
|
|
367
358
|
}
|
|
368
359
|
} catch {
|
|
369
|
-
showToastHandler?.(
|
|
370
|
-
'error',
|
|
371
|
-
tTagSelector(
|
|
372
|
-
'messages.updateError',
|
|
373
|
-
'Não foi possível atualizar as tags'
|
|
374
|
-
)
|
|
375
|
-
);
|
|
360
|
+
showToastHandler?.('error', t('tagSelector.messages.updateError'));
|
|
376
361
|
}
|
|
377
362
|
};
|
|
378
363
|
|
|
379
364
|
const canApprove = titulo.status === 'rascunho';
|
|
380
|
-
const canSettle = ['aberto', 'parcial'].includes(titulo.status);
|
|
365
|
+
const canSettle = ['aberto', 'parcial', 'vencido'].includes(titulo.status);
|
|
381
366
|
|
|
382
367
|
const getErrorMessage = (error: any, fallback: string) => {
|
|
383
368
|
const message = error?.response?.data?.message;
|
|
@@ -406,11 +391,11 @@ export default function TituloReceberDetalhePage() {
|
|
|
406
391
|
});
|
|
407
392
|
|
|
408
393
|
await refetch();
|
|
409
|
-
showToastHandler?.('success', '
|
|
394
|
+
showToastHandler?.('success', t('messages.approveSuccess'));
|
|
410
395
|
} catch (error) {
|
|
411
396
|
showToastHandler?.(
|
|
412
397
|
'error',
|
|
413
|
-
getErrorMessage(error, '
|
|
398
|
+
getErrorMessage(error, t('messages.approveError'))
|
|
414
399
|
);
|
|
415
400
|
} finally {
|
|
416
401
|
setIsApproving(false);
|
|
@@ -436,18 +421,21 @@ export default function TituloReceberDetalhePage() {
|
|
|
436
421
|
|
|
437
422
|
await refetch();
|
|
438
423
|
setIsSettleDialogOpen(false);
|
|
439
|
-
showToastHandler?.('success', '
|
|
424
|
+
showToastHandler?.('success', t('messages.settleSuccess'));
|
|
440
425
|
} catch (error) {
|
|
441
426
|
showToastHandler?.(
|
|
442
427
|
'error',
|
|
443
|
-
getErrorMessage(error, '
|
|
428
|
+
getErrorMessage(error, t('messages.settleError'))
|
|
444
429
|
);
|
|
445
430
|
} finally {
|
|
446
431
|
setIsSettling(false);
|
|
447
432
|
}
|
|
448
433
|
};
|
|
449
434
|
|
|
450
|
-
const handleReverseSettlement = async (
|
|
435
|
+
const handleReverseSettlement = async (
|
|
436
|
+
settlementId: string,
|
|
437
|
+
reasonOverride?: string
|
|
438
|
+
) => {
|
|
451
439
|
if (!settlementId || reversingSettlementId) {
|
|
452
440
|
return;
|
|
453
441
|
}
|
|
@@ -455,17 +443,27 @@ export default function TituloReceberDetalhePage() {
|
|
|
455
443
|
setReversingSettlementId(settlementId);
|
|
456
444
|
try {
|
|
457
445
|
await request({
|
|
458
|
-
url: `/finance/
|
|
459
|
-
method: '
|
|
460
|
-
data: {
|
|
446
|
+
url: `/finance/settlements/${settlementId}/reverse`,
|
|
447
|
+
method: 'POST',
|
|
448
|
+
data: {
|
|
449
|
+
reason:
|
|
450
|
+
reasonOverride?.trim() ||
|
|
451
|
+
reverseReason?.trim() ||
|
|
452
|
+
t('messages.reverseDefaultReason'),
|
|
453
|
+
memo:
|
|
454
|
+
reasonOverride?.trim() ||
|
|
455
|
+
reverseReason?.trim() ||
|
|
456
|
+
t('messages.reverseDefaultReason'),
|
|
457
|
+
},
|
|
461
458
|
});
|
|
462
459
|
|
|
463
460
|
await refetch();
|
|
464
|
-
|
|
461
|
+
setReverseReason('');
|
|
462
|
+
showToastHandler?.('success', t('messages.reverseSuccess'));
|
|
465
463
|
} catch (error) {
|
|
466
464
|
showToastHandler?.(
|
|
467
465
|
'error',
|
|
468
|
-
getErrorMessage(error, '
|
|
466
|
+
getErrorMessage(error, t('messages.reverseError'))
|
|
469
467
|
);
|
|
470
468
|
} finally {
|
|
471
469
|
setReversingSettlementId(null);
|
|
@@ -505,7 +503,7 @@ export default function TituloReceberDetalhePage() {
|
|
|
505
503
|
onClick={() => void handleApprove()}
|
|
506
504
|
>
|
|
507
505
|
<CheckCircle className="mr-2 h-4 w-4" />
|
|
508
|
-
|
|
506
|
+
{t('actions.approve')}
|
|
509
507
|
</DropdownMenuItem>
|
|
510
508
|
<DropdownMenuItem
|
|
511
509
|
disabled={!canSettle || settleCandidates.length === 0}
|
|
@@ -527,9 +525,9 @@ export default function TituloReceberDetalhePage() {
|
|
|
527
525
|
>
|
|
528
526
|
<SheetContent className="w-full sm:max-w-lg overflow-y-auto">
|
|
529
527
|
<SheetHeader>
|
|
530
|
-
<SheetTitle>
|
|
528
|
+
<SheetTitle>{t('settleSheet.title')}</SheetTitle>
|
|
531
529
|
<SheetDescription>
|
|
532
|
-
|
|
530
|
+
{t('settleSheet.description')}
|
|
533
531
|
</SheetDescription>
|
|
534
532
|
</SheetHeader>
|
|
535
533
|
|
|
@@ -543,7 +541,9 @@ export default function TituloReceberDetalhePage() {
|
|
|
543
541
|
name="installmentId"
|
|
544
542
|
render={({ field }) => (
|
|
545
543
|
<FormItem>
|
|
546
|
-
<FormLabel>
|
|
544
|
+
<FormLabel>
|
|
545
|
+
{t('settleSheet.installmentLabel')}
|
|
546
|
+
</FormLabel>
|
|
547
547
|
<Select
|
|
548
548
|
value={field.value}
|
|
549
549
|
onValueChange={(value) => {
|
|
@@ -564,17 +564,23 @@ export default function TituloReceberDetalhePage() {
|
|
|
564
564
|
>
|
|
565
565
|
<FormControl>
|
|
566
566
|
<SelectTrigger>
|
|
567
|
-
<SelectValue
|
|
567
|
+
<SelectValue
|
|
568
|
+
placeholder={t(
|
|
569
|
+
'settleSheet.installmentPlaceholder'
|
|
570
|
+
)}
|
|
571
|
+
/>
|
|
568
572
|
</SelectTrigger>
|
|
569
573
|
</FormControl>
|
|
570
574
|
<SelectContent>
|
|
571
575
|
{settleCandidates.map((parcela: any) => (
|
|
572
576
|
<SelectItem key={parcela.id} value={parcela.id}>
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
577
|
+
{t('settleSheet.installmentOption', {
|
|
578
|
+
number: parcela.numero,
|
|
579
|
+
amount: new Intl.NumberFormat('pt-BR', {
|
|
580
|
+
style: 'currency',
|
|
581
|
+
currency: 'BRL',
|
|
582
|
+
}).format(Number(parcela.valorAberto || 0)),
|
|
583
|
+
})}
|
|
578
584
|
</SelectItem>
|
|
579
585
|
))}
|
|
580
586
|
</SelectContent>
|
|
@@ -589,7 +595,7 @@ export default function TituloReceberDetalhePage() {
|
|
|
589
595
|
name="amount"
|
|
590
596
|
render={({ field }) => (
|
|
591
597
|
<FormItem>
|
|
592
|
-
<FormLabel>
|
|
598
|
+
<FormLabel>{t('settleSheet.amountLabel')}</FormLabel>
|
|
593
599
|
<FormControl>
|
|
594
600
|
<InputMoney
|
|
595
601
|
value={Number(field.value || 0)}
|
|
@@ -608,7 +614,9 @@ export default function TituloReceberDetalhePage() {
|
|
|
608
614
|
name="description"
|
|
609
615
|
render={({ field }) => (
|
|
610
616
|
<FormItem>
|
|
611
|
-
<FormLabel>
|
|
617
|
+
<FormLabel>
|
|
618
|
+
{t('settleSheet.descriptionLabel')}
|
|
619
|
+
</FormLabel>
|
|
612
620
|
<FormControl>
|
|
613
621
|
<Input {...field} value={field.value || ''} />
|
|
614
622
|
</FormControl>
|
|
@@ -624,16 +632,85 @@ export default function TituloReceberDetalhePage() {
|
|
|
624
632
|
disabled={isSettling}
|
|
625
633
|
onClick={() => setIsSettleDialogOpen(false)}
|
|
626
634
|
>
|
|
627
|
-
|
|
635
|
+
{t('common.cancel')}
|
|
628
636
|
</Button>
|
|
629
637
|
<Button type="submit" disabled={isSettling}>
|
|
630
|
-
|
|
638
|
+
{t('settleSheet.confirm')}
|
|
631
639
|
</Button>
|
|
632
640
|
</div>
|
|
633
641
|
</form>
|
|
634
642
|
</Form>
|
|
635
643
|
</SheetContent>
|
|
636
644
|
</Sheet>
|
|
645
|
+
|
|
646
|
+
<Sheet
|
|
647
|
+
open={isReverseSheetOpen}
|
|
648
|
+
onOpenChange={(open) => {
|
|
649
|
+
setIsReverseSheetOpen(open);
|
|
650
|
+
|
|
651
|
+
if (!open) {
|
|
652
|
+
setSelectedSettlementIdToReverse(null);
|
|
653
|
+
setReverseReason('');
|
|
654
|
+
}
|
|
655
|
+
}}
|
|
656
|
+
>
|
|
657
|
+
<SheetContent className="w-full sm:max-w-lg overflow-y-auto">
|
|
658
|
+
<SheetHeader>
|
|
659
|
+
<SheetTitle>{t('reverseSheet.title')}</SheetTitle>
|
|
660
|
+
<SheetDescription>
|
|
661
|
+
{t('reverseSheet.description')}
|
|
662
|
+
</SheetDescription>
|
|
663
|
+
</SheetHeader>
|
|
664
|
+
|
|
665
|
+
<div className="space-y-4 px-4">
|
|
666
|
+
<div className="space-y-2">
|
|
667
|
+
<Label>{t('reverseSheet.reasonLabel')}</Label>
|
|
668
|
+
<Input
|
|
669
|
+
value={reverseReason}
|
|
670
|
+
onChange={(event) => setReverseReason(event.target.value)}
|
|
671
|
+
placeholder={t('reverseSheet.reasonPlaceholder')}
|
|
672
|
+
maxLength={255}
|
|
673
|
+
disabled={!!reversingSettlementId}
|
|
674
|
+
/>
|
|
675
|
+
</div>
|
|
676
|
+
|
|
677
|
+
<div className="flex flex-col gap-2">
|
|
678
|
+
<Button
|
|
679
|
+
disabled={
|
|
680
|
+
!!reversingSettlementId ||
|
|
681
|
+
!selectedSettlementIdToReverse
|
|
682
|
+
}
|
|
683
|
+
onClick={() => {
|
|
684
|
+
if (!selectedSettlementIdToReverse) {
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
void handleReverseSettlement(
|
|
689
|
+
selectedSettlementIdToReverse
|
|
690
|
+
).finally(() => {
|
|
691
|
+
setIsReverseSheetOpen(false);
|
|
692
|
+
setSelectedSettlementIdToReverse(null);
|
|
693
|
+
setReverseReason('');
|
|
694
|
+
});
|
|
695
|
+
}}
|
|
696
|
+
>
|
|
697
|
+
{t('reverseSheet.confirm')}
|
|
698
|
+
</Button>
|
|
699
|
+
<Button
|
|
700
|
+
variant="outline"
|
|
701
|
+
disabled={!!reversingSettlementId}
|
|
702
|
+
onClick={() => {
|
|
703
|
+
setIsReverseSheetOpen(false);
|
|
704
|
+
setSelectedSettlementIdToReverse(null);
|
|
705
|
+
setReverseReason('');
|
|
706
|
+
}}
|
|
707
|
+
>
|
|
708
|
+
{t('common.cancel')}
|
|
709
|
+
</Button>
|
|
710
|
+
</div>
|
|
711
|
+
</div>
|
|
712
|
+
</SheetContent>
|
|
713
|
+
</Sheet>
|
|
637
714
|
</div>
|
|
638
715
|
}
|
|
639
716
|
/>
|
|
@@ -711,35 +788,21 @@ export default function TituloReceberDetalhePage() {
|
|
|
711
788
|
onChange={handleChangeTags}
|
|
712
789
|
onCreateTag={handleCreateTag}
|
|
713
790
|
disabled={isCreatingTag}
|
|
714
|
-
emptyText={
|
|
791
|
+
emptyText={t('tagSelector.noTags')}
|
|
715
792
|
labels={{
|
|
716
|
-
addTag:
|
|
717
|
-
sheetTitle:
|
|
718
|
-
sheetDescription:
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
),
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
),
|
|
727
|
-
createAction: tTagSelector('createAction', 'Criar tag'),
|
|
728
|
-
popularTitle: tTagSelector(
|
|
729
|
-
'popularTitle',
|
|
730
|
-
'Tags mais usadas'
|
|
731
|
-
),
|
|
732
|
-
selectedTitle: tTagSelector(
|
|
733
|
-
'selectedTitle',
|
|
734
|
-
'Tags selecionadas'
|
|
735
|
-
),
|
|
736
|
-
noTags: tTagSelector('noTags', 'Sem tags'),
|
|
737
|
-
cancel: tTagSelector('cancel', 'Cancelar'),
|
|
738
|
-
apply: tTagSelector('apply', 'Aplicar'),
|
|
793
|
+
addTag: t('tagSelector.addTag'),
|
|
794
|
+
sheetTitle: t('tagSelector.sheetTitle'),
|
|
795
|
+
sheetDescription: t('tagSelector.sheetDescription'),
|
|
796
|
+
createLabel: t('tagSelector.createLabel'),
|
|
797
|
+
createPlaceholder: t('tagSelector.createPlaceholder'),
|
|
798
|
+
createAction: t('tagSelector.createAction'),
|
|
799
|
+
popularTitle: t('tagSelector.popularTitle'),
|
|
800
|
+
selectedTitle: t('tagSelector.selectedTitle'),
|
|
801
|
+
noTags: t('tagSelector.noTags'),
|
|
802
|
+
cancel: t('tagSelector.cancel'),
|
|
803
|
+
apply: t('tagSelector.apply'),
|
|
739
804
|
removeTagAria: (tagName: string) =>
|
|
740
|
-
t
|
|
741
|
-
? t('tagSelector.removeTagAria', { tag: tagName })
|
|
742
|
-
: `Remover tag ${tagName}`,
|
|
805
|
+
t('tagSelector.removeTagAria', { tag: tagName }),
|
|
743
806
|
}}
|
|
744
807
|
/>
|
|
745
808
|
</dd>
|
|
@@ -839,7 +902,9 @@ export default function TituloReceberDetalhePage() {
|
|
|
839
902
|
</TableHead>
|
|
840
903
|
<TableHead>{t('receiptsTable.account')}</TableHead>
|
|
841
904
|
<TableHead>{t('receiptsTable.method')}</TableHead>
|
|
842
|
-
<TableHead className="text-right">
|
|
905
|
+
<TableHead className="text-right">
|
|
906
|
+
{t('receiptsTable.actions')}
|
|
907
|
+
</TableHead>
|
|
843
908
|
</TableRow>
|
|
844
909
|
</TableHeader>
|
|
845
910
|
<TableBody>
|
|
@@ -863,47 +928,25 @@ export default function TituloReceberDetalhePage() {
|
|
|
863
928
|
{liq.metodo}
|
|
864
929
|
</TableCell>
|
|
865
930
|
<TableCell className="text-right">
|
|
866
|
-
<
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
</AlertDialogTitle>
|
|
886
|
-
<AlertDialogDescription>
|
|
887
|
-
Esta ação estorna o recebimento e
|
|
888
|
-
recalcula saldos e status.
|
|
889
|
-
</AlertDialogDescription>
|
|
890
|
-
</AlertDialogHeader>
|
|
891
|
-
<AlertDialogFooter>
|
|
892
|
-
<AlertDialogCancel>
|
|
893
|
-
Cancelar
|
|
894
|
-
</AlertDialogCancel>
|
|
895
|
-
<AlertDialogAction
|
|
896
|
-
onClick={() =>
|
|
897
|
-
void handleReverseSettlement(
|
|
898
|
-
String(liq.settlementId)
|
|
899
|
-
)
|
|
900
|
-
}
|
|
901
|
-
>
|
|
902
|
-
Confirmar estorno
|
|
903
|
-
</AlertDialogAction>
|
|
904
|
-
</AlertDialogFooter>
|
|
905
|
-
</AlertDialogContent>
|
|
906
|
-
</AlertDialog>
|
|
931
|
+
<Button
|
|
932
|
+
variant="outline"
|
|
933
|
+
size="sm"
|
|
934
|
+
disabled={
|
|
935
|
+
!liq.settlementId ||
|
|
936
|
+
liq.status === 'reversed' ||
|
|
937
|
+
!!reversingSettlementId
|
|
938
|
+
}
|
|
939
|
+
onClick={() => {
|
|
940
|
+
setSelectedSettlementIdToReverse(
|
|
941
|
+
String(liq.settlementId)
|
|
942
|
+
);
|
|
943
|
+
setReverseReason('');
|
|
944
|
+
setIsReverseSheetOpen(true);
|
|
945
|
+
}}
|
|
946
|
+
>
|
|
947
|
+
<Undo className="mr-2 h-4 w-4" />
|
|
948
|
+
{t('receiptsTable.reverseButton')}
|
|
949
|
+
</Button>
|
|
907
950
|
</TableCell>
|
|
908
951
|
</TableRow>
|
|
909
952
|
);
|