@hed-hog/finance 0.0.224 → 0.0.225
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-financial-title.dto.d.ts +19 -0
- package/dist/dto/create-financial-title.dto.d.ts.map +1 -0
- package/dist/dto/create-financial-title.dto.js +128 -0
- package/dist/dto/create-financial-title.dto.js.map +1 -0
- package/dist/finance.controller.d.ts +276 -0
- package/dist/finance.controller.d.ts.map +1 -0
- package/dist/finance.controller.js +110 -0
- package/dist/finance.controller.js.map +1 -0
- package/dist/finance.module.d.ts.map +1 -1
- package/dist/finance.module.js +8 -3
- package/dist/finance.module.js.map +1 -1
- package/dist/finance.service.d.ts +295 -0
- package/dist/finance.service.d.ts.map +1 -0
- package/dist/finance.service.js +416 -0
- package/dist/finance.service.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/hedhog/data/menu.yaml +72 -25
- package/hedhog/data/route.yaml +55 -1
- package/hedhog/frontend/app/accounts-payable/approvals/page.tsx.ejs +69 -44
- package/hedhog/frontend/app/accounts-payable/installments/[id]/page.tsx.ejs +68 -46
- package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +87 -63
- package/hedhog/frontend/app/accounts-receivable/collections-default/page.tsx.ejs +94 -59
- package/hedhog/frontend/app/accounts-receivable/installments/[id]/page.tsx.ejs +78 -52
- package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +89 -68
- package/hedhog/frontend/app/cash-and-banks/bank-accounts/page.tsx.ejs +69 -47
- package/hedhog/frontend/app/cash-and-banks/bank-reconciliation/page.tsx.ejs +79 -53
- package/hedhog/frontend/app/cash-and-banks/statements/page.tsx.ejs +43 -36
- package/hedhog/frontend/app/cash-and-banks/transfers/page.tsx.ejs +47 -38
- package/hedhog/frontend/app/page.tsx.ejs +54 -31
- package/hedhog/frontend/app/planning/cash-flow-forecast/page.tsx.ejs +51 -38
- package/hedhog/frontend/app/planning/receivables-calendar/page.tsx.ejs +63 -33
- package/hedhog/frontend/app/planning/scenarios/page.tsx.ejs +50 -33
- package/hedhog/frontend/messages/en.json +776 -0
- package/hedhog/frontend/messages/pt.json +776 -0
- package/package.json +3 -3
- package/src/dto/create-financial-title.dto.ts +142 -0
- package/src/finance.controller.ts +89 -0
- package/src/finance.module.ts +8 -3
- package/src/finance.service.ts +529 -0
- package/src/index.ts +4 -0
package/hedhog/data/route.yaml
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
|
-
- url: /finance
|
|
1
|
+
- url: /finance/data
|
|
2
2
|
method: GET
|
|
3
|
+
relations:
|
|
4
|
+
role:
|
|
5
|
+
- where:
|
|
6
|
+
slug: admin
|
|
7
|
+
- where:
|
|
8
|
+
slug: admin-finance
|
|
9
|
+
|
|
10
|
+
- url: /finance/accounts-payable/installments
|
|
11
|
+
method: GET
|
|
12
|
+
relations:
|
|
13
|
+
role:
|
|
14
|
+
- where:
|
|
15
|
+
slug: admin
|
|
16
|
+
- where:
|
|
17
|
+
slug: admin-finance
|
|
18
|
+
|
|
19
|
+
- url: /finance/accounts-payable/installments/:id
|
|
20
|
+
method: GET
|
|
21
|
+
relations:
|
|
22
|
+
role:
|
|
23
|
+
- where:
|
|
24
|
+
slug: admin
|
|
25
|
+
- where:
|
|
26
|
+
slug: admin-finance
|
|
27
|
+
|
|
28
|
+
- url: /finance/accounts-payable/installments
|
|
29
|
+
method: POST
|
|
30
|
+
relations:
|
|
31
|
+
role:
|
|
32
|
+
- where:
|
|
33
|
+
slug: admin
|
|
34
|
+
- where:
|
|
35
|
+
slug: admin-finance
|
|
36
|
+
|
|
37
|
+
- url: /finance/accounts-receivable/installments
|
|
38
|
+
method: GET
|
|
39
|
+
relations:
|
|
40
|
+
role:
|
|
41
|
+
- where:
|
|
42
|
+
slug: admin
|
|
43
|
+
- where:
|
|
44
|
+
slug: admin-finance
|
|
45
|
+
|
|
46
|
+
- url: /finance/accounts-receivable/installments/:id
|
|
47
|
+
method: GET
|
|
48
|
+
relations:
|
|
49
|
+
role:
|
|
50
|
+
- where:
|
|
51
|
+
slug: admin
|
|
52
|
+
- where:
|
|
53
|
+
slug: admin-finance
|
|
54
|
+
|
|
55
|
+
- url: /finance/accounts-receivable/installments
|
|
56
|
+
method: POST
|
|
3
57
|
relations:
|
|
4
58
|
role:
|
|
5
59
|
- where:
|
|
@@ -20,7 +20,8 @@ import {
|
|
|
20
20
|
} from '@/components/ui/dialog';
|
|
21
21
|
import { Label } from '@/components/ui/label';
|
|
22
22
|
import { Money } from '@/components/ui/money';
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
import { Page, PageHeader } from '@/components/entity-list';
|
|
24
25
|
import {
|
|
25
26
|
Table,
|
|
26
27
|
TableBody,
|
|
@@ -31,23 +32,19 @@ import {
|
|
|
31
32
|
} from '@/components/ui/table';
|
|
32
33
|
import { Textarea } from '@/components/ui/textarea';
|
|
33
34
|
import { AlertTriangle, CheckCircle, Clock, XCircle } from 'lucide-react';
|
|
35
|
+
import { useTranslations } from 'next-intl';
|
|
34
36
|
import { useEffect, useState } from 'react';
|
|
35
37
|
import { formatarData } from '../../_lib/formatters';
|
|
36
38
|
import { useFinanceData } from '../../_lib/use-finance-data';
|
|
37
39
|
|
|
38
|
-
const urgenciaConfig = {
|
|
39
|
-
baixa: { label: 'Baixa', className: 'bg-slate-100 text-slate-700' },
|
|
40
|
-
media: { label: 'Média', className: 'bg-blue-100 text-blue-700' },
|
|
41
|
-
alta: { label: 'Alta', className: 'bg-orange-100 text-orange-700' },
|
|
42
|
-
critica: { label: 'Crítica', className: 'bg-red-100 text-red-700' },
|
|
43
|
-
};
|
|
44
|
-
|
|
45
40
|
function AprovacaoDialog({
|
|
46
41
|
tipo,
|
|
47
42
|
onConfirm,
|
|
43
|
+
t,
|
|
48
44
|
}: {
|
|
49
45
|
tipo: 'aprovar' | 'reprovar';
|
|
50
46
|
onConfirm: () => void;
|
|
47
|
+
t: ReturnType<typeof useTranslations>;
|
|
51
48
|
}) {
|
|
52
49
|
const isAprovar = tipo === 'aprovar';
|
|
53
50
|
|
|
@@ -58,12 +55,12 @@ function AprovacaoDialog({
|
|
|
58
55
|
{isAprovar ? (
|
|
59
56
|
<>
|
|
60
57
|
<CheckCircle className="mr-2 h-4 w-4" />
|
|
61
|
-
|
|
58
|
+
{t('dialog.approveAction')}
|
|
62
59
|
</>
|
|
63
60
|
) : (
|
|
64
61
|
<>
|
|
65
62
|
<XCircle className="mr-2 h-4 w-4" />
|
|
66
|
-
|
|
63
|
+
{t('dialog.rejectAction')}
|
|
67
64
|
</>
|
|
68
65
|
)}
|
|
69
66
|
</Button>
|
|
@@ -71,34 +68,34 @@ function AprovacaoDialog({
|
|
|
71
68
|
<DialogContent>
|
|
72
69
|
<DialogHeader>
|
|
73
70
|
<DialogTitle>
|
|
74
|
-
{isAprovar ? '
|
|
71
|
+
{isAprovar ? t('dialog.approveTitle') : t('dialog.rejectTitle')}
|
|
75
72
|
</DialogTitle>
|
|
76
73
|
<DialogDescription>
|
|
77
74
|
{isAprovar
|
|
78
|
-
? '
|
|
79
|
-
: '
|
|
75
|
+
? t('dialog.approveDescription')
|
|
76
|
+
: t('dialog.rejectDescription')}
|
|
80
77
|
</DialogDescription>
|
|
81
78
|
</DialogHeader>
|
|
82
79
|
<div className="space-y-4">
|
|
83
80
|
<div className="space-y-2">
|
|
84
|
-
<Label htmlFor="comentario">
|
|
81
|
+
<Label htmlFor="comentario">{t('dialog.comment')}</Label>
|
|
85
82
|
<Textarea
|
|
86
83
|
id="comentario"
|
|
87
84
|
placeholder={
|
|
88
85
|
isAprovar
|
|
89
|
-
? '
|
|
90
|
-
: '
|
|
86
|
+
? t('dialog.optionalCommentPlaceholder')
|
|
87
|
+
: t('dialog.rejectReasonPlaceholder')
|
|
91
88
|
}
|
|
92
89
|
/>
|
|
93
90
|
</div>
|
|
94
91
|
</div>
|
|
95
92
|
<DialogFooter>
|
|
96
|
-
<Button variant="outline">
|
|
93
|
+
<Button variant="outline">{t('dialog.cancel')}</Button>
|
|
97
94
|
<Button
|
|
98
95
|
variant={isAprovar ? 'default' : 'destructive'}
|
|
99
96
|
onClick={onConfirm}
|
|
100
97
|
>
|
|
101
|
-
{isAprovar ? '
|
|
98
|
+
{isAprovar ? t('dialog.confirmApprove') : t('dialog.confirmReject')}
|
|
102
99
|
</Button>
|
|
103
100
|
</DialogFooter>
|
|
104
101
|
</DialogContent>
|
|
@@ -107,6 +104,7 @@ function AprovacaoDialog({
|
|
|
107
104
|
}
|
|
108
105
|
|
|
109
106
|
export default function AprovacoesPage() {
|
|
107
|
+
const t = useTranslations('finance.PayableApprovalsPage');
|
|
110
108
|
const { data } = useFinanceData();
|
|
111
109
|
const { aprovacoesPendentes, titulosPagar, pessoas } = data;
|
|
112
110
|
|
|
@@ -122,26 +120,45 @@ export default function AprovacoesPage() {
|
|
|
122
120
|
setAprovacoes(aprovacoes.filter((a) => a.id !== id));
|
|
123
121
|
};
|
|
124
122
|
|
|
123
|
+
const urgenciaConfig = {
|
|
124
|
+
baixa: {
|
|
125
|
+
label: t('urgency.low'),
|
|
126
|
+
className: 'bg-slate-100 text-slate-700',
|
|
127
|
+
},
|
|
128
|
+
media: {
|
|
129
|
+
label: t('urgency.medium'),
|
|
130
|
+
className: 'bg-blue-100 text-blue-700',
|
|
131
|
+
},
|
|
132
|
+
alta: {
|
|
133
|
+
label: t('urgency.high'),
|
|
134
|
+
className: 'bg-orange-100 text-orange-700',
|
|
135
|
+
},
|
|
136
|
+
critica: {
|
|
137
|
+
label: t('urgency.critical'),
|
|
138
|
+
className: 'bg-red-100 text-red-700',
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
|
|
125
142
|
const totalPendente = aprovacoes.reduce((acc, a) => acc + a.valor, 0);
|
|
126
143
|
|
|
127
144
|
return (
|
|
128
|
-
<
|
|
145
|
+
<Page>
|
|
129
146
|
<PageHeader
|
|
130
|
-
title=
|
|
131
|
-
description=
|
|
147
|
+
title={t('header.title')}
|
|
148
|
+
description={t('header.description')}
|
|
132
149
|
breadcrumbs={[
|
|
133
|
-
{
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
},
|
|
137
|
-
{ label: 'Aprovações' },
|
|
150
|
+
{ label: t('breadcrumbs.home'), href: '/' },
|
|
151
|
+
{ label: t('breadcrumbs.finance'), href: '/finance' },
|
|
152
|
+
{ label: t('breadcrumbs.current') },
|
|
138
153
|
]}
|
|
139
154
|
/>
|
|
140
155
|
|
|
141
156
|
<div className="grid gap-4 md:grid-cols-3">
|
|
142
157
|
<Card>
|
|
143
158
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
144
|
-
<CardTitle className="text-sm font-medium">
|
|
159
|
+
<CardTitle className="text-sm font-medium">
|
|
160
|
+
{t('cards.pending')}
|
|
161
|
+
</CardTitle>
|
|
145
162
|
<Clock className="h-4 w-4 text-muted-foreground" />
|
|
146
163
|
</CardHeader>
|
|
147
164
|
<CardContent>
|
|
@@ -150,7 +167,9 @@ export default function AprovacoesPage() {
|
|
|
150
167
|
</Card>
|
|
151
168
|
<Card>
|
|
152
169
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
153
|
-
<CardTitle className="text-sm font-medium">
|
|
170
|
+
<CardTitle className="text-sm font-medium">
|
|
171
|
+
{t('cards.totalValue')}
|
|
172
|
+
</CardTitle>
|
|
154
173
|
<AlertTriangle className="h-4 w-4 text-muted-foreground" />
|
|
155
174
|
</CardHeader>
|
|
156
175
|
<CardContent>
|
|
@@ -161,7 +180,9 @@ export default function AprovacoesPage() {
|
|
|
161
180
|
</Card>
|
|
162
181
|
<Card>
|
|
163
182
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
164
|
-
<CardTitle className="text-sm font-medium">
|
|
183
|
+
<CardTitle className="text-sm font-medium">
|
|
184
|
+
{t('cards.urgent')}
|
|
185
|
+
</CardTitle>
|
|
165
186
|
<AlertTriangle className="h-4 w-4 text-orange-500" />
|
|
166
187
|
</CardHeader>
|
|
167
188
|
<CardContent>
|
|
@@ -178,22 +199,26 @@ export default function AprovacoesPage() {
|
|
|
178
199
|
|
|
179
200
|
<Card>
|
|
180
201
|
<CardHeader>
|
|
181
|
-
<CardTitle>
|
|
182
|
-
<CardDescription>
|
|
202
|
+
<CardTitle>{t('table.title')}</CardTitle>
|
|
203
|
+
<CardDescription>{t('table.description')}</CardDescription>
|
|
183
204
|
</CardHeader>
|
|
184
205
|
<CardContent>
|
|
185
206
|
{aprovacoes.length > 0 ? (
|
|
186
207
|
<Table>
|
|
187
208
|
<TableHeader>
|
|
188
209
|
<TableRow>
|
|
189
|
-
<TableHead>
|
|
190
|
-
<TableHead>
|
|
191
|
-
<TableHead>
|
|
192
|
-
<TableHead className="text-right">
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
<TableHead>
|
|
196
|
-
<TableHead
|
|
210
|
+
<TableHead>{t('table.headers.document')}</TableHead>
|
|
211
|
+
<TableHead>{t('table.headers.supplier')}</TableHead>
|
|
212
|
+
<TableHead>{t('table.headers.requester')}</TableHead>
|
|
213
|
+
<TableHead className="text-right">
|
|
214
|
+
{t('table.headers.value')}
|
|
215
|
+
</TableHead>
|
|
216
|
+
<TableHead>{t('table.headers.policy')}</TableHead>
|
|
217
|
+
<TableHead>{t('table.headers.urgency')}</TableHead>
|
|
218
|
+
<TableHead>{t('table.headers.date')}</TableHead>
|
|
219
|
+
<TableHead className="text-right">
|
|
220
|
+
{t('table.headers.actions')}
|
|
221
|
+
</TableHead>
|
|
197
222
|
</TableRow>
|
|
198
223
|
</TableHeader>
|
|
199
224
|
<TableBody>
|
|
@@ -236,10 +261,12 @@ export default function AprovacoesPage() {
|
|
|
236
261
|
<div className="flex justify-end gap-2">
|
|
237
262
|
<AprovacaoDialog
|
|
238
263
|
tipo="aprovar"
|
|
264
|
+
t={t}
|
|
239
265
|
onConfirm={() => handleAprovacao(aprovacao.id)}
|
|
240
266
|
/>
|
|
241
267
|
<AprovacaoDialog
|
|
242
268
|
tipo="reprovar"
|
|
269
|
+
t={t}
|
|
243
270
|
onConfirm={() => handleAprovacao(aprovacao.id)}
|
|
244
271
|
/>
|
|
245
272
|
</div>
|
|
@@ -252,14 +279,12 @@ export default function AprovacoesPage() {
|
|
|
252
279
|
) : (
|
|
253
280
|
<div className="flex flex-col items-center justify-center py-12 text-center">
|
|
254
281
|
<CheckCircle className="h-12 w-12 text-green-500" />
|
|
255
|
-
<h3 className="mt-4 text-lg font-semibold">
|
|
256
|
-
<p className="text-muted-foreground">
|
|
257
|
-
Não há aprovações pendentes.
|
|
258
|
-
</p>
|
|
282
|
+
<h3 className="mt-4 text-lg font-semibold">{t('empty.title')}</h3>
|
|
283
|
+
<p className="text-muted-foreground">{t('empty.description')}</p>
|
|
259
284
|
</div>
|
|
260
285
|
)}
|
|
261
286
|
</CardContent>
|
|
262
287
|
</Card>
|
|
263
|
-
</
|
|
288
|
+
</Page>
|
|
264
289
|
);
|
|
265
290
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { Page, PageHeader } from '@/components/entity-list';
|
|
3
4
|
import { AuditTimeline } from '@/components/ui/audit-timeline';
|
|
4
5
|
import { Badge } from '@/components/ui/badge';
|
|
5
6
|
import { Button } from '@/components/ui/button';
|
|
@@ -18,7 +19,6 @@ import {
|
|
|
18
19
|
DropdownMenuTrigger,
|
|
19
20
|
} from '@/components/ui/dropdown-menu';
|
|
20
21
|
import { Money } from '@/components/ui/money';
|
|
21
|
-
import { PageHeader } from '@/components/ui/page-header';
|
|
22
22
|
import { StatusBadge } from '@/components/ui/status-badge';
|
|
23
23
|
import {
|
|
24
24
|
Table,
|
|
@@ -39,12 +39,14 @@ import {
|
|
|
39
39
|
Undo,
|
|
40
40
|
XCircle,
|
|
41
41
|
} from 'lucide-react';
|
|
42
|
+
import { useTranslations } from 'next-intl';
|
|
42
43
|
import Link from 'next/link';
|
|
43
44
|
import { useParams } from 'next/navigation';
|
|
44
45
|
import { formatarData } from '../../../_lib/formatters';
|
|
45
46
|
import { useFinanceData } from '../../../_lib/use-finance-data';
|
|
46
47
|
|
|
47
48
|
export default function TituloDetalhePage() {
|
|
49
|
+
const t = useTranslations('finance.PayableInstallmentDetailPage');
|
|
48
50
|
const params = useParams<{ id: string }>();
|
|
49
51
|
const id = params?.id;
|
|
50
52
|
const { data } = useFinanceData();
|
|
@@ -64,11 +66,17 @@ export default function TituloDetalhePage() {
|
|
|
64
66
|
return (
|
|
65
67
|
<div className="space-y-6">
|
|
66
68
|
<PageHeader
|
|
67
|
-
title=
|
|
68
|
-
description=
|
|
69
|
+
title={t('notFound.title')}
|
|
70
|
+
description={t('notFound.description')}
|
|
69
71
|
breadcrumbs={[
|
|
70
|
-
{
|
|
71
|
-
|
|
72
|
+
{
|
|
73
|
+
label: t('notFound.breadcrumbPayables'),
|
|
74
|
+
href: '/finance/accounts-payable/installments',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
label: t('notFound.breadcrumbInstallments'),
|
|
78
|
+
href: '/finance/accounts-payable/installments',
|
|
79
|
+
},
|
|
72
80
|
]}
|
|
73
81
|
/>
|
|
74
82
|
</div>
|
|
@@ -106,7 +114,7 @@ export default function TituloDetalhePage() {
|
|
|
106
114
|
}));
|
|
107
115
|
|
|
108
116
|
return (
|
|
109
|
-
<
|
|
117
|
+
<Page>
|
|
110
118
|
<div className="flex items-center gap-4">
|
|
111
119
|
<Button variant="ghost" size="icon" asChild>
|
|
112
120
|
<Link href="/finance/accounts-payable/installments">
|
|
@@ -117,8 +125,12 @@ export default function TituloDetalhePage() {
|
|
|
117
125
|
title={titulo.documento}
|
|
118
126
|
description={titulo.descricao}
|
|
119
127
|
breadcrumbs={[
|
|
120
|
-
{ label: '
|
|
121
|
-
{ label: '
|
|
128
|
+
{ label: t('breadcrumbs.home'), href: '/' },
|
|
129
|
+
{ label: t('breadcrumbs.finance'), href: '/finance' },
|
|
130
|
+
{
|
|
131
|
+
label: t('breadcrumbs.payables'),
|
|
132
|
+
href: '/finance/accounts-payable/installments',
|
|
133
|
+
},
|
|
122
134
|
{ label: titulo.documento },
|
|
123
135
|
]}
|
|
124
136
|
actions={
|
|
@@ -128,30 +140,30 @@ export default function TituloDetalhePage() {
|
|
|
128
140
|
<DropdownMenuTrigger asChild>
|
|
129
141
|
<Button variant="outline">
|
|
130
142
|
<MoreHorizontal className="mr-2 h-4 w-4" />
|
|
131
|
-
|
|
143
|
+
{t('actions.title')}
|
|
132
144
|
</Button>
|
|
133
145
|
</DropdownMenuTrigger>
|
|
134
146
|
<DropdownMenuContent align="end">
|
|
135
147
|
<DropdownMenuItem>
|
|
136
148
|
<Edit className="mr-2 h-4 w-4" />
|
|
137
|
-
|
|
149
|
+
{t('actions.edit')}
|
|
138
150
|
</DropdownMenuItem>
|
|
139
151
|
<DropdownMenuItem>
|
|
140
152
|
<CheckCircle className="mr-2 h-4 w-4" />
|
|
141
|
-
|
|
153
|
+
{t('actions.approve')}
|
|
142
154
|
</DropdownMenuItem>
|
|
143
155
|
<DropdownMenuItem>
|
|
144
156
|
<Download className="mr-2 h-4 w-4" />
|
|
145
|
-
|
|
157
|
+
{t('actions.settle')}
|
|
146
158
|
</DropdownMenuItem>
|
|
147
159
|
<DropdownMenuItem>
|
|
148
160
|
<Undo className="mr-2 h-4 w-4" />
|
|
149
|
-
|
|
161
|
+
{t('actions.reverse')}
|
|
150
162
|
</DropdownMenuItem>
|
|
151
163
|
<DropdownMenuSeparator />
|
|
152
164
|
<DropdownMenuItem className="text-destructive">
|
|
153
165
|
<XCircle className="mr-2 h-4 w-4" />
|
|
154
|
-
|
|
166
|
+
{t('actions.cancel')}
|
|
155
167
|
</DropdownMenuItem>
|
|
156
168
|
</DropdownMenuContent>
|
|
157
169
|
</DropdownMenu>
|
|
@@ -163,13 +175,13 @@ export default function TituloDetalhePage() {
|
|
|
163
175
|
<div className="grid gap-6 lg:grid-cols-3">
|
|
164
176
|
<Card className="lg:col-span-2">
|
|
165
177
|
<CardHeader>
|
|
166
|
-
<CardTitle>
|
|
178
|
+
<CardTitle>{t('documentData.title')}</CardTitle>
|
|
167
179
|
</CardHeader>
|
|
168
180
|
<CardContent>
|
|
169
181
|
<dl className="grid gap-4 sm:grid-cols-2">
|
|
170
182
|
<div>
|
|
171
183
|
<dt className="text-sm font-medium text-muted-foreground">
|
|
172
|
-
|
|
184
|
+
{t('documentData.supplier')}
|
|
173
185
|
</dt>
|
|
174
186
|
<dd className="mt-1">
|
|
175
187
|
<Link
|
|
@@ -182,19 +194,19 @@ export default function TituloDetalhePage() {
|
|
|
182
194
|
</div>
|
|
183
195
|
<div>
|
|
184
196
|
<dt className="text-sm font-medium text-muted-foreground">
|
|
185
|
-
|
|
197
|
+
{t('documentData.cnpjCpf')}
|
|
186
198
|
</dt>
|
|
187
199
|
<dd className="mt-1">{fornecedor?.documento}</dd>
|
|
188
200
|
</div>
|
|
189
201
|
<div>
|
|
190
202
|
<dt className="text-sm font-medium text-muted-foreground">
|
|
191
|
-
|
|
203
|
+
{t('documentData.competency')}
|
|
192
204
|
</dt>
|
|
193
205
|
<dd className="mt-1">{titulo.competencia}</dd>
|
|
194
206
|
</div>
|
|
195
207
|
<div>
|
|
196
208
|
<dt className="text-sm font-medium text-muted-foreground">
|
|
197
|
-
|
|
209
|
+
{t('documentData.totalValue')}
|
|
198
210
|
</dt>
|
|
199
211
|
<dd className="mt-1 text-lg font-semibold">
|
|
200
212
|
<Money value={titulo.valorTotal} />
|
|
@@ -202,25 +214,25 @@ export default function TituloDetalhePage() {
|
|
|
202
214
|
</div>
|
|
203
215
|
<div>
|
|
204
216
|
<dt className="text-sm font-medium text-muted-foreground">
|
|
205
|
-
|
|
217
|
+
{t('documentData.category')}
|
|
206
218
|
</dt>
|
|
207
219
|
<dd className="mt-1">{categoria?.nome}</dd>
|
|
208
220
|
</div>
|
|
209
221
|
<div>
|
|
210
222
|
<dt className="text-sm font-medium text-muted-foreground">
|
|
211
|
-
|
|
223
|
+
{t('documentData.costCenter')}
|
|
212
224
|
</dt>
|
|
213
225
|
<dd className="mt-1">{centroCusto?.nome}</dd>
|
|
214
226
|
</div>
|
|
215
227
|
<div>
|
|
216
228
|
<dt className="text-sm font-medium text-muted-foreground">
|
|
217
|
-
|
|
229
|
+
{t('documentData.createdAt')}
|
|
218
230
|
</dt>
|
|
219
231
|
<dd className="mt-1">{formatarData(titulo.criadoEm)}</dd>
|
|
220
232
|
</div>
|
|
221
233
|
<div>
|
|
222
234
|
<dt className="text-sm font-medium text-muted-foreground">
|
|
223
|
-
|
|
235
|
+
{t('documentData.tags')}
|
|
224
236
|
</dt>
|
|
225
237
|
<dd className="mt-1 flex gap-1">
|
|
226
238
|
{tituloTags.length > 0 ? (
|
|
@@ -244,8 +256,8 @@ export default function TituloDetalhePage() {
|
|
|
244
256
|
|
|
245
257
|
<Card>
|
|
246
258
|
<CardHeader>
|
|
247
|
-
<CardTitle>
|
|
248
|
-
<CardDescription>
|
|
259
|
+
<CardTitle>{t('attachments.title')}</CardTitle>
|
|
260
|
+
<CardDescription>{t('attachments.description')}</CardDescription>
|
|
249
261
|
</CardHeader>
|
|
250
262
|
<CardContent>
|
|
251
263
|
{titulo.anexos.length > 0 ? (
|
|
@@ -263,7 +275,9 @@ export default function TituloDetalhePage() {
|
|
|
263
275
|
))}
|
|
264
276
|
</ul>
|
|
265
277
|
) : (
|
|
266
|
-
<p className="text-sm text-muted-foreground">
|
|
278
|
+
<p className="text-sm text-muted-foreground">
|
|
279
|
+
{t('attachments.none')}
|
|
280
|
+
</p>
|
|
267
281
|
)}
|
|
268
282
|
</CardContent>
|
|
269
283
|
</Card>
|
|
@@ -271,9 +285,9 @@ export default function TituloDetalhePage() {
|
|
|
271
285
|
|
|
272
286
|
<Tabs defaultValue="parcelas">
|
|
273
287
|
<TabsList>
|
|
274
|
-
<TabsTrigger value="parcelas">
|
|
275
|
-
<TabsTrigger value="liquidacoes">
|
|
276
|
-
<TabsTrigger value="auditoria">
|
|
288
|
+
<TabsTrigger value="parcelas">{t('tabs.installments')}</TabsTrigger>
|
|
289
|
+
<TabsTrigger value="liquidacoes">{t('tabs.settlements')}</TabsTrigger>
|
|
290
|
+
<TabsTrigger value="auditoria">{t('tabs.audit')}</TabsTrigger>
|
|
277
291
|
</TabsList>
|
|
278
292
|
|
|
279
293
|
<TabsContent value="parcelas" className="mt-4">
|
|
@@ -282,11 +296,13 @@ export default function TituloDetalhePage() {
|
|
|
282
296
|
<Table>
|
|
283
297
|
<TableHeader>
|
|
284
298
|
<TableRow>
|
|
285
|
-
<TableHead>
|
|
286
|
-
<TableHead>
|
|
287
|
-
<TableHead className="text-right">
|
|
288
|
-
|
|
289
|
-
|
|
299
|
+
<TableHead>{t('installmentsTable.installment')}</TableHead>
|
|
300
|
+
<TableHead>{t('installmentsTable.dueDate')}</TableHead>
|
|
301
|
+
<TableHead className="text-right">
|
|
302
|
+
{t('installmentsTable.value')}
|
|
303
|
+
</TableHead>
|
|
304
|
+
<TableHead>{t('installmentsTable.method')}</TableHead>
|
|
305
|
+
<TableHead>{t('installmentsTable.status')}</TableHead>
|
|
290
306
|
</TableRow>
|
|
291
307
|
</TableHeader>
|
|
292
308
|
<TableBody>
|
|
@@ -320,13 +336,21 @@ export default function TituloDetalhePage() {
|
|
|
320
336
|
<Table>
|
|
321
337
|
<TableHeader>
|
|
322
338
|
<TableRow>
|
|
323
|
-
<TableHead>
|
|
324
|
-
<TableHead className="text-right">
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
<TableHead className="text-right">
|
|
328
|
-
|
|
329
|
-
|
|
339
|
+
<TableHead>{t('settlementsTable.date')}</TableHead>
|
|
340
|
+
<TableHead className="text-right">
|
|
341
|
+
{t('settlementsTable.value')}
|
|
342
|
+
</TableHead>
|
|
343
|
+
<TableHead className="text-right">
|
|
344
|
+
{t('settlementsTable.interest')}
|
|
345
|
+
</TableHead>
|
|
346
|
+
<TableHead className="text-right">
|
|
347
|
+
{t('settlementsTable.discount')}
|
|
348
|
+
</TableHead>
|
|
349
|
+
<TableHead className="text-right">
|
|
350
|
+
{t('settlementsTable.fine')}
|
|
351
|
+
</TableHead>
|
|
352
|
+
<TableHead>{t('settlementsTable.account')}</TableHead>
|
|
353
|
+
<TableHead>{t('settlementsTable.method')}</TableHead>
|
|
330
354
|
</TableRow>
|
|
331
355
|
</TableHeader>
|
|
332
356
|
<TableBody>
|
|
@@ -360,7 +384,7 @@ export default function TituloDetalhePage() {
|
|
|
360
384
|
</Table>
|
|
361
385
|
) : (
|
|
362
386
|
<p className="text-center text-muted-foreground py-8">
|
|
363
|
-
|
|
387
|
+
{t('settlementsTable.none')}
|
|
364
388
|
</p>
|
|
365
389
|
)}
|
|
366
390
|
</CardContent>
|
|
@@ -374,15 +398,13 @@ export default function TituloDetalhePage() {
|
|
|
374
398
|
<AuditTimeline events={auditEvents} />
|
|
375
399
|
) : (
|
|
376
400
|
<p className="text-center text-muted-foreground py-8">
|
|
377
|
-
|
|
401
|
+
{t('audit.none')}
|
|
378
402
|
</p>
|
|
379
403
|
)}
|
|
380
404
|
</CardContent>
|
|
381
405
|
</Card>
|
|
382
406
|
</TabsContent>
|
|
383
407
|
</Tabs>
|
|
384
|
-
</
|
|
408
|
+
</Page>
|
|
385
409
|
);
|
|
386
410
|
}
|
|
387
|
-
|
|
388
|
-
|