@hed-hog/finance 0.0.233 → 0.0.236

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.
Files changed (76) hide show
  1. package/dist/dto/create-cost-center.dto.d.ts +4 -0
  2. package/dist/dto/create-cost-center.dto.d.ts.map +1 -0
  3. package/dist/dto/create-cost-center.dto.js +24 -0
  4. package/dist/dto/create-cost-center.dto.js.map +1 -0
  5. package/dist/dto/create-finance-category.dto.d.ts +6 -0
  6. package/dist/dto/create-finance-category.dto.d.ts.map +1 -0
  7. package/dist/dto/create-finance-category.dto.js +37 -0
  8. package/dist/dto/create-finance-category.dto.js.map +1 -0
  9. package/dist/dto/create-period-close.dto.d.ts +7 -0
  10. package/dist/dto/create-period-close.dto.d.ts.map +1 -0
  11. package/dist/dto/create-period-close.dto.js +44 -0
  12. package/dist/dto/create-period-close.dto.js.map +1 -0
  13. package/dist/dto/move-finance-category.dto.d.ts +5 -0
  14. package/dist/dto/move-finance-category.dto.d.ts.map +1 -0
  15. package/dist/dto/move-finance-category.dto.js +32 -0
  16. package/dist/dto/move-finance-category.dto.js.map +1 -0
  17. package/dist/dto/update-cost-center.dto.d.ts +5 -0
  18. package/dist/dto/update-cost-center.dto.d.ts.map +1 -0
  19. package/dist/dto/update-cost-center.dto.js +32 -0
  20. package/dist/dto/update-cost-center.dto.js.map +1 -0
  21. package/dist/dto/update-finance-category.dto.d.ts +7 -0
  22. package/dist/dto/update-finance-category.dto.d.ts.map +1 -0
  23. package/dist/dto/update-finance-category.dto.js +46 -0
  24. package/dist/dto/update-finance-category.dto.js.map +1 -0
  25. package/dist/finance-audit-logs.controller.d.ts +13 -0
  26. package/dist/finance-audit-logs.controller.d.ts.map +1 -0
  27. package/dist/finance-audit-logs.controller.js +54 -0
  28. package/dist/finance-audit-logs.controller.js.map +1 -0
  29. package/dist/finance-categories.controller.d.ts +42 -0
  30. package/dist/finance-categories.controller.d.ts.map +1 -0
  31. package/dist/finance-categories.controller.js +84 -0
  32. package/dist/finance-categories.controller.js.map +1 -0
  33. package/dist/finance-cost-centers.controller.d.ts +32 -0
  34. package/dist/finance-cost-centers.controller.d.ts.map +1 -0
  35. package/dist/finance-cost-centers.controller.js +72 -0
  36. package/dist/finance-cost-centers.controller.js.map +1 -0
  37. package/dist/finance-installments.controller.d.ts +4 -0
  38. package/dist/finance-installments.controller.d.ts.map +1 -1
  39. package/dist/finance-period-close.controller.d.ts +27 -0
  40. package/dist/finance-period-close.controller.d.ts.map +1 -0
  41. package/dist/finance-period-close.controller.js +64 -0
  42. package/dist/finance-period-close.controller.js.map +1 -0
  43. package/dist/finance.module.d.ts.map +1 -1
  44. package/dist/finance.module.js +8 -0
  45. package/dist/finance.module.js.map +1 -1
  46. package/dist/finance.service.d.ts +119 -0
  47. package/dist/finance.service.d.ts.map +1 -1
  48. package/dist/finance.service.js +733 -36
  49. package/dist/finance.service.js.map +1 -1
  50. package/dist/index.d.ts +4 -0
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +4 -0
  53. package/dist/index.js.map +1 -1
  54. package/hedhog/data/route.yaml +108 -0
  55. package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +76 -6
  56. package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +76 -6
  57. package/hedhog/frontend/app/administration/audit-logs/page.tsx.ejs +309 -0
  58. package/hedhog/frontend/app/administration/categories/page.tsx.ejs +642 -0
  59. package/hedhog/frontend/app/administration/cost-centers/page.tsx.ejs +371 -0
  60. package/hedhog/frontend/app/administration/period-close/page.tsx.ejs +502 -0
  61. package/hedhog/frontend/messages/en.json +225 -0
  62. package/hedhog/frontend/messages/pt.json +225 -0
  63. package/package.json +5 -5
  64. package/src/dto/create-cost-center.dto.ts +9 -0
  65. package/src/dto/create-finance-category.dto.ts +21 -0
  66. package/src/dto/create-period-close.dto.ts +34 -0
  67. package/src/dto/move-finance-category.dto.ts +18 -0
  68. package/src/dto/update-cost-center.dto.ts +17 -0
  69. package/src/dto/update-finance-category.dto.ts +30 -0
  70. package/src/finance-audit-logs.controller.ts +30 -0
  71. package/src/finance-categories.controller.ts +52 -0
  72. package/src/finance-cost-centers.controller.ts +43 -0
  73. package/src/finance-period-close.controller.ts +34 -0
  74. package/src/finance.module.ts +8 -0
  75. package/src/finance.service.ts +1020 -29
  76. package/src/index.ts +4 -0
