@hed-hog/finance 0.0.238 → 0.0.239
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/reject-title.dto.d.ts +4 -0
- package/dist/dto/reject-title.dto.d.ts.map +1 -0
- package/dist/dto/reject-title.dto.js +22 -0
- package/dist/dto/reject-title.dto.js.map +1 -0
- package/dist/dto/reverse-settlement.dto.d.ts +4 -0
- package/dist/dto/reverse-settlement.dto.d.ts.map +1 -0
- package/dist/dto/reverse-settlement.dto.js +22 -0
- package/dist/dto/reverse-settlement.dto.js.map +1 -0
- package/dist/dto/settle-installment.dto.d.ts +12 -0
- package/dist/dto/settle-installment.dto.d.ts.map +1 -0
- package/dist/dto/settle-installment.dto.js +71 -0
- package/dist/dto/settle-installment.dto.js.map +1 -0
- package/dist/finance-data.controller.d.ts +13 -5
- package/dist/finance-data.controller.d.ts.map +1 -1
- package/dist/finance-installments.controller.d.ts +248 -12
- package/dist/finance-installments.controller.d.ts.map +1 -1
- package/dist/finance-installments.controller.js +92 -0
- package/dist/finance-installments.controller.js.map +1 -1
- package/dist/finance.service.d.ts +275 -17
- package/dist/finance.service.d.ts.map +1 -1
- package/dist/finance.service.js +666 -78
- package/dist/finance.service.js.map +1 -1
- package/hedhog/data/route.yaml +63 -0
- package/hedhog/frontend/app/accounts-payable/approvals/page.tsx.ejs +92 -12
- package/hedhog/frontend/app/accounts-payable/installments/[id]/page.tsx.ejs +355 -4
- package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +440 -16
- package/hedhog/frontend/app/accounts-receivable/installments/[id]/page.tsx.ejs +396 -49
- package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +432 -14
- package/package.json +5 -5
- package/src/dto/reject-title.dto.ts +7 -0
- package/src/dto/reverse-settlement.dto.ts +7 -0
- package/src/dto/settle-installment.dto.ts +55 -0
- package/src/finance-installments.controller.ts +102 -0
- package/src/finance.service.ts +1007 -82
|
@@ -1,6 +1,17 @@
|
|
|
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';
|
|
4
15
|
import { AuditTimeline } from '@/components/ui/audit-timeline';
|
|
5
16
|
import { Button } from '@/components/ui/button';
|
|
6
17
|
import {
|
|
@@ -10,6 +21,14 @@ import {
|
|
|
10
21
|
CardHeader,
|
|
11
22
|
CardTitle,
|
|
12
23
|
} from '@/components/ui/card';
|
|
24
|
+
import {
|
|
25
|
+
Dialog,
|
|
26
|
+
DialogContent,
|
|
27
|
+
DialogDescription,
|
|
28
|
+
DialogFooter,
|
|
29
|
+
DialogHeader,
|
|
30
|
+
DialogTitle,
|
|
31
|
+
} from '@/components/ui/dialog';
|
|
13
32
|
import {
|
|
14
33
|
DropdownMenu,
|
|
15
34
|
DropdownMenuContent,
|
|
@@ -17,7 +36,24 @@ import {
|
|
|
17
36
|
DropdownMenuSeparator,
|
|
18
37
|
DropdownMenuTrigger,
|
|
19
38
|
} from '@/components/ui/dropdown-menu';
|
|
39
|
+
import {
|
|
40
|
+
Form,
|
|
41
|
+
FormControl,
|
|
42
|
+
FormField,
|
|
43
|
+
FormItem,
|
|
44
|
+
FormLabel,
|
|
45
|
+
FormMessage,
|
|
46
|
+
} from '@/components/ui/form';
|
|
47
|
+
import { Input } from '@/components/ui/input';
|
|
48
|
+
import { InputMoney } from '@/components/ui/input-money';
|
|
20
49
|
import { Money } from '@/components/ui/money';
|
|
50
|
+
import {
|
|
51
|
+
Select,
|
|
52
|
+
SelectContent,
|
|
53
|
+
SelectItem,
|
|
54
|
+
SelectTrigger,
|
|
55
|
+
SelectValue,
|
|
56
|
+
} from '@/components/ui/select';
|
|
21
57
|
import { StatusBadge } from '@/components/ui/status-badge';
|
|
22
58
|
import {
|
|
23
59
|
Table,
|
|
@@ -30,6 +66,7 @@ import {
|
|
|
30
66
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
|
31
67
|
import { TagSelectorSheet } from '@/components/ui/tag-selector-sheet';
|
|
32
68
|
import { useApp } from '@hed-hog/next-app-provider';
|
|
69
|
+
import { zodResolver } from '@hookform/resolvers/zod';
|
|
33
70
|
import {
|
|
34
71
|
CheckCircle,
|
|
35
72
|
Download,
|
|
@@ -43,15 +80,25 @@ import { useTranslations } from 'next-intl';
|
|
|
43
80
|
import Link from 'next/link';
|
|
44
81
|
import { useParams } from 'next/navigation';
|
|
45
82
|
import { useEffect, useState } from 'react';
|
|
83
|
+
import { useForm } from 'react-hook-form';
|
|
84
|
+
import { z } from 'zod';
|
|
46
85
|
import { formatarData } from '../../../_lib/formatters';
|
|
47
86
|
import { useFinanceData } from '../../../_lib/use-finance-data';
|
|
48
87
|
|
|
88
|
+
const settleSchema = z.object({
|
|
89
|
+
installmentId: z.string().min(1, 'Parcela obrigatória'),
|
|
90
|
+
amount: z.number().min(0.01, 'Valor deve ser maior que zero'),
|
|
91
|
+
description: z.string().optional(),
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
type SettleFormValues = z.infer<typeof settleSchema>;
|
|
95
|
+
|
|
49
96
|
export default function TituloDetalhePage() {
|
|
50
97
|
const t = useTranslations('finance.PayableInstallmentDetailPage');
|
|
51
98
|
const { request, showToastHandler } = useApp();
|
|
52
99
|
const params = useParams<{ id: string }>();
|
|
53
100
|
const id = params?.id;
|
|
54
|
-
const { data } = useFinanceData();
|
|
101
|
+
const { data, refetch } = useFinanceData();
|
|
55
102
|
const {
|
|
56
103
|
titulosPagar,
|
|
57
104
|
pessoas,
|
|
@@ -64,9 +111,31 @@ export default function TituloDetalhePage() {
|
|
|
64
111
|
|
|
65
112
|
const titulo = titulosPagar.find((t) => t.id === id);
|
|
66
113
|
|
|
114
|
+
const settleCandidates = (titulo?.parcelas || []).filter(
|
|
115
|
+
(parcela: any) =>
|
|
116
|
+
parcela.status === 'aberto' ||
|
|
117
|
+
parcela.status === 'parcial' ||
|
|
118
|
+
parcela.status === 'vencido'
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const settleForm = useForm<SettleFormValues>({
|
|
122
|
+
resolver: zodResolver(settleSchema),
|
|
123
|
+
defaultValues: {
|
|
124
|
+
installmentId: settleCandidates[0]?.id || '',
|
|
125
|
+
amount: Number(settleCandidates[0]?.valorAberto || 0),
|
|
126
|
+
description: '',
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
67
130
|
const [availableTags, setAvailableTags] = useState<any[]>([]);
|
|
68
131
|
const [selectedTagIds, setSelectedTagIds] = useState<string[]>([]);
|
|
69
132
|
const [isCreatingTag, setIsCreatingTag] = useState(false);
|
|
133
|
+
const [isApproving, setIsApproving] = useState(false);
|
|
134
|
+
const [isSettling, setIsSettling] = useState(false);
|
|
135
|
+
const [isSettleDialogOpen, setIsSettleDialogOpen] = useState(false);
|
|
136
|
+
const [reversingSettlementId, setReversingSettlementId] = useState<
|
|
137
|
+
string | null
|
|
138
|
+
>(null);
|
|
70
139
|
|
|
71
140
|
useEffect(() => {
|
|
72
141
|
setAvailableTags(tags || []);
|
|
@@ -80,6 +149,27 @@ export default function TituloDetalhePage() {
|
|
|
80
149
|
setSelectedTagIds(Array.isArray(titulo.tags) ? titulo.tags : []);
|
|
81
150
|
}, [titulo]);
|
|
82
151
|
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
const firstCandidate = settleCandidates[0];
|
|
154
|
+
const nextInstallmentId = firstCandidate?.id || '';
|
|
155
|
+
const nextAmount = Number(firstCandidate?.valorAberto || 0);
|
|
156
|
+
const currentInstallmentId = settleForm.getValues('installmentId') || '';
|
|
157
|
+
const currentAmount = Number(settleForm.getValues('amount') || 0);
|
|
158
|
+
|
|
159
|
+
if (
|
|
160
|
+
currentInstallmentId === nextInstallmentId &&
|
|
161
|
+
currentAmount === nextAmount
|
|
162
|
+
) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
settleForm.reset({
|
|
167
|
+
installmentId: nextInstallmentId,
|
|
168
|
+
amount: nextAmount,
|
|
169
|
+
description: '',
|
|
170
|
+
});
|
|
171
|
+
}, [settleForm, settleCandidates]);
|
|
172
|
+
|
|
83
173
|
if (!titulo) {
|
|
84
174
|
return (
|
|
85
175
|
<div className="space-y-6">
|
|
@@ -267,6 +357,102 @@ export default function TituloDetalhePage() {
|
|
|
267
357
|
}
|
|
268
358
|
};
|
|
269
359
|
|
|
360
|
+
const canApprove = titulo.status === 'rascunho';
|
|
361
|
+
const canSettle = ['aprovado', 'aberto', 'parcial'].includes(titulo.status);
|
|
362
|
+
|
|
363
|
+
const getErrorMessage = (error: any, fallback: string) => {
|
|
364
|
+
const message = error?.response?.data?.message;
|
|
365
|
+
|
|
366
|
+
if (Array.isArray(message)) {
|
|
367
|
+
return message.join(', ');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (typeof message === 'string' && message.trim()) {
|
|
371
|
+
return message;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return fallback;
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
const handleApprove = async () => {
|
|
378
|
+
if (!canApprove || isApproving) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
setIsApproving(true);
|
|
383
|
+
try {
|
|
384
|
+
await request({
|
|
385
|
+
url: `/finance/accounts-payable/installments/${titulo.id}/approve`,
|
|
386
|
+
method: 'PATCH',
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
await refetch();
|
|
390
|
+
showToastHandler?.('success', 'Título aprovado com sucesso');
|
|
391
|
+
} catch (error) {
|
|
392
|
+
showToastHandler?.(
|
|
393
|
+
'error',
|
|
394
|
+
getErrorMessage(error, 'Não foi possível aprovar o título')
|
|
395
|
+
);
|
|
396
|
+
} finally {
|
|
397
|
+
setIsApproving(false);
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const handleSettle = async (values: SettleFormValues) => {
|
|
402
|
+
if (!canSettle || isSettling) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
setIsSettling(true);
|
|
407
|
+
try {
|
|
408
|
+
await request({
|
|
409
|
+
url: `/finance/accounts-payable/installments/${titulo.id}/settlements`,
|
|
410
|
+
method: 'POST',
|
|
411
|
+
data: {
|
|
412
|
+
installment_id: Number(values.installmentId),
|
|
413
|
+
amount: values.amount,
|
|
414
|
+
description: values.description?.trim() || undefined,
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
await refetch();
|
|
419
|
+
setIsSettleDialogOpen(false);
|
|
420
|
+
showToastHandler?.('success', 'Baixa registrada com sucesso');
|
|
421
|
+
} catch (error) {
|
|
422
|
+
showToastHandler?.(
|
|
423
|
+
'error',
|
|
424
|
+
getErrorMessage(error, 'Não foi possível registrar a baixa')
|
|
425
|
+
);
|
|
426
|
+
} finally {
|
|
427
|
+
setIsSettling(false);
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
const handleReverseSettlement = async (settlementId: string) => {
|
|
432
|
+
if (!settlementId || reversingSettlementId) {
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
setReversingSettlementId(settlementId);
|
|
437
|
+
try {
|
|
438
|
+
await request({
|
|
439
|
+
url: `/finance/accounts-payable/installments/${titulo.id}/settlements/${settlementId}/reverse`,
|
|
440
|
+
method: 'PATCH',
|
|
441
|
+
data: {},
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
await refetch();
|
|
445
|
+
showToastHandler?.('success', 'Estorno realizado com sucesso');
|
|
446
|
+
} catch (error) {
|
|
447
|
+
showToastHandler?.(
|
|
448
|
+
'error',
|
|
449
|
+
getErrorMessage(error, 'Não foi possível estornar a liquidação')
|
|
450
|
+
);
|
|
451
|
+
} finally {
|
|
452
|
+
setReversingSettlementId(null);
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
|
|
270
456
|
return (
|
|
271
457
|
<Page>
|
|
272
458
|
<PageHeader
|
|
@@ -295,15 +481,21 @@ export default function TituloDetalhePage() {
|
|
|
295
481
|
<Edit className="mr-2 h-4 w-4" />
|
|
296
482
|
{t('actions.edit')}
|
|
297
483
|
</DropdownMenuItem>
|
|
298
|
-
<DropdownMenuItem
|
|
484
|
+
<DropdownMenuItem
|
|
485
|
+
disabled={!canApprove || isApproving}
|
|
486
|
+
onClick={() => void handleApprove()}
|
|
487
|
+
>
|
|
299
488
|
<CheckCircle className="mr-2 h-4 w-4" />
|
|
300
489
|
{t('actions.approve')}
|
|
301
490
|
</DropdownMenuItem>
|
|
302
|
-
<DropdownMenuItem
|
|
491
|
+
<DropdownMenuItem
|
|
492
|
+
disabled={!canSettle || settleCandidates.length === 0}
|
|
493
|
+
onClick={() => setIsSettleDialogOpen(true)}
|
|
494
|
+
>
|
|
303
495
|
<Download className="mr-2 h-4 w-4" />
|
|
304
496
|
{t('actions.settle')}
|
|
305
497
|
</DropdownMenuItem>
|
|
306
|
-
<DropdownMenuItem>
|
|
498
|
+
<DropdownMenuItem disabled>
|
|
307
499
|
<Undo className="mr-2 h-4 w-4" />
|
|
308
500
|
{t('actions.reverse')}
|
|
309
501
|
</DropdownMenuItem>
|
|
@@ -314,6 +506,121 @@ export default function TituloDetalhePage() {
|
|
|
314
506
|
</DropdownMenuItem>
|
|
315
507
|
</DropdownMenuContent>
|
|
316
508
|
</DropdownMenu>
|
|
509
|
+
|
|
510
|
+
<Dialog
|
|
511
|
+
open={isSettleDialogOpen}
|
|
512
|
+
onOpenChange={setIsSettleDialogOpen}
|
|
513
|
+
>
|
|
514
|
+
<DialogContent>
|
|
515
|
+
<DialogHeader>
|
|
516
|
+
<DialogTitle>Registrar baixa</DialogTitle>
|
|
517
|
+
<DialogDescription>
|
|
518
|
+
Informe a parcela e o valor da baixa. O backend valida os
|
|
519
|
+
estados e limites de valor automaticamente.
|
|
520
|
+
</DialogDescription>
|
|
521
|
+
</DialogHeader>
|
|
522
|
+
|
|
523
|
+
<Form {...settleForm}>
|
|
524
|
+
<form
|
|
525
|
+
className="space-y-4"
|
|
526
|
+
onSubmit={settleForm.handleSubmit(handleSettle)}
|
|
527
|
+
>
|
|
528
|
+
<FormField
|
|
529
|
+
control={settleForm.control}
|
|
530
|
+
name="installmentId"
|
|
531
|
+
render={({ field }) => (
|
|
532
|
+
<FormItem>
|
|
533
|
+
<FormLabel>Parcela</FormLabel>
|
|
534
|
+
<Select
|
|
535
|
+
value={field.value}
|
|
536
|
+
onValueChange={(value) => {
|
|
537
|
+
field.onChange(value);
|
|
538
|
+
|
|
539
|
+
const selected = settleCandidates.find(
|
|
540
|
+
(parcela: any) => parcela.id === value
|
|
541
|
+
);
|
|
542
|
+
|
|
543
|
+
if (selected) {
|
|
544
|
+
settleForm.setValue(
|
|
545
|
+
'amount',
|
|
546
|
+
Number(selected.valorAberto || 0),
|
|
547
|
+
{ shouldValidate: true }
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
}}
|
|
551
|
+
>
|
|
552
|
+
<FormControl>
|
|
553
|
+
<SelectTrigger>
|
|
554
|
+
<SelectValue placeholder="Selecione" />
|
|
555
|
+
</SelectTrigger>
|
|
556
|
+
</FormControl>
|
|
557
|
+
<SelectContent>
|
|
558
|
+
{settleCandidates.map((parcela: any) => (
|
|
559
|
+
<SelectItem key={parcela.id} value={parcela.id}>
|
|
560
|
+
Parcela {parcela.numero} - em aberto:{' '}
|
|
561
|
+
{new Intl.NumberFormat('pt-BR', {
|
|
562
|
+
style: 'currency',
|
|
563
|
+
currency: 'BRL',
|
|
564
|
+
}).format(Number(parcela.valorAberto || 0))}
|
|
565
|
+
</SelectItem>
|
|
566
|
+
))}
|
|
567
|
+
</SelectContent>
|
|
568
|
+
</Select>
|
|
569
|
+
<FormMessage />
|
|
570
|
+
</FormItem>
|
|
571
|
+
)}
|
|
572
|
+
/>
|
|
573
|
+
|
|
574
|
+
<FormField
|
|
575
|
+
control={settleForm.control}
|
|
576
|
+
name="amount"
|
|
577
|
+
render={({ field }) => (
|
|
578
|
+
<FormItem>
|
|
579
|
+
<FormLabel>Valor</FormLabel>
|
|
580
|
+
<FormControl>
|
|
581
|
+
<InputMoney
|
|
582
|
+
value={Number(field.value || 0)}
|
|
583
|
+
onValueChange={(value) => {
|
|
584
|
+
field.onChange(Number(value || 0));
|
|
585
|
+
}}
|
|
586
|
+
/>
|
|
587
|
+
</FormControl>
|
|
588
|
+
<FormMessage />
|
|
589
|
+
</FormItem>
|
|
590
|
+
)}
|
|
591
|
+
/>
|
|
592
|
+
|
|
593
|
+
<FormField
|
|
594
|
+
control={settleForm.control}
|
|
595
|
+
name="description"
|
|
596
|
+
render={({ field }) => (
|
|
597
|
+
<FormItem>
|
|
598
|
+
<FormLabel>Descrição (opcional)</FormLabel>
|
|
599
|
+
<FormControl>
|
|
600
|
+
<Input {...field} value={field.value || ''} />
|
|
601
|
+
</FormControl>
|
|
602
|
+
<FormMessage />
|
|
603
|
+
</FormItem>
|
|
604
|
+
)}
|
|
605
|
+
/>
|
|
606
|
+
|
|
607
|
+
<DialogFooter>
|
|
608
|
+
<Button
|
|
609
|
+
type="button"
|
|
610
|
+
variant="outline"
|
|
611
|
+
disabled={isSettling}
|
|
612
|
+
onClick={() => setIsSettleDialogOpen(false)}
|
|
613
|
+
>
|
|
614
|
+
Cancelar
|
|
615
|
+
</Button>
|
|
616
|
+
<Button type="submit" disabled={isSettling}>
|
|
617
|
+
Confirmar baixa
|
|
618
|
+
</Button>
|
|
619
|
+
</DialogFooter>
|
|
620
|
+
</form>
|
|
621
|
+
</Form>
|
|
622
|
+
</DialogContent>
|
|
623
|
+
</Dialog>
|
|
317
624
|
</div>
|
|
318
625
|
}
|
|
319
626
|
/>
|
|
@@ -522,6 +829,7 @@ export default function TituloDetalhePage() {
|
|
|
522
829
|
</TableHead>
|
|
523
830
|
<TableHead>{t('settlementsTable.account')}</TableHead>
|
|
524
831
|
<TableHead>{t('settlementsTable.method')}</TableHead>
|
|
832
|
+
<TableHead className="text-right">Ações</TableHead>
|
|
525
833
|
</TableRow>
|
|
526
834
|
</TableHeader>
|
|
527
835
|
<TableBody>
|
|
@@ -547,6 +855,49 @@ export default function TituloDetalhePage() {
|
|
|
547
855
|
<TableCell className="capitalize">
|
|
548
856
|
{liq.metodo}
|
|
549
857
|
</TableCell>
|
|
858
|
+
<TableCell className="text-right">
|
|
859
|
+
<AlertDialog>
|
|
860
|
+
<AlertDialogTrigger asChild>
|
|
861
|
+
<Button
|
|
862
|
+
variant="outline"
|
|
863
|
+
size="sm"
|
|
864
|
+
disabled={
|
|
865
|
+
!liq.settlementId ||
|
|
866
|
+
liq.status === 'reversed' ||
|
|
867
|
+
!!reversingSettlementId
|
|
868
|
+
}
|
|
869
|
+
>
|
|
870
|
+
<Undo className="mr-2 h-4 w-4" />
|
|
871
|
+
Estornar
|
|
872
|
+
</Button>
|
|
873
|
+
</AlertDialogTrigger>
|
|
874
|
+
<AlertDialogContent>
|
|
875
|
+
<AlertDialogHeader>
|
|
876
|
+
<AlertDialogTitle>
|
|
877
|
+
Confirmar estorno
|
|
878
|
+
</AlertDialogTitle>
|
|
879
|
+
<AlertDialogDescription>
|
|
880
|
+
Esta ação cria o estorno da liquidação e
|
|
881
|
+
recalcula saldos e status.
|
|
882
|
+
</AlertDialogDescription>
|
|
883
|
+
</AlertDialogHeader>
|
|
884
|
+
<AlertDialogFooter>
|
|
885
|
+
<AlertDialogCancel>
|
|
886
|
+
Cancelar
|
|
887
|
+
</AlertDialogCancel>
|
|
888
|
+
<AlertDialogAction
|
|
889
|
+
onClick={() =>
|
|
890
|
+
void handleReverseSettlement(
|
|
891
|
+
String(liq.settlementId)
|
|
892
|
+
)
|
|
893
|
+
}
|
|
894
|
+
>
|
|
895
|
+
Confirmar estorno
|
|
896
|
+
</AlertDialogAction>
|
|
897
|
+
</AlertDialogFooter>
|
|
898
|
+
</AlertDialogContent>
|
|
899
|
+
</AlertDialog>
|
|
900
|
+
</TableCell>
|
|
550
901
|
</TableRow>
|
|
551
902
|
);
|
|
552
903
|
})
|