@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.
Files changed (32) hide show
  1. package/dist/dto/reverse-settlement.dto.d.ts +1 -0
  2. package/dist/dto/reverse-settlement.dto.d.ts.map +1 -1
  3. package/dist/dto/reverse-settlement.dto.js +5 -0
  4. package/dist/dto/reverse-settlement.dto.js.map +1 -1
  5. package/dist/finance-installments.controller.d.ts +106 -4
  6. package/dist/finance-installments.controller.d.ts.map +1 -1
  7. package/dist/finance-installments.controller.js +38 -2
  8. package/dist/finance-installments.controller.js.map +1 -1
  9. package/dist/finance.service.d.ts +104 -2
  10. package/dist/finance.service.d.ts.map +1 -1
  11. package/dist/finance.service.js +366 -121
  12. package/dist/finance.service.js.map +1 -1
  13. package/hedhog/data/route.yaml +27 -0
  14. package/hedhog/frontend/app/_components/finance-entity-field-with-create.tsx.ejs +572 -0
  15. package/hedhog/frontend/app/_components/finance-title-actions-menu.tsx.ejs +244 -0
  16. package/hedhog/frontend/app/_components/person-field-with-create.tsx.ejs +143 -51
  17. package/hedhog/frontend/app/_lib/title-action-rules.ts.ejs +36 -0
  18. package/hedhog/frontend/app/accounts-payable/installments/[id]/page.tsx.ejs +449 -293
  19. package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +1189 -545
  20. package/hedhog/frontend/app/accounts-receivable/installments/[id]/page.tsx.ejs +176 -133
  21. package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +1459 -312
  22. package/hedhog/frontend/app/page.tsx.ejs +15 -4
  23. package/hedhog/frontend/messages/en.json +294 -5
  24. package/hedhog/frontend/messages/pt.json +294 -5
  25. package/hedhog/query/settlement-auditability.sql +175 -0
  26. package/hedhog/table/bank_reconciliation.yaml +11 -0
  27. package/hedhog/table/settlement.yaml +17 -1
  28. package/hedhog/table/settlement_allocation.yaml +3 -0
  29. package/package.json +7 -7
  30. package/src/dto/reverse-settlement.dto.ts +4 -0
  31. package/src/finance-installments.controller.ts +45 -12
  32. package/src/finance.service.ts +521 -146
@@ -21,6 +21,7 @@ import {
21
21
  Wallet,
22
22
  } from 'lucide-react';
23
23
  import { useLocale, useTranslations } from 'next-intl';