@@ -0,0 +1,371 @@
1
+ 'use client';
2
+
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
+ } from '@/components/ui/alert-dialog';
14
+ import { Badge } from '@/components/ui/badge';
15
+ import { Button } from '@/components/ui/button';
16
+ import {
17
+ Card,
18
+ CardContent,
19
+ CardDescription,
20
+ CardHeader,
21
+ CardTitle,
22
+ } from '@/components/ui/card';
23
+ import {
24
+ Form,
25
+ FormControl,
26
+ FormField,
27
+ FormItem,
28
+ FormLabel,
29
+ FormMessage,
30
+ } from '@/components/ui/form';
31
+ import { Input } from '@/components/ui/input';
32
+ import {
33
+ Sheet,
34
+ SheetContent,
35
+ SheetDescription,
36
+ SheetHeader,
37
+ SheetTitle,
38
+ } from '@/components/ui/sheet';
39
+ import { useApp, useQuery } from '@hed-hog/next-app-provider';
40
+ import { zodResolver } from '@hookform/resolvers/zod';
41
+ import { Building2, Pencil, Plus, Trash2 } from 'lucide-react';
42
+ import { useTranslations } from 'next-intl';
43
+ import { useState } from 'react';
44
+ import { useForm } from 'react-hook-form';
45
+ import { z } from 'zod';
46
+
47
+ type CostCenterFormValues = {
48
+ nome: string;
49
+ };
50
+
51
+ type CostCenter = {
52
+ id: string;
53
+ codigo: string;
54
+ nome: string;
55
+ status: 'active' | 'inactive';
56
+ ativo: boolean;
57
+ };
58
+
59
+ function CentroCustoSheet({
60
+ open,
61
+ onOpenChange,
62
+ onSaved,
63
+ editingCostCenter,
64
+ onEditingChange,
65
+ t,
66
+ }: {
67
+ open: boolean;
68
+ onOpenChange: (open: boolean) => void;
69
+ onSaved: () => Promise<any> | void;
70
+ editingCostCenter: CostCenter | null;
71
+ onEditingChange: (costCenter: CostCenter | null) => void;
72
+ t: ReturnType<typeof useTranslations>;
73
+ }) {
74
+ const { request, showToastHandler } = useApp();
75
+
76
+ const costCenterFormSchema = z.object({
77
+ nome: z.string().trim().min(1, t('sheet.validation.nameRequired')),
78
+ });
79
+
80
+ const form = useForm<CostCenterFormValues>({
81
+ resolver: zodResolver(costCenterFormSchema),
82
+ defaultValues: {
83
+ nome: '',
84
+ },
85
+ });
86
+
87
+ const handleSubmit = async (values: CostCenterFormValues) => {
88
+ try {
89
+ if (editingCostCenter) {
90
+ await request({
91
+ url: `/finance/cost-centers/${editingCostCenter.id}`,
92
+ method: 'PATCH',
93
+ data: {
94
+ name: values.nome,
95
+ },
96
+ });
97
+ } else {
98
+ await request({
99
+ url: '/finance/cost-centers',
100
+ method: 'POST',
101
+ data: {
102
+ name: values.nome,
103
+ },
104
+ });
105
+ }
106
+
107
+ await onSaved();
108
+ form.reset({ nome: '' });
109
+ onEditingChange(null);
110
+ onOpenChange(false);
111
+ showToastHandler?.(
112
+ 'success',
113
+ editingCostCenter
114
+ ? t('messages.updateSuccess')
115
+ : t('messages.createSuccess')
116
+ );
117
+ } catch {
118
+ showToastHandler?.(
119
+ 'error',
120
+ editingCostCenter
121
+ ? t('messages.updateError')
122
+ : t('messages.createError')
123
+ );
124
+ }
125
+ };
126
+
127
+ const handleOpenChange = (nextOpen: boolean) => {
128
+ onOpenChange(nextOpen);
129
+
130
+ if (!nextOpen) {
131
+ form.reset({ nome: '' });
132
+ onEditingChange(null);
133
+ return;
134
+ }
135
+
136
+ if (editingCostCenter) {
137
+ form.reset({
138
+ nome: editingCostCenter.nome,
139
+ });
140
+ }
141
+ };
142
+
143
+ return (
144
+ <Sheet open={open} onOpenChange={handleOpenChange}>
145
+ <SheetContent className="w-full sm:max-w-lg">
146
+ <SheetHeader>
147
+ <SheetTitle>
148
+ {editingCostCenter ? t('sheet.editTitle') : t('sheet.newTitle')}
149
+ </SheetTitle>
150
+ <SheetDescription>
151
+ {editingCostCenter
152
+ ? t('sheet.editDescription')
153
+ : t('sheet.newDescription')}
154
+ </SheetDescription>
155
+ </SheetHeader>
156
+
157
+ <Form {...form}>
158
+ <form
159
+ className="space-y-4 p-4"
160
+ onSubmit={form.handleSubmit(handleSubmit)}
161
+ >
162
+ <FormField
163
+ control={form.control}
164
+ name="nome"
165
+ render={({ field }) => (
166
+ <FormItem>
167
+ <FormLabel>{t('sheet.fields.name')}</FormLabel>
168
+ <FormControl>
169
+ <Input
170
+ placeholder={t('sheet.fields.namePlaceholder')}
171
+ {...field}
172
+ />
173
+ </FormControl>
174
+ <FormMessage />
175
+ </FormItem>
176
+ )}
177
+ />
178
+
179
+ <div className="flex justify-end gap-2">
180
+ <Button
181
+ type="button"
182
+ variant="outline"
183
+ onClick={() => handleOpenChange(false)}
184
+ >
185
+ {t('common.cancel')}
186
+ </Button>
187
+ <Button type="submit" disabled={form.formState.isSubmitting}>
188
+ {t('common.save')}
189
+ </Button>
190
+ </div>
191
+ </form>
192
+ </Form>
193
+ </SheetContent>
194
+ </Sheet>
195
+ );
196
+ }
197
+
198
+ export default function CostCentersPage() {
199
+ const t = useTranslations('finance.AdminCostCentersPage');
200
+ const { request, showToastHandler } = useApp();
201
+
202
+ const [sheetOpen, setSheetOpen] = useState(false);
203
+ const [editingCostCenter, setEditingCostCenter] = useState<CostCenter | null>(
204
+ null
205
+ );
206
+ const [costCenterIdToDelete, setCostCenterIdToDelete] = useState<
207
+ string | null
208
+ >(null);
209
+
210
+ const { data: costCenters, refetch } = useQuery<CostCenter[]>({
211
+ queryKey: ['finance-cost-centers'],
212
+ queryFn: async () => {
213
+ const response = await request({
214
+ url: '/finance/cost-centers',
215
+ method: 'GET',
216
+ });
217
+
218
+ return (response.data || []) as CostCenter[];
219
+ },
220
+ placeholderData: [],
221
+ });
222
+
223
+ const handleDelete = async () => {
224
+ if (!costCenterIdToDelete) {
225
+ return;
226
+ }
227
+
228
+ try {
229
+ await request({
230
+ url: `/finance/cost-centers/${costCenterIdToDelete}`,
231
+ method: 'DELETE',
232
+ });
233
+
234
+ await refetch();
235
+ setCostCenterIdToDelete(null);
236
+ showToastHandler?.('success', t('messages.deleteSuccess'));
237
+ } catch {
238
+ showToastHandler?.('error', t('messages.deleteError'));
239
+ }
240
+ };
241
+
242
+ const centers = costCenters || [];
243
+
244
+ return (
245
+ <Page>
246
+ <PageHeader
247
+ title={t('header.title')}
248
+ description={t('header.description')}
249
+ breadcrumbs={[
250
+ { label: t('breadcrumbs.finance'), href: '/finance' },
251
+ {
252
+ label: t('breadcrumbs.administration'),
253
+ href: '/finance/administration',
254
+ },
255
+ { label: t('breadcrumbs.current') },
256
+ ]}
257
+ />
258
+
259
+ <div className="grid gap-4">
260
+ <Card>
261
+ <CardHeader className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
262
+ <div>
263
+ <CardTitle>{t('card.title')}</CardTitle>
264
+ <CardDescription>{t('card.description')}</CardDescription>
265
+ </div>
266
+ <Button
267
+ onClick={() => {
268
+ setEditingCostCenter(null);
269
+ setSheetOpen(true);
270
+ }}
271
+ className="gap-2"
272
+ >
273
+ <Plus className="h-4 w-4" />
274
+ {t('actions.newCostCenter')}
275
+ </Button>
276
+ </CardHeader>
277
+
278
+ <CardContent>
279
+ {centers.length === 0 ? (
280
+ <div className="rounded-md border border-dashed p-8 text-center text-sm text-muted-foreground">
281
+ {t('table.empty')}
282
+ </div>
283
+ ) : (
284
+ <div className="grid gap-3">
285
+ {centers.map((costCenter) => (
286
+ <div
287
+ key={costCenter.id}
288
+ className="flex flex-col gap-3 rounded-md border p-4 sm:flex-row sm:items-center sm:justify-between"
289
+ >
290
+ <div className="flex items-start gap-3">
291
+ <div className="rounded-md bg-muted p-2">
292
+ <Building2 className="h-4 w-4" />
293
+ </div>
294
+ <div>
295
+ <p className="text-sm font-medium">{costCenter.nome}</p>
296
+ <p className="text-xs text-muted-foreground">
297
+ {t('table.code', { code: costCenter.codigo })}
298
+ </p>
299
+ </div>
300
+ </div>
301
+
302
+ <div className="flex items-center gap-2">
303
+ <Badge
304
+ variant={costCenter.ativo ? 'default' : 'secondary'}
305
+ >
306
+ {costCenter.ativo
307
+ ? t('table.status.active')
308
+ : t('table.status.inactive')}
309
+ </Badge>
310
+ <Button
311
+ variant="outline"
312
+ size="icon"
313
+ onClick={() => {
314
+ setEditingCostCenter(costCenter);
315
+ setSheetOpen(true);
316
+ }}
317
+ >
318
+ <Pencil className="h-4 w-4" />
319
+ </Button>
320
+ <Button
321
+ variant="outline"
322
+ size="icon"
323
+ onClick={() => setCostCenterIdToDelete(costCenter.id)}
324
+ disabled={!costCenter.ativo}
325
+ >
326
+ <Trash2 className="h-4 w-4" />
327
+ </Button>
328
+ </div>
329
+ </div>
330
+ ))}
331
+ </div>
332
+ )}
333
+ </CardContent>
334
+ </Card>
335
+ </div>
336
+
337
+ <CentroCustoSheet
338
+ open={sheetOpen}
339
+ onOpenChange={setSheetOpen}
340
+ onSaved={refetch}
341
+ editingCostCenter={editingCostCenter}
342
+ onEditingChange={setEditingCostCenter}
343
+ t={t}
344
+ />
345
+
346
+ <AlertDialog
347
+ open={!!costCenterIdToDelete}
348
+ onOpenChange={(open) => {
349
+ if (!open) {
350
+ setCostCenterIdToDelete(null);
351
+ }
352
+ }}
353
+ >
354
+ <AlertDialogContent>
355
+ <AlertDialogHeader>
356
+ <AlertDialogTitle>{t('deleteDialog.title')}</AlertDialogTitle>
357
+ <AlertDialogDescription>
358
+ {t('deleteDialog.description')}
359
+ </AlertDialogDescription>
360
+ </AlertDialogHeader>
361
+ <AlertDialogFooter>
362
+ <AlertDialogCancel>{t('common.cancel')}</AlertDialogCancel>
363
+ <AlertDialogAction onClick={handleDelete}>
364
+ {t('deleteDialog.confirm')}
365
+ </AlertDialogAction>
366
+ </AlertDialogFooter>
367
+ </AlertDialogContent>
368
+ </AlertDialog>
369
+ </Page>
370
+ );
371
+ }