@hed-hog/finance 0.0.225 → 0.0.227
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-bank-account.dto.d.ts +9 -0
- package/dist/dto/create-bank-account.dto.d.ts.map +1 -0
- package/dist/dto/create-bank-account.dto.js +61 -0
- package/dist/dto/create-bank-account.dto.js.map +1 -0
- package/dist/dto/update-bank-account.dto.d.ts +9 -0
- package/dist/dto/update-bank-account.dto.d.ts.map +1 -0
- package/dist/dto/update-bank-account.dto.js +60 -0
- package/dist/dto/update-bank-account.dto.js.map +1 -0
- package/dist/finance-bank-accounts.controller.d.ts +47 -0
- package/dist/finance-bank-accounts.controller.d.ts.map +1 -0
- package/dist/finance-bank-accounts.controller.js +73 -0
- package/dist/finance-bank-accounts.controller.js.map +1 -0
- package/dist/finance-data.controller.d.ts +136 -0
- package/dist/finance-data.controller.d.ts.map +1 -0
- package/dist/finance-data.controller.js +36 -0
- package/dist/finance-data.controller.js.map +1 -0
- package/dist/finance-installments.controller.d.ts +149 -0
- package/dist/finance-installments.controller.d.ts.map +1 -0
- package/dist/finance-installments.controller.js +101 -0
- package/dist/finance-installments.controller.js.map +1 -0
- package/dist/finance.module.d.ts.map +1 -1
- package/dist/finance.module.js +8 -2
- package/dist/finance.module.js.map +1 -1
- package/dist/finance.service.d.ts +53 -5
- package/dist/finance.service.d.ts.map +1 -1
- package/dist/finance.service.js +167 -9
- package/dist/finance.service.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/hedhog/data/menu.yaml +5 -1
- package/hedhog/data/route.yaml +36 -0
- package/hedhog/frontend/app/accounts-payable/approvals/page.tsx.ejs +4 -1
- package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +307 -112
- package/hedhog/frontend/app/accounts-receivable/collections-default/page.tsx.ejs +25 -8
- package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +301 -100
- package/hedhog/frontend/app/cash-and-banks/bank-accounts/page.tsx.ejs +378 -71
- package/hedhog/frontend/app/cash-and-banks/bank-reconciliation/page.tsx.ejs +6 -3
- package/hedhog/frontend/app/cash-and-banks/statements/page.tsx.ejs +4 -2
- package/hedhog/frontend/app/cash-and-banks/transfers/page.tsx.ejs +6 -7
- package/package.json +6 -6
- package/src/dto/create-bank-account.dto.ts +49 -0
- package/src/dto/update-bank-account.dto.ts +45 -0
- package/src/finance-bank-accounts.controller.ts +43 -0
- package/src/finance-data.controller.ts +14 -0
- package/src/{finance.controller.ts → finance-installments.controller.ts} +8 -13
- package/src/finance.module.ts +8 -2
- package/src/finance.service.ts +202 -9
- package/src/index.ts +3 -1
|
@@ -10,8 +10,16 @@ import {
|
|
|
10
10
|
CardHeader,
|
|
11
11
|
CardTitle,
|
|
12
12
|
} from '@/components/ui/card';
|
|
13
|
+
import {
|
|
14
|
+
Form,
|
|
15
|
+
FormControl,
|
|
16
|
+
FormField,
|
|
17
|
+
FormItem,
|
|
18
|
+
FormLabel,
|
|
19
|
+
FormMessage,
|
|
20
|
+
} from '@/components/ui/form';
|
|
13
21
|
import { Input } from '@/components/ui/input';
|
|
14
|
-
import {
|
|
22
|
+
import { InputMoney } from '@/components/ui/input-money';
|
|
15
23
|
import { Money } from '@/components/ui/money';
|
|
16
24
|
import {
|
|
17
25
|
Select,
|
|
@@ -26,97 +34,321 @@ import {
|
|
|
26
34
|
SheetDescription,
|
|
27
35
|
SheetHeader,
|
|
28
36
|
SheetTitle,
|
|
29
|
-
SheetTrigger,
|
|
30
37
|
} from '@/components/ui/sheet';
|
|
38
|
+
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
39
|
+
import { zodResolver } from '@hookform/resolvers/zod';
|
|
31
40
|
import {
|
|
32
41
|
Building2,
|
|
33
42
|
Eye,
|
|
34
43
|
Landmark,
|
|
44
|
+
Pencil,
|
|
35
45
|
PiggyBank,
|
|
36
46
|
Plus,
|
|
37
47
|
RefreshCw,
|
|
48
|
+
Trash2,
|
|
38
49
|
TrendingUp,
|
|
39
50
|
Upload,
|
|
40
51
|
Wallet,
|
|
41
52
|
} from 'lucide-react';
|
|
42
53
|
import { useTranslations } from 'next-intl';
|
|
43
54
|
import Link from 'next/link';
|
|
44
|
-
import {
|
|
55
|
+
import { useEffect, useState } from 'react';
|
|
56
|
+
import { useForm } from 'react-hook-form';
|
|
57
|
+
import { z } from 'zod';
|
|
58
|
+
|
|
59
|
+
const bankAccountFormSchema = z.object({
|
|
60
|
+
banco: z.string().trim().min(1, 'Banco é obrigatório'),
|
|
61
|
+
agencia: z.string().optional(),
|
|
62
|
+
conta: z.string().optional(),
|
|
63
|
+
tipo: z.string().min(1, 'Tipo é obrigatório'),
|
|
64
|
+
descricao: z.string().optional(),
|
|
65
|
+
saldoInicial: z.number().min(0, 'Saldo inicial inválido'),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
type BankAccountFormValues = z.infer<typeof bankAccountFormSchema>;
|
|
69
|
+
|
|
70
|
+
type BankAccount = {
|
|
71
|
+
id: string;
|
|
72
|
+
codigo: string;
|
|
73
|
+
descricao: string;
|
|
74
|
+
banco: string;
|
|
75
|
+
agencia: string;
|
|
76
|
+
conta: string;
|
|
77
|
+
tipo: 'corrente' | 'poupanca' | 'investimento' | 'caixa';
|
|
78
|
+
saldoAtual: number;
|
|
79
|
+
saldoConciliado: number;
|
|
80
|
+
ativo: boolean;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
function NovaContaSheet({
|
|
84
|
+
t,
|
|
85
|
+
onCreated,
|
|
86
|
+
open,
|
|
87
|
+
onOpenChange,
|
|
88
|
+
editingAccount,
|
|
89
|
+
onEditingAccountChange,
|
|
90
|
+
}: {
|
|
91
|
+
t: ReturnType<typeof useTranslations>;
|
|
92
|
+
onCreated: () => Promise<any> | void;
|
|
93
|
+
open: boolean;
|
|
94
|
+
onOpenChange: (open: boolean) => void;
|
|
95
|
+
editingAccount: BankAccount | null;
|
|
96
|
+
onEditingAccountChange: (account: BankAccount | null) => void;
|
|
97
|
+
}) {
|
|
98
|
+
const { request, showToastHandler } = useApp();
|
|
99
|
+
|
|
100
|
+
const form = useForm<BankAccountFormValues>({
|
|
101
|
+
resolver: zodResolver(bankAccountFormSchema),
|
|
102
|
+
defaultValues: {
|
|
103
|
+
banco: '',
|
|
104
|
+
agencia: '',
|
|
105
|
+
conta: '',
|
|
106
|
+
tipo: '',
|
|
107
|
+
descricao: '',
|
|
108
|
+
saldoInicial: 0,
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (!open) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (editingAccount) {
|
|
118
|
+
form.reset({
|
|
119
|
+
banco: editingAccount.banco,
|
|
120
|
+
agencia: editingAccount.agencia === '-' ? '' : editingAccount.agencia,
|
|
121
|
+
conta: editingAccount.conta === '-' ? '' : editingAccount.conta,
|
|
122
|
+
tipo: editingAccount.tipo,
|
|
123
|
+
descricao: editingAccount.descricao,
|
|
124
|
+
saldoInicial: editingAccount.saldoAtual,
|
|
125
|
+
});
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
form.reset({
|
|
130
|
+
banco: '',
|
|
131
|
+
agencia: '',
|
|
132
|
+
conta: '',
|
|
133
|
+
tipo: '',
|
|
134
|
+
descricao: '',
|
|
135
|
+
saldoInicial: 0,
|
|
136
|
+
});
|
|
137
|
+
}, [editingAccount, form, open]);
|
|
138
|
+
|
|
139
|
+
const handleSubmit = async (values: BankAccountFormValues) => {
|
|
140
|
+
try {
|
|
141
|
+
if (editingAccount) {
|
|
142
|
+
await request({
|
|
143
|
+
url: `/finance/bank-accounts/${editingAccount.id}`,
|
|
144
|
+
method: 'PATCH',
|
|
145
|
+
data: {
|
|
146
|
+
bank: values.banco,
|
|
147
|
+
branch: values.agencia || undefined,
|
|
148
|
+
account: values.conta || undefined,
|
|
149
|
+
type: values.tipo,
|
|
150
|
+
description: values.descricao?.trim() || undefined,
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
} else {
|
|
154
|
+
await request({
|
|
155
|
+
url: '/finance/bank-accounts',
|
|
156
|
+
method: 'POST',
|
|
157
|
+
data: {
|
|
158
|
+
bank: values.banco,
|
|
159
|
+
branch: values.agencia || undefined,
|
|
160
|
+
account: values.conta || undefined,
|
|
161
|
+
type: values.tipo,
|
|
162
|
+
description: values.descricao?.trim() || undefined,
|
|
163
|
+
initial_balance: values.saldoInicial,
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
await onCreated();
|
|
169
|
+
form.reset();
|
|
170
|
+
onOpenChange(false);
|
|
171
|
+
onEditingAccountChange(null);
|
|
172
|
+
showToastHandler?.(
|
|
173
|
+
'success',
|
|
174
|
+
editingAccount
|
|
175
|
+
? 'Conta bancária atualizada com sucesso'
|
|
176
|
+
: 'Conta bancária cadastrada com sucesso'
|
|
177
|
+
);
|
|
178
|
+
} catch {
|
|
179
|
+
showToastHandler?.(
|
|
180
|
+
'error',
|
|
181
|
+
editingAccount
|
|
182
|
+
? 'Erro ao atualizar conta bancária'
|
|
183
|
+
: 'Erro ao cadastrar conta bancária'
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const handleCancel = () => {
|
|
189
|
+
form.reset();
|
|
190
|
+
onEditingAccountChange(null);
|
|
191
|
+
onOpenChange(false);
|
|
192
|
+
};
|
|
45
193
|
|
|
46
|
-
function NovaContaSheet({ t }: { t: ReturnType<typeof useTranslations> }) {
|
|
47
194
|
return (
|
|
48
|
-
<Sheet
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
195
|
+
<Sheet
|
|
196
|
+
open={open}
|
|
197
|
+
onOpenChange={(nextOpen) => {
|
|
198
|
+
onOpenChange(nextOpen);
|
|
199
|
+
if (!nextOpen) {
|
|
200
|
+
onEditingAccountChange(null);
|
|
201
|
+
}
|
|
202
|
+
}}
|
|
203
|
+
>
|
|
55
204
|
<SheetContent className="w-full sm:max-w-lg">
|
|
56
205
|
<SheetHeader>
|
|
57
|
-
<SheetTitle>
|
|
206
|
+
<SheetTitle>
|
|
207
|
+
{editingAccount ? t('common.edit') : t('newAccount.title')}
|
|
208
|
+
</SheetTitle>
|
|
58
209
|
<SheetDescription>{t('newAccount.description')}</SheetDescription>
|
|
59
210
|
</SheetHeader>
|
|
60
|
-
<form
|
|
61
|
-
<
|
|
62
|
-
<div className="
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
211
|
+
<Form {...form}>
|
|
212
|
+
<form className="p-4" onSubmit={form.handleSubmit(handleSubmit)}>
|
|
213
|
+
<div className="grid gap-4">
|
|
214
|
+
<FormField
|
|
215
|
+
control={form.control}
|
|
216
|
+
name="banco"
|
|
217
|
+
render={({ field }) => (
|
|
218
|
+
<FormItem>
|
|
219
|
+
<FormLabel>{t('fields.bank')}</FormLabel>
|
|
220
|
+
<FormControl>
|
|
221
|
+
<Input
|
|
222
|
+
placeholder={t('fields.bankPlaceholder')}
|
|
223
|
+
{...field}
|
|
224
|
+
/>
|
|
225
|
+
</FormControl>
|
|
226
|
+
<FormMessage />
|
|
227
|
+
</FormItem>
|
|
228
|
+
)}
|
|
229
|
+
/>
|
|
230
|
+
|
|
231
|
+
<div className="grid grid-cols-2 gap-4">
|
|
232
|
+
<FormField
|
|
233
|
+
control={form.control}
|
|
234
|
+
name="agencia"
|
|
235
|
+
render={({ field }) => (
|
|
236
|
+
<FormItem>
|
|
237
|
+
<FormLabel>{t('fields.branch')}</FormLabel>
|
|
238
|
+
<FormControl>
|
|
239
|
+
<Input
|
|
240
|
+
placeholder="0000"
|
|
241
|
+
{...field}
|
|
242
|
+
value={field.value || ''}
|
|
243
|
+
/>
|
|
244
|
+
</FormControl>
|
|
245
|
+
<FormMessage />
|
|
246
|
+
</FormItem>
|
|
247
|
+
)}
|
|
248
|
+
/>
|
|
249
|
+
|
|
250
|
+
<FormField
|
|
251
|
+
control={form.control}
|
|
252
|
+
name="conta"
|
|
253
|
+
render={({ field }) => (
|
|
254
|
+
<FormItem>
|
|
255
|
+
<FormLabel>{t('fields.account')}</FormLabel>
|
|
256
|
+
<FormControl>
|
|
257
|
+
<Input
|
|
258
|
+
placeholder="00000-0"
|
|
259
|
+
{...field}
|
|
260
|
+
value={field.value || ''}
|
|
261
|
+
/>
|
|
262
|
+
</FormControl>
|
|
263
|
+
<FormMessage />
|
|
264
|
+
</FormItem>
|
|
265
|
+
)}
|
|
266
|
+
/>
|
|
74
267
|
</div>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
268
|
+
|
|
269
|
+
<FormField
|
|
270
|
+
control={form.control}
|
|
271
|
+
name="tipo"
|
|
272
|
+
render={({ field }) => (
|
|
273
|
+
<FormItem>
|
|
274
|
+
<FormLabel>{t('fields.type')}</FormLabel>
|
|
275
|
+
<Select value={field.value} onValueChange={field.onChange}>
|
|
276
|
+
<FormControl>
|
|
277
|
+
<SelectTrigger>
|
|
278
|
+
<SelectValue placeholder={t('common.select')} />
|
|
279
|
+
</SelectTrigger>
|
|
280
|
+
</FormControl>
|
|
281
|
+
<SelectContent>
|
|
282
|
+
<SelectItem value="corrente">
|
|
283
|
+
{t('types.corrente')}
|
|
284
|
+
</SelectItem>
|
|
285
|
+
<SelectItem value="poupanca">
|
|
286
|
+
{t('types.poupanca')}
|
|
287
|
+
</SelectItem>
|
|
288
|
+
<SelectItem value="investimento">
|
|
289
|
+
{t('types.investimento')}
|
|
290
|
+
</SelectItem>
|
|
291
|
+
<SelectItem value="caixa">
|
|
292
|
+
{t('types.caixa')}
|
|
293
|
+
</SelectItem>
|
|
294
|
+
</SelectContent>
|
|
295
|
+
</Select>
|
|
296
|
+
<FormMessage />
|
|
297
|
+
</FormItem>
|
|
298
|
+
)}
|
|
101
299
|
/>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
300
|
+
|
|
301
|
+
<FormField
|
|
302
|
+
control={form.control}
|
|
303
|
+
name="descricao"
|
|
304
|
+
render={({ field }) => (
|
|
305
|
+
<FormItem>
|
|
306
|
+
<FormLabel>{t('fields.description')}</FormLabel>
|
|
307
|
+
<FormControl>
|
|
308
|
+
<Input
|
|
309
|
+
placeholder={t('fields.descriptionPlaceholder')}
|
|
310
|
+
{...field}
|
|
311
|
+
value={field.value || ''}
|
|
312
|
+
/>
|
|
313
|
+
</FormControl>
|
|
314
|
+
<FormMessage />
|
|
315
|
+
</FormItem>
|
|
316
|
+
)}
|
|
110
317
|
/>
|
|
318
|
+
|
|
319
|
+
<FormField
|
|
320
|
+
control={form.control}
|
|
321
|
+
name="saldoInicial"
|
|
322
|
+
render={({ field }) => (
|
|
323
|
+
<FormItem>
|
|
324
|
+
<FormLabel>{t('fields.initialBalance')}</FormLabel>
|
|
325
|
+
<FormControl>
|
|
326
|
+
<InputMoney
|
|
327
|
+
ref={field.ref}
|
|
328
|
+
name={field.name}
|
|
329
|
+
value={field.value}
|
|
330
|
+
onBlur={field.onBlur}
|
|
331
|
+
onValueChange={(value) => field.onChange(value ?? 0)}
|
|
332
|
+
placeholder="0,00"
|
|
333
|
+
disabled={!!editingAccount}
|
|
334
|
+
/>
|
|
335
|
+
</FormControl>
|
|
336
|
+
<FormMessage />
|
|
337
|
+
</FormItem>
|
|
338
|
+
)}
|
|
339
|
+
/>
|
|
340
|
+
</div>
|
|
341
|
+
|
|
342
|
+
<div className="flex justify-end gap-2 pt-4">
|
|
343
|
+
<Button type="button" variant="outline" onClick={handleCancel}>
|
|
344
|
+
{t('common.cancel')}
|
|
345
|
+
</Button>
|
|
346
|
+
<Button type="submit" disabled={form.formState.isSubmitting}>
|
|
347
|
+
{t('common.save')}
|
|
348
|
+
</Button>
|
|
111
349
|
</div>
|
|
112
|
-
</
|
|
113
|
-
|
|
114
|
-
<Button type="button" variant="outline">
|
|
115
|
-
{t('common.cancel')}
|
|
116
|
-
</Button>
|
|
117
|
-
<Button type="submit">{t('common.save')}</Button>
|
|
118
|
-
</div>
|
|
119
|
-
</form>
|
|
350
|
+
</form>
|
|
351
|
+
</Form>
|
|
120
352
|
</SheetContent>
|
|
121
353
|
</Sheet>
|
|
122
354
|
);
|
|
@@ -124,8 +356,23 @@ function NovaContaSheet({ t }: { t: ReturnType<typeof useTranslations> }) {
|
|
|
124
356
|
|
|
125
357
|
export default function ContasBancariasPage() {
|
|
126
358
|
const t = useTranslations('finance.BankAccountsPage');
|
|
127
|
-
const {
|
|
128
|
-
const
|
|
359
|
+
const { request, showToastHandler } = useApp();
|
|
360
|
+
const [sheetOpen, setSheetOpen] = useState(false);
|
|
361
|
+
const [editingAccount, setEditingAccount] = useState<BankAccount | null>(
|
|
362
|
+
null
|
|
363
|
+
);
|
|
364
|
+
const { data: contasBancarias, refetch } = useQuery<BankAccount[]>({
|
|
365
|
+
queryKey: ['finance-bank-accounts'],
|
|
366
|
+
queryFn: async () => {
|
|
367
|
+
const response = await request({
|
|
368
|
+
url: '/finance/bank-accounts',
|
|
369
|
+
method: 'GET',
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
return (response.data || []) as BankAccount[];
|
|
373
|
+
},
|
|
374
|
+
initialData: [],
|
|
375
|
+
});
|
|
129
376
|
|
|
130
377
|
const tipoConfig = {
|
|
131
378
|
corrente: { label: t('types.corrente'), icon: Building2 },
|
|
@@ -142,6 +389,38 @@ export default function ContasBancariasPage() {
|
|
|
142
389
|
.filter((c) => c.ativo)
|
|
143
390
|
.reduce((acc, c) => acc + c.saldoConciliado, 0);
|
|
144
391
|
|
|
392
|
+
const handleCreate = () => {
|
|
393
|
+
setEditingAccount(null);
|
|
394
|
+
setSheetOpen(true);
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
const handleEdit = (account: BankAccount) => {
|
|
398
|
+
setEditingAccount(account);
|
|
399
|
+
setSheetOpen(true);
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
const handleDelete = async (accountId: string) => {
|
|
403
|
+
const confirmed = window.confirm(
|
|
404
|
+
'Deseja realmente inativar esta conta bancária?'
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
if (!confirmed) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
try {
|
|
412
|
+
await request({
|
|
413
|
+
url: `/finance/bank-accounts/${accountId}`,
|
|
414
|
+
method: 'DELETE',
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
await refetch();
|
|
418
|
+
showToastHandler?.('success', 'Conta bancária inativada com sucesso');
|
|
419
|
+
} catch {
|
|
420
|
+
showToastHandler?.('error', 'Erro ao inativar conta bancária');
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
|
|
145
424
|
return (
|
|
146
425
|
<Page>
|
|
147
426
|
<PageHeader
|
|
@@ -152,7 +431,21 @@ export default function ContasBancariasPage() {
|
|
|
152
431
|
{ label: t('breadcrumbs.finance'), href: '/finance' },
|
|
153
432
|
{ label: t('breadcrumbs.current') },
|
|
154
433
|
]}
|
|
155
|
-
actions={
|
|
434
|
+
actions={
|
|
435
|
+
<Button onClick={handleCreate}>
|
|
436
|
+
<Plus className="mr-2 h-4 w-4" />
|
|
437
|
+
{t('newAccount.action')}
|
|
438
|
+
</Button>
|
|
439
|
+
}
|
|
440
|
+
/>
|
|
441
|
+
|
|
442
|
+
<NovaContaSheet
|
|
443
|
+
t={t}
|
|
444
|
+
onCreated={refetch}
|
|
445
|
+
open={sheetOpen}
|
|
446
|
+
onOpenChange={setSheetOpen}
|
|
447
|
+
editingAccount={editingAccount}
|
|
448
|
+
onEditingAccountChange={setEditingAccount}
|
|
156
449
|
/>
|
|
157
450
|
|
|
158
451
|
<div className="grid gap-4 md:grid-cols-2">
|
|
@@ -284,6 +577,20 @@ export default function ContasBancariasPage() {
|
|
|
284
577
|
<Button variant="outline" size="sm">
|
|
285
578
|
<Upload className="h-4 w-4" />
|
|
286
579
|
</Button>
|
|
580
|
+
<Button
|
|
581
|
+
variant="outline"
|
|
582
|
+
size="sm"
|
|
583
|
+
onClick={() => handleEdit(conta)}
|
|
584
|
+
>
|
|
585
|
+
<Pencil className="h-4 w-4" />
|
|
586
|
+
</Button>
|
|
587
|
+
<Button
|
|
588
|
+
variant="outline"
|
|
589
|
+
size="sm"
|
|
590
|
+
onClick={() => handleDelete(conta.id)}
|
|
591
|
+
>
|
|
592
|
+
<Trash2 className="h-4 w-4" />
|
|
593
|
+
</Button>
|
|
287
594
|
</div>
|
|
288
595
|
</div>
|
|
289
596
|
</CardContent>
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
DialogTrigger,
|
|
22
22
|
} from '@/components/ui/dialog';
|
|
23
23
|
import { Input } from '@/components/ui/input';
|
|
24
|
+
import { InputMoney } from '@/components/ui/input-money';
|
|
24
25
|
import { Label } from '@/components/ui/label';
|
|
25
26
|
import { Money } from '@/components/ui/money';
|
|
26
27
|
import { Progress } from '@/components/ui/progress';
|
|
@@ -77,7 +78,7 @@ function CriarAjusteDialog({ t }: { t: ReturnType<typeof useTranslations> }) {
|
|
|
77
78
|
</div>
|
|
78
79
|
<div className="space-y-2">
|
|
79
80
|
<Label htmlFor="valor">{t('adjustment.value')}</Label>
|
|
80
|
-
<
|
|
81
|
+
<InputMoney id="valor" placeholder="0,00" />
|
|
81
82
|
</div>
|
|
82
83
|
<div className="space-y-2">
|
|
83
84
|
<Label htmlFor="descricao">{t('adjustment.details')}</Label>
|
|
@@ -88,8 +89,10 @@ function CriarAjusteDialog({ t }: { t: ReturnType<typeof useTranslations> }) {
|
|
|
88
89
|
</div>
|
|
89
90
|
</div>
|
|
90
91
|
<DialogFooter>
|
|
91
|
-
<Button variant="outline">
|
|
92
|
-
|
|
92
|
+
<Button type="button" variant="outline">
|
|
93
|
+
{t('common.cancel')}
|
|
94
|
+
</Button>
|
|
95
|
+
<Button type="button">{t('adjustment.submit')}</Button>
|
|
93
96
|
</DialogFooter>
|
|
94
97
|
</DialogContent>
|
|
95
98
|
</Dialog>
|
|
@@ -89,8 +89,10 @@ function ImportarExtratoDialog({
|
|
|
89
89
|
</div>
|
|
90
90
|
</div>
|
|
91
91
|
<DialogFooter>
|
|
92
|
-
<Button variant="outline">
|
|
93
|
-
|
|
92
|
+
<Button type="button" variant="outline">
|
|
93
|
+
{t('common.cancel')}
|
|
94
|
+
</Button>
|
|
95
|
+
<Button type="button">{t('importDialog.submit')}</Button>
|
|
94
96
|
</DialogFooter>
|
|
95
97
|
</DialogContent>
|
|
96
98
|
</Dialog>
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
CardTitle,
|
|
11
11
|
} from '@/components/ui/card';
|
|
12
12
|
import { Input } from '@/components/ui/input';
|
|
13
|
+
import { InputMoney } from '@/components/ui/input-money';
|
|
13
14
|
import { Label } from '@/components/ui/label';
|
|
14
15
|
import { Money } from '@/components/ui/money';
|
|
15
16
|
import {
|
|
@@ -61,7 +62,10 @@ function NovaTransferenciaSheet({
|
|
|
61
62
|
<SheetTitle>{t('newTransfer.title')}</SheetTitle>
|
|
62
63
|
<SheetDescription>{t('newTransfer.description')}</SheetDescription>
|
|
63
64
|
</SheetHeader>
|
|
64
|
-
<form
|
|
65
|
+
<form
|
|
66
|
+
className="mt-6 space-y-4"
|
|
67
|
+
onSubmit={(event) => event.preventDefault()}
|
|
68
|
+
>
|
|
65
69
|
<div className="grid gap-4">
|
|
66
70
|
<div className="space-y-2">
|
|
67
71
|
<Label htmlFor="contaOrigem">{t('fields.sourceAccount')}</Label>
|
|
@@ -102,12 +106,7 @@ function NovaTransferenciaSheet({
|
|
|
102
106
|
</div>
|
|
103
107
|
<div className="space-y-2">
|
|
104
108
|
<Label htmlFor="valor">{t('fields.value')}</Label>
|
|
105
|
-
<
|
|
106
|
-
id="valor"
|
|
107
|
-
type="number"
|
|
108
|
-
placeholder="0,00"
|
|
109
|
-
step="0.01"
|
|
110
|
-
/>
|
|
109
|
+
<InputMoney id="valor" placeholder="0,00" />
|
|
111
110
|
</div>
|
|
112
111
|
</div>
|
|
113
112
|
<div className="space-y-2">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hed-hog/finance",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.227",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
"@nestjs/core": "^11",
|
|
10
10
|
"@nestjs/jwt": "^11",
|
|
11
11
|
"@nestjs/mapped-types": "*",
|
|
12
|
-
"@hed-hog/api-locale": "0.0.11",
|
|
13
|
-
"@hed-hog/api-pagination": "0.0.5",
|
|
14
12
|
"@hed-hog/api-prisma": "0.0.4",
|
|
15
|
-
"@hed-hog/api": "0.0.
|
|
16
|
-
"@hed-hog/
|
|
13
|
+
"@hed-hog/api-pagination": "0.0.5",
|
|
14
|
+
"@hed-hog/api-locale": "0.0.11",
|
|
17
15
|
"@hed-hog/tag": "0.0.223",
|
|
18
|
-
"@hed-hog/api-types": "0.0.1"
|
|
16
|
+
"@hed-hog/api-types": "0.0.1",
|
|
17
|
+
"@hed-hog/api": "0.0.3",
|
|
18
|
+
"@hed-hog/contact": "0.0.223"
|
|
19
19
|
},
|
|
20
20
|
"exports": {
|
|
21
21
|
".": {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { getLocaleText } from '@hed-hog/api-locale';
|
|
2
|
+
import { IsNumber, IsOptional, IsString, Min } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
export class CreateBankAccountDto {
|
|
5
|
+
@IsString({
|
|
6
|
+
message: (args) => getLocaleText('validation.bankMustBeString', args.value),
|
|
7
|
+
})
|
|
8
|
+
bank: string;
|
|
9
|
+
|
|
10
|
+
@IsOptional()
|
|
11
|
+
@IsString({
|
|
12
|
+
message: (args) =>
|
|
13
|
+
getLocaleText('validation.branchMustBeString', args.value),
|
|
14
|
+
})
|
|
15
|
+
branch?: string;
|
|
16
|
+
|
|
17
|
+
@IsOptional()
|
|
18
|
+
@IsString({
|
|
19
|
+
message: (args) =>
|
|
20
|
+
getLocaleText('validation.accountMustBeString', args.value),
|
|
21
|
+
})
|
|
22
|
+
account?: string;
|
|
23
|
+
|
|
24
|
+
@IsString({
|
|
25
|
+
message: (args) =>
|
|
26
|
+
getLocaleText('validation.accountTypeMustBeString', args.value),
|
|
27
|
+
})
|
|
28
|
+
type: string;
|
|
29
|
+
|
|
30
|
+
@IsOptional()
|
|
31
|
+
@IsString({
|
|
32
|
+
message: (args) =>
|
|
33
|
+
getLocaleText('validation.descriptionMustBeString', args.value),
|
|
34
|
+
})
|
|
35
|
+
description?: string;
|
|
36
|
+
|
|
37
|
+
@IsOptional()
|
|
38
|
+
@IsNumber(
|
|
39
|
+
{},
|
|
40
|
+
{
|
|
41
|
+
message: (args) =>
|
|
42
|
+
getLocaleText('validation.initialBalanceMustBeNumber', args.value),
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
@Min(0, {
|
|
46
|
+
message: (args) => getLocaleText('validation.initialBalanceMin', args.value),
|
|
47
|
+
})
|
|
48
|
+
initial_balance?: number;
|
|
49
|
+
}
|