24
+ import Link from 'next/link';
24
25
  import {
25
26
  CartesianGrid,
26
27
  Legend,
@@ -110,6 +111,7 @@ function ProximosVencimentos({
110
111
  .filter((p: any) => p.status === 'aberto' || p.status === 'vencido')
111
112
  .map((p: any) => ({
112
113
  tipo: 'pagar' as const,
114
+ tituloId: t.id,
113
115
  documento: t.documento,
114
116
  pessoa: getPessoaById(t.fornecedorId)?.nome || '',
115
117
  vencimento: p.vencimento,
@@ -125,6 +127,7 @@ function ProximosVencimentos({
125
127
  .filter((p: any) => p.status === 'aberto' || p.status === 'vencido')
126
128
  .map((p: any) => ({
127
129
  tipo: 'receber' as const,
130
+ tituloId: t.id,
128
131
  documento: t.documento,
129
132
  pessoa: getPessoaById(t.clienteId)?.nome || '',
130
133
  vencimento: p.vencimento,
@@ -147,7 +150,11 @@ function ProximosVencimentos({
147
150
  <CardContent>
148
151
  <div className="space-y-4">
149
152
  {vencimentosPagar.map((item, i) => (
150
- <div key={i} className="flex items-center justify-between">
153
+ <Link
154
+ key={i}
155
+ href={`/finance/accounts-payable/installments/${item.tituloId}`}
156
+ className="flex items-center justify-between rounded-md p-2 -m-2 transition-colors hover:bg-muted/50 active:bg-muted"
157
+ >
151
158
  <div className="space-y-1">
152
159
  <p className="text-sm font-medium">{item.documento}</p>
153
160
  <p className="text-xs text-muted-foreground">{item.pessoa}</p>
@@ -161,7 +168,7 @@ function ProximosVencimentos({
161
168
  </p>
162
169
  </div>
163
170
  <StatusBadge status={item.status} />
164
- </div>
171
+ </Link>
165
172
  ))}
166
173
  </div>
167
174
  </CardContent>
@@ -178,7 +185,11 @@ function ProximosVencimentos({
178
185
  <CardContent>
179
186
  <div className="space-y-4">
180
187
  {vencimentosReceber.map((item, i) => (
181
- <div key={i} className="flex items-center justify-between">
188
+ <Link
189
+ key={i}
190
+ href={`/finance/accounts-receivable/installments/${item.tituloId}`}
191
+ className="flex items-center justify-between rounded-md p-2 -m-2 transition-colors hover:bg-muted/50 active:bg-muted"
192
+ >
182
193
  <div className="space-y-1">
183
194
  <p className="text-sm font-medium">{item.documento}</p>
184
195
  <p className="text-xs text-muted-foreground">{item.pessoa}</p>
@@ -192,7 +203,7 @@ function ProximosVencimentos({
192
203
  </p>
193
204
  </div>
194
205
  <StatusBadge status={item.status} />
195
- </div>
206
+ </Link>
196
207
  ))}
197
208
  </div>
198
209
  </CardContent>
@@ -99,11 +99,114 @@
99
99
  "description": "There are no pending approvals."
100
100
  }
101
101
  },
102
+ "PersonFieldWithCreate": {
103
+ "sheet": {
104
+ "title": "New {entityLabel}",
105
+ "description": "Only name and type are required. You can complete the remaining fields now or later."
106
+ },
107
+ "common": {
108
+ "select": "Select"
109
+ },
110
+ "types": {
111
+ "individual": "Individual",
112
+ "company": "Company"
113
+ },
114
+ "fields": {
115
+ "name": "Name",
116
+ "type": "Type",
117
+ "documentIndividualOptional": "CPF (optional)",
118
+ "documentCompanyOptional": "CNPJ (optional)",
119
+ "emailOptional": "Email (optional)",
120
+ "phoneOptional": "Phone (optional)",
121
+ "addressOptional": "Address (optional)"
122
+ },
123
+ "placeholders": {
124
+ "name": "{entityLabel} name",
125
+ "email": "{entityLabel}@company.com",
126
+ "phone": "(11) 99999-9999",
127
+ "addressLine1": "Street, number, complement",
128
+ "city": "City",
129
+ "state": "State"
130
+ },
131
+ "search": {
132
+ "placeholder": "Type to search person...",
133
+ "loading": "Searching people...",
134
+ "noResults": "No person found"
135
+ },
136
+ "actions": {
137
+ "cancel": "Cancel",
138
+ "saveEntity": "Save {entityLabel}",
139
+ "createNew": "Create new record",
140
+ "clearSelection": "Clear selection",
141
+ "createEntityAria": "Create new {entityLabel}"
142
+ },
143
+ "messages": {
144
+ "createdSuccess": "{entityLabel} created successfully",
145
+ "createdError": "Could not create {entityLabel}"
146
+ }
147
+ },
148
+ "FinanceEntityFieldWithCreate": {
149
+ "validation": {
150
+ "nameRequired": "Name is required"
151
+ },
152
+ "fields": {
153
+ "name": "Name"
154
+ },
155
+ "actions": {
156
+ "cancel": "Cancel",
157
+ "save": "Save",
158
+ "createCategoryAria": "Create new category",
159
+ "createCostCenterAria": "Create new cost center"
160
+ },
161
+ "categorySheet": {
162
+ "title": "New category",
163
+ "description": "Register a new category to use in this entry.",
164
+ "namePlaceholder": "Category name"
165
+ },
166
+ "costCenterSheet": {
167
+ "title": "New cost center",
168
+ "description": "Register a new cost center to use in this entry.",
169
+ "namePlaceholder": "Cost center name"
170
+ },
171
+ "messages": {
172
+ "categoryCreateSuccess": "Category created successfully",
173
+ "categoryCreateError": "Could not create category",
174
+ "costCenterCreateSuccess": "Cost center created successfully",
175
+ "costCenterCreateError": "Could not create cost center"
176
+ }
177
+ },
102
178
  "PayableInstallmentsPage": {
103
179
  "common": {
104
180
  "select": "Select...",
105
181
  "cancel": "Cancel",
106
- "save": "Save"
182
+ "save": "Save",
183
+ "upload": {
184
+ "label": "Invoice file (optional)",
185
+ "upload": "Upload",
186
+ "change": "Change file",
187
+ "remove": "Remove",
188
+ "selectedPrefix": "File:",
189
+ "uploadingProgress": "Upload in progress: {progress}%",
190
+ "processingAi": "Processing document with AI",
191
+ "lowConfidence": "Extraction confidence: {confidence}%",
192
+ "fillingWithAi": "Filling with AI...",
193
+ "uploadingFile": "Uploading file..."
194
+ }
195
+ },
196
+ "validation": {
197
+ "documentRequired": "Document is required",
198
+ "supplierRequired": "Supplier is required",
199
+ "dueDateRequired": "Due date is required",
200
+ "amountGreaterThanZero": "Amount must be greater than zero",
201
+ "invalidInstallmentCount": "Invalid installments count",
202
+ "installmentsMin": "Minimum of 1 installment",
203
+ "installmentsMax": "Maximum of 120 installments",
204
+ "installmentDueDateRequired": "Installment due date is required",
205
+ "installmentAmountGreaterThanZero": "Installment amount must be greater than zero",
206
+ "installmentsRequired": "Provide at least one installment",
207
+ "installmentsCountMismatch": "Installments count does not match detailed schedule",
208
+ "installmentsSumMismatch": "Installments sum must match total amount",
209
+ "installmentRequired": "Installment is required"
107
210
  },
108
211
  "newTitle": {
109
212
  "action": "New Title",
@@ -169,9 +272,75 @@
169
272
  "approve": "Approve",
170
273
  "settle": "Settle",
171
274
  "reverse": "Reverse",
172
- "cancel": "Cancel"
275
+ "cancel": "Cancel",
276
+ "openAttachment": "Open attachment"
173
277
  }
174
278
  },
279
+ "dialogs": {
280
+ "cancel": {
281
+ "title": "Confirm cancellation",
282
+ "description": "This action cancels the title and cannot be undone automatically.",
283
+ "cancel": "Back",
284
+ "confirm": "Confirm cancellation"
285
+ },
286
+ "reverse": {
287
+ "title": "Confirm reversal",
288
+ "description": "Provide a reason for the reversal. The system will recalculate balances and status automatically.",
289
+ "reasonLabel": "Reversal reason",
290
+ "reasonPlaceholder": "Ex.: duplicate settlement",
291
+ "cancel": "Back",
292
+ "confirm": "Confirm reversal"
293
+ }
294
+ },
295
+ "settleSheet": {
296
+ "title": "Register settlement",
297
+ "description": "Provide installment and settlement amount for title {document}.",
298
+ "installmentLabel": "Installment",
299
+ "installmentPlaceholder": "Select",
300
+ "installmentOption": "Installment {number} - open amount: {amount}",
301
+ "amountLabel": "Amount",
302
+ "descriptionLabel": "Description (optional)",
303
+ "confirm": "Confirm settlement"
304
+ },
305
+ "installmentsEditor": {
306
+ "title": "Installments",
307
+ "countLabel": "Installments Count",
308
+ "recalculate": "Recalculate automatically",
309
+ "autoRedistributeLabel": "Automatically redistribute remaining amount when editing installment",
310
+ "autoRedistributeHint": "Redistribution occurs after typing stops and on field blur.",
311
+ "dueDateLabel": "Due date",
312
+ "amountLabel": "Amount",
313
+ "totalPrefix": "Installments total: {total}",
314
+ "adjustmentNeeded": "(adjustment needed)"
315
+ },
316
+ "editTitle": {
317
+ "description": "Edit title data while it is in draft status."
318
+ },
319
+ "messages": {
320
+ "createSuccess": "Title created successfully",
321
+ "createError": "Error creating title",
322
+ "invalidFile": "Invalid file",
323
+ "attachSuccess": "Attachment linked successfully",
324
+ "aiExtractSuccess": "Invoice data extracted and auto-filled",
325
+ "aiExtractError": "Could not extract data automatically",
326
+ "uploadError": "Could not upload file",
327
+ "invalidTitleForEdit": "Invalid title for edit",
328
+ "updateSuccess": "Title updated successfully",
329
+ "updateError": "Could not update title",
330
+ "editDraftOnly": "Only draft titles can be edited",
331
+ "cancelSuccess": "Title canceled successfully",
332
+ "cancelError": "Could not cancel title",
333
+ "approveSuccess": "Title approved successfully",
334
+ "approveError": "Could not approve title",
335
+ "noInstallmentForSettle": "No installment available for settlement",
336
+ "settleSuccess": "Settlement registered successfully",
337
+ "settleError": "Could not register settlement",
338
+ "noActiveSettlementToReverse": "No active settlement available to reverse",
339
+ "reverseDefaultReason": "Reversal created from title list",
340
+ "reverseSuccess": "Reversal completed successfully",
341
+ "reverseError": "Could not reverse settlement",
342
+ "openAttachmentError": "Could not open attachment"
343
+ },
175
344
  "footer": {
176
345
  "showing": "Showing {filtered} of {total} records",
177
346
  "previous": "Previous",
@@ -212,6 +381,8 @@
212
381
  "reverse": {
213
382
  "title": "Confirm reversal",
214
383
  "description": "This action reverses the selected settlement, recalculates installment balances, and updates the title status.",
384
+ "reasonLabel": "Reversal reason",
385
+ "reasonPlaceholder": "Ex.: duplicate settlement",
215
386
  "cancel": "Cancel",
216
387
  "confirm": "Confirm reversal"
217
388
  }
@@ -234,7 +405,9 @@
234
405
  "reverseSuccess": "Reversal completed successfully",
235
406
  "reverseError": "Could not reverse the settlement",
236
407
  "cancelSuccess": "Title canceled successfully",
237
- "cancelError": "Could not cancel the title"
408
+ "cancelError": "Could not cancel the title",
409
+ "unreconcileSuccess": "Reconciliation removed successfully",
410
+ "unreconcileError": "Could not remove settlement reconciliation"
238
411
  },
239
412
  "documentData": {
240
413
  "title": "Document Data",
@@ -300,6 +473,32 @@
300
473
  "reverseDialogConfirm": "Confirm reversal",
301
474
  "none": "No settlement recorded"
302
475
  },
476
+ "settlementsHistory": {
477
+ "loading": "Loading settlements history...",
478
+ "allocationsTitle": "Allocations",
479
+ "allocationInstallment": "Installment",
480
+ "headers": {
481
+ "date": "Date",
482
+ "type": "Type",
483
+ "status": "Status",
484
+ "netAmount": "Net Amount",
485
+ "method": "Method",
486
+ "account": "Account",
487
+ "reconciled": "Reconciled",
488
+ "actions": "Actions"
489
+ },
490
+ "normalType": "NORMAL",
491
+ "reversalType": "REVERSAL",
492
+ "reversedStatus": "REVERSED",
493
+ "reconciled": {
494
+ "yes": "Reconciled",
495
+ "no": "Pending"
496
+ },
497
+ "unreconcile": "Unreconcile",
498
+ "unreconcileLoading": "Unreconciling...",
499
+ "unreconcileFirst": "Unreconcile first",
500
+ "reverse": "Reverse"
501
+ },
303
502
  "audit": { "none": "No audit event" }
304
503
  },
305
504
  "CollectionsDefaultPage": {
@@ -376,7 +575,33 @@
376
575
  "common": {
377
576
  "select": "Select...",
378
577
  "cancel": "Cancel",
379
- "save": "Save"
578
+ "save": "Save",
579
+ "upload": {
580
+ "label": "Invoice file (optional)",
581
+ "upload": "Upload",
582
+ "change": "Change file",
583
+ "remove": "Remove",
584
+ "selectedPrefix": "File:",
585
+ "uploadingProgress": "Upload in progress: {progress}%",
586
+ "processingAi": "Processing document with AI",
587
+ "lowConfidence": "Extraction confidence: {confidence}%",
588
+ "fillingWithAi": "Filling with AI...",
589
+ "uploadingFile": "Uploading file..."
590
+ }
591
+ },
592
+ "validation": {
593
+ "documentRequired": "Document is required",
594
+ "clientRequired": "Client is required",
595
+ "dueDateRequired": "Due date is required",
596
+ "amountGreaterThanZero": "Amount must be greater than zero",
597
+ "invalidInstallmentCount": "Invalid installments count",
598
+ "installmentsMin": "Minimum of 1 installment",
599
+ "installmentsMax": "Maximum of 120 installments",
600
+ "installmentDueDateRequired": "Installment due date is required",
601
+ "installmentAmountGreaterThanZero": "Installment amount must be greater than zero",
602
+ "installmentsRequired": "Provide at least one installment",
603
+ "installmentsCountMismatch": "Installments count does not match detailed schedule",
604
+ "installmentsSumMismatch": "Installments sum must match total amount"
380
605
  },
381
606
  "newTitle": {
382
607
  "action": "New Title",
@@ -436,9 +661,37 @@
436
661
  "viewDetails": "View Details",
437
662
  "edit": "Edit",
438
663
  "registerReceipt": "Register Receipt",
439
- "sendCollection": "Send Collection"
664
+ "sendCollection": "Send Collection",
665
+ "openAttachment": "Open attachment"
440
666
  }
441
667
  },
668
+ "installmentsEditor": {
669
+ "title": "Installments",
670
+ "countLabel": "Installments Count",
671
+ "recalculate": "Recalculate automatically",
672
+ "autoRedistributeLabel": "Automatically redistribute remaining amount when editing installment",
673
+ "dueDateLabel": "Due date",
674
+ "amountLabel": "Amount",
675
+ "totalPrefix": "Installments total: {total}",
676
+ "adjustmentNeeded": "(adjustment needed)"
677
+ },
678
+ "editTitle": {
679
+ "description": "Edit title data while it is in draft status."
680
+ },
681
+ "messages": {
682
+ "createSuccess": "Title created successfully",
683
+ "createError": "Error creating title",
684
+ "invalidFile": "Invalid file",
685
+ "attachSuccess": "Attachment linked successfully",
686
+ "aiExtractSuccess": "Invoice data extracted and auto-filled",
687
+ "aiExtractError": "Could not extract data automatically",
688
+ "uploadError": "Could not upload file",
689
+ "invalidTitleForEdit": "Invalid title for edit",
690
+ "updateSuccess": "Title updated successfully",
691
+ "updateError": "Could not update title",
692
+ "editDraftOnly": "Only draft titles can be edited",
693
+ "openAttachmentError": "Could not open attachment"
694
+ },
442
695
  "footer": {
443
696
  "showing": "Showing {filtered} of {total} records",
444
697
  "previous": "Previous",
@@ -465,9 +718,43 @@
465
718
  "actions": {
466
719
  "title": "Actions",
467
720
  "edit": "Edit",
721
+ "approve": "Approve",
468
722
  "registerReceipt": "Register Receipt",
469
723
  "sendCollection": "Send Collection"
470
724
  },
725
+ "common": {
726
+ "cancel": "Cancel"
727
+ },
728
+ "validation": {
729
+ "installmentRequired": "Installment is required",
730
+ "amountGreaterThanZero": "Amount must be greater than zero"
731
+ },
732
+ "settleSheet": {
733
+ "title": "Register receipt",
734
+ "description": "Provide installment and amount for partial or full receipt.",
735
+ "installmentLabel": "Installment",
736
+ "installmentPlaceholder": "Select",
737
+ "installmentOption": "Installment {number} - open amount: {amount}",
738
+ "amountLabel": "Amount",
739
+ "descriptionLabel": "Description (optional)",
740
+ "confirm": "Confirm receipt"
741
+ },
742
+ "reverseSheet": {
743
+ "title": "Confirm reversal",
744
+ "description": "This action reverses the receipt and recalculates balances and status.",
745
+ "reasonLabel": "Reversal reason",
746
+ "reasonPlaceholder": "Ex.: duplicate settlement",
747
+ "confirm": "Confirm reversal"
748
+ },
749
+ "messages": {
750
+ "approveSuccess": "Title approved successfully",
751
+ "approveError": "Could not approve the title",
752
+ "settleSuccess": "Receipt registered successfully",
753
+ "settleError": "Could not register receipt",
754
+ "reverseSuccess": "Reversal completed successfully",
755
+ "reverseError": "Could not reverse receipt",
756
+ "reverseDefaultReason": "Reversal performed from title detail"
757
+ },
471
758
  "documentData": {
472
759
  "title": "Document Data",
473
760
  "client": "Client",
@@ -521,6 +808,8 @@
521
808
  "discount": "Discount",
522
809
  "account": "Account",
523
810
  "method": "Method",
811
+ "actions": "Actions",
812
+ "reverseButton": "Reverse",
524
813
  "none": "No receipt recorded"
525
814
  },
526
815
  "audit": { "none": "No audit event" }