@spaceinvoices/react-ui 0.4.3 → 0.4.5

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 (263) hide show
  1. package/cli/dist/index.js +1 -1
  2. package/package.json +1 -1
  3. package/src/common/autocomplete.tsx +18 -2
  4. package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +61 -12
  5. package/src/components/advance-invoices/create/locales/de.ts +17 -0
  6. package/src/components/advance-invoices/create/locales/es.ts +17 -0
  7. package/src/components/advance-invoices/create/locales/fr.ts +17 -0
  8. package/src/components/advance-invoices/create/locales/hr.ts +16 -0
  9. package/src/components/advance-invoices/create/locales/it.ts +17 -0
  10. package/src/components/advance-invoices/create/locales/nl.ts +17 -0
  11. package/src/components/advance-invoices/create/locales/pl.ts +16 -0
  12. package/src/components/advance-invoices/create/locales/pt.ts +16 -0
  13. package/src/components/advance-invoices/create/locales/sl.ts +16 -0
  14. package/src/components/advance-invoices/create/prepare-advance-invoice-submission.ts +0 -1
  15. package/src/components/advance-invoices/list/list-row-actions.tsx +48 -1
  16. package/src/components/advance-invoices/list/list-table.tsx +100 -50
  17. package/src/components/advance-invoices/list/locales/de.ts +9 -0
  18. package/src/components/advance-invoices/list/locales/en.ts +7 -0
  19. package/src/components/advance-invoices/list/locales/es.ts +9 -0
  20. package/src/components/advance-invoices/list/locales/fr.ts +9 -0
  21. package/src/components/advance-invoices/list/locales/hr.ts +8 -0
  22. package/src/components/advance-invoices/list/locales/it.ts +9 -0
  23. package/src/components/advance-invoices/list/locales/nl.ts +9 -0
  24. package/src/components/advance-invoices/list/locales/pl.ts +8 -0
  25. package/src/components/advance-invoices/list/locales/pt.ts +9 -0
  26. package/src/components/advance-invoices/list/locales/sl.ts +8 -0
  27. package/src/components/credit-notes/create/create-credit-note-form.tsx +185 -11
  28. package/src/components/credit-notes/create/locales/de.ts +18 -0
  29. package/src/components/credit-notes/create/locales/es.ts +18 -0
  30. package/src/components/credit-notes/create/locales/fr.ts +18 -0
  31. package/src/components/credit-notes/create/locales/hr.ts +17 -0
  32. package/src/components/credit-notes/create/locales/it.ts +18 -0
  33. package/src/components/credit-notes/create/locales/nl.ts +18 -0
  34. package/src/components/credit-notes/create/locales/pl.ts +17 -0
  35. package/src/components/credit-notes/create/locales/pt.ts +17 -0
  36. package/src/components/credit-notes/create/locales/sl.ts +18 -1
  37. package/src/components/credit-notes/credit-notes.hooks.ts +30 -0
  38. package/src/components/credit-notes/list/list-row-actions.tsx +44 -1
  39. package/src/components/credit-notes/list/list-table.tsx +93 -32
  40. package/src/components/credit-notes/list/locales/de.ts +7 -0
  41. package/src/components/credit-notes/list/locales/en.ts +6 -0
  42. package/src/components/credit-notes/list/locales/es.ts +7 -0
  43. package/src/components/credit-notes/list/locales/fr.ts +7 -0
  44. package/src/components/credit-notes/list/locales/hr.ts +7 -0
  45. package/src/components/credit-notes/list/locales/it.ts +7 -0
  46. package/src/components/credit-notes/list/locales/nl.ts +7 -0
  47. package/src/components/credit-notes/list/locales/pl.ts +7 -0
  48. package/src/components/credit-notes/list/locales/pt.ts +7 -0
  49. package/src/components/credit-notes/list/locales/sl.ts +7 -0
  50. package/src/components/customers/customer-list-table/customer-list-table.tsx +0 -3
  51. package/src/components/customers/customer-list-table/locales/de.ts +1 -0
  52. package/src/components/customers/customer-list-table/locales/es.ts +1 -0
  53. package/src/components/customers/customer-list-table/locales/fr.ts +1 -0
  54. package/src/components/customers/customer-list-table/locales/hr.ts +1 -0
  55. package/src/components/customers/customer-list-table/locales/it.ts +1 -0
  56. package/src/components/customers/customer-list-table/locales/nl.ts +1 -0
  57. package/src/components/customers/customer-list-table/locales/pl.ts +1 -0
  58. package/src/components/customers/customer-list-table/locales/pt.ts +1 -0
  59. package/src/components/customers/customer-list-table/locales/sl.ts +1 -0
  60. package/src/components/dashboard/collection-rate-card/use-collection-rate.ts +48 -9
  61. package/src/components/dashboard/revenue-trend-chart/use-revenue-trend.ts +77 -48
  62. package/src/components/dashboard/shared/use-revenue-data.ts +77 -9
  63. package/src/components/delivery-notes/create/create-delivery-note-form.tsx +67 -7
  64. package/src/components/delivery-notes/create/locales/de.ts +16 -0
  65. package/src/components/delivery-notes/create/locales/es.ts +16 -0
  66. package/src/components/delivery-notes/create/locales/fr.ts +16 -0
  67. package/src/components/delivery-notes/create/locales/hr.ts +16 -0
  68. package/src/components/delivery-notes/create/locales/it.ts +16 -0
  69. package/src/components/delivery-notes/create/locales/nl.ts +16 -0
  70. package/src/components/delivery-notes/create/locales/pl.ts +16 -0
  71. package/src/components/delivery-notes/create/locales/pt.ts +16 -0
  72. package/src/components/delivery-notes/create/locales/sl.ts +17 -1
  73. package/src/components/delivery-notes/list/list-row-actions.tsx +20 -1
  74. package/src/components/delivery-notes/list/list-table.tsx +50 -8
  75. package/src/components/delivery-notes/list/locales/de.ts +35 -0
  76. package/src/components/delivery-notes/list/locales/en.ts +33 -0
  77. package/src/components/delivery-notes/list/locales/es.ts +35 -0
  78. package/src/components/delivery-notes/list/locales/fr.ts +35 -0
  79. package/src/components/delivery-notes/list/locales/hr.ts +35 -0
  80. package/src/components/delivery-notes/list/locales/it.ts +35 -0
  81. package/src/components/delivery-notes/list/locales/nl.ts +35 -0
  82. package/src/components/delivery-notes/list/locales/pl.ts +35 -0
  83. package/src/components/delivery-notes/list/locales/pt.ts +35 -0
  84. package/src/components/delivery-notes/list/locales/sl.ts +35 -0
  85. package/src/components/documents/create/document-add-item-form.tsx +70 -0
  86. package/src/components/documents/create/document-details-section.tsx +163 -29
  87. package/src/components/documents/create/document-items-section.tsx +21 -4
  88. package/src/components/documents/create/linked-documents-info.tsx +82 -0
  89. package/src/components/documents/create/live-preview.tsx +25 -5
  90. package/src/components/documents/create/mark-as-paid-section.tsx +29 -20
  91. package/src/components/documents/create/prepare-document-submission.ts +19 -7
  92. package/src/components/documents/shared/document-preview-display.tsx +3 -4
  93. package/src/components/documents/types.ts +2 -2
  94. package/src/components/documents/view/document-actions-bar.tsx +7 -27
  95. package/src/components/documents/view/document-activities-list.tsx +65 -47
  96. package/src/components/documents/view/document-details-card.tsx +118 -76
  97. package/src/components/documents/view/document-payments-list.tsx +99 -65
  98. package/src/components/documents/view/document-relations-list.tsx +43 -28
  99. package/src/components/documents/view/document-sidebar.tsx +151 -0
  100. package/src/components/documents/view/index.ts +2 -0
  101. package/src/components/documents/view/locales/de.ts +4 -0
  102. package/src/components/documents/view/locales/es.ts +4 -0
  103. package/src/components/documents/view/locales/fr.ts +4 -0
  104. package/src/components/documents/view/locales/hr.ts +4 -0
  105. package/src/components/documents/view/locales/it.ts +4 -0
  106. package/src/components/documents/view/locales/nl.ts +4 -0
  107. package/src/components/documents/view/locales/pl.ts +4 -0
  108. package/src/components/documents/view/locales/pt.ts +4 -0
  109. package/src/components/documents/view/locales/sl.ts +5 -1
  110. package/src/components/documents/view/use-document-download.ts +7 -3
  111. package/src/components/entities/create-entity-form.tsx +166 -13
  112. package/src/components/entities/entity-settings-form/entity-settings-form.tsx +101 -1
  113. package/src/components/entities/entity-settings-form/input-with-preview.tsx +30 -2
  114. package/src/components/entities/entity-settings-form/locales/de.ts +10 -0
  115. package/src/components/entities/entity-settings-form/locales/es.ts +10 -0
  116. package/src/components/entities/entity-settings-form/locales/fr.ts +10 -0
  117. package/src/components/entities/entity-settings-form/locales/hr.ts +10 -0
  118. package/src/components/entities/entity-settings-form/locales/it.ts +10 -0
  119. package/src/components/entities/entity-settings-form/locales/nl.ts +10 -0
  120. package/src/components/entities/entity-settings-form/locales/pl.ts +10 -0
  121. package/src/components/entities/entity-settings-form/locales/pt.ts +10 -0
  122. package/src/components/entities/entity-settings-form/locales/sl.ts +10 -0
  123. package/src/components/entities/fina-settings-form/fina-settings-form.tsx +6 -6
  124. package/src/components/entities/fina-settings-form/locales/de.ts +2 -2
  125. package/src/components/entities/fina-settings-form/locales/en.ts +2 -2
  126. package/src/components/entities/fina-settings-form/locales/es.ts +2 -2
  127. package/src/components/entities/fina-settings-form/locales/fr.ts +2 -2
  128. package/src/components/entities/fina-settings-form/locales/hr.ts +2 -2
  129. package/src/components/entities/fina-settings-form/locales/it.ts +2 -2
  130. package/src/components/entities/fina-settings-form/locales/nl.ts +2 -2
  131. package/src/components/entities/fina-settings-form/locales/pl.ts +2 -2
  132. package/src/components/entities/fina-settings-form/locales/pt.ts +2 -2
  133. package/src/components/entities/fina-settings-form/locales/sl.ts +2 -2
  134. package/src/components/entities/furs-settings-form/locales/en.ts +0 -1
  135. package/src/components/entities/settings/company-settings-form.tsx +173 -20
  136. package/src/components/entities/settings/pdf-template-selector/locales/de.ts +3 -1
  137. package/src/components/entities/settings/pdf-template-selector/locales/es.ts +3 -1
  138. package/src/components/entities/settings/pdf-template-selector/locales/fr.ts +4 -1
  139. package/src/components/entities/settings/pdf-template-selector/locales/hr.ts +4 -1
  140. package/src/components/entities/settings/pdf-template-selector/locales/it.ts +3 -1
  141. package/src/components/entities/settings/pdf-template-selector/locales/nl.ts +3 -1
  142. package/src/components/entities/settings/pdf-template-selector/locales/pl.ts +3 -1
  143. package/src/components/entities/settings/pdf-template-selector/locales/pt.ts +3 -1
  144. package/src/components/entities/settings/pdf-template-selector/locales/sl.ts +3 -1
  145. package/src/components/entities/settings/pdf-template-selector/pdf-template-cards.tsx +1 -0
  146. package/src/components/estimates/create/create-estimate-form.tsx +93 -8
  147. package/src/components/estimates/create/locales/de.ts +16 -0
  148. package/src/components/estimates/create/locales/es.ts +16 -0
  149. package/src/components/estimates/create/locales/fr.ts +16 -0
  150. package/src/components/estimates/create/locales/hr.ts +16 -0
  151. package/src/components/estimates/create/locales/it.ts +16 -0
  152. package/src/components/estimates/create/locales/nl.ts +16 -0
  153. package/src/components/estimates/create/locales/pl.ts +16 -0
  154. package/src/components/estimates/create/locales/pt.ts +16 -0
  155. package/src/components/estimates/create/locales/sl.ts +17 -1
  156. package/src/components/estimates/list/list-table.tsx +14 -8
  157. package/src/components/estimates/list/locales/de.ts +2 -0
  158. package/src/components/estimates/list/locales/en.ts +1 -0
  159. package/src/components/estimates/list/locales/es.ts +2 -0
  160. package/src/components/estimates/list/locales/fr.ts +2 -0
  161. package/src/components/estimates/list/locales/hr.ts +2 -0
  162. package/src/components/estimates/list/locales/it.ts +2 -0
  163. package/src/components/estimates/list/locales/nl.ts +2 -0
  164. package/src/components/estimates/list/locales/pl.ts +2 -0
  165. package/src/components/estimates/list/locales/pt.ts +2 -0
  166. package/src/components/estimates/list/locales/sl.ts +2 -0
  167. package/src/components/export/document-export-form.tsx +55 -14
  168. package/src/components/export/index.ts +2 -0
  169. package/src/components/export/sales-per-item-export-form.tsx +223 -0
  170. package/src/components/invoices/create/create-invoice-form.tsx +106 -11
  171. package/src/components/invoices/create/locales/de.ts +26 -0
  172. package/src/components/invoices/create/locales/es.ts +26 -0
  173. package/src/components/invoices/create/locales/fr.ts +26 -0
  174. package/src/components/invoices/create/locales/hr.ts +25 -0
  175. package/src/components/invoices/create/locales/it.ts +26 -0
  176. package/src/components/invoices/create/locales/nl.ts +26 -0
  177. package/src/components/invoices/create/locales/pl.ts +25 -0
  178. package/src/components/invoices/create/locales/pt.ts +25 -0
  179. package/src/components/invoices/create/locales/sl.ts +26 -1
  180. package/src/components/invoices/invoices-furs.hooks.ts +4 -1
  181. package/src/components/invoices/list/list-table.tsx +77 -31
  182. package/src/components/invoices/list/locales/de.ts +5 -0
  183. package/src/components/invoices/list/locales/en.ts +4 -0
  184. package/src/components/invoices/list/locales/es.ts +5 -0
  185. package/src/components/invoices/list/locales/fr.ts +5 -0
  186. package/src/components/invoices/list/locales/hr.ts +5 -0
  187. package/src/components/invoices/list/locales/it.ts +5 -0
  188. package/src/components/invoices/list/locales/nl.ts +5 -0
  189. package/src/components/invoices/list/locales/pl.ts +5 -0
  190. package/src/components/invoices/list/locales/pt.ts +5 -0
  191. package/src/components/invoices/list/locales/sl.ts +5 -0
  192. package/src/components/invoices/view/fiscalization-status-card.tsx +44 -24
  193. package/src/components/items/item-combobox.tsx +5 -3
  194. package/src/components/items/item-list-table/item-list-header.tsx +4 -17
  195. package/src/components/items/item-list-table/item-list-table.tsx +3 -3
  196. package/src/components/items/item-list-table/locales/de.ts +1 -0
  197. package/src/components/items/item-list-table/locales/es.ts +1 -0
  198. package/src/components/items/item-list-table/locales/fr.ts +1 -0
  199. package/src/components/items/item-list-table/locales/hr.ts +1 -0
  200. package/src/components/items/item-list-table/locales/it.ts +1 -0
  201. package/src/components/items/item-list-table/locales/nl.ts +1 -0
  202. package/src/components/items/item-list-table/locales/pl.ts +1 -0
  203. package/src/components/items/item-list-table/locales/pt.ts +1 -0
  204. package/src/components/items/item-list-table/locales/sl.ts +1 -0
  205. package/src/components/payments/list/list-table.tsx +0 -4
  206. package/src/components/payments/list/locales/de.ts +1 -0
  207. package/src/components/payments/list/locales/es.ts +1 -0
  208. package/src/components/payments/list/locales/fr.ts +1 -0
  209. package/src/components/payments/list/locales/hr.ts +1 -0
  210. package/src/components/payments/list/locales/it.ts +1 -0
  211. package/src/components/payments/list/locales/nl.ts +1 -0
  212. package/src/components/payments/list/locales/pl.ts +1 -0
  213. package/src/components/payments/list/locales/pt.ts +1 -0
  214. package/src/components/payments/list/locales/sl.ts +1 -0
  215. package/src/components/recurring-invoices/list/list-table.tsx +0 -7
  216. package/src/components/recurring-invoices/list/locales/de.ts +1 -0
  217. package/src/components/recurring-invoices/list/locales/es.ts +1 -0
  218. package/src/components/recurring-invoices/list/locales/fr.ts +1 -0
  219. package/src/components/recurring-invoices/list/locales/hr.ts +1 -0
  220. package/src/components/recurring-invoices/list/locales/it.ts +1 -0
  221. package/src/components/recurring-invoices/list/locales/nl.ts +1 -0
  222. package/src/components/recurring-invoices/list/locales/pl.ts +1 -0
  223. package/src/components/recurring-invoices/list/locales/pt.ts +1 -0
  224. package/src/components/recurring-invoices/list/locales/sl.ts +1 -0
  225. package/src/components/request-logs/request-log-list-table.tsx +0 -3
  226. package/src/components/table/README.md +14 -121
  227. package/src/components/table/data-table.tsx +22 -37
  228. package/src/components/table/hooks/use-table-state.ts +3 -27
  229. package/src/components/table/index.ts +0 -2
  230. package/src/components/table/search-input.tsx +17 -0
  231. package/src/components/table/selection-toolbar.tsx +35 -1
  232. package/src/components/table/table-empty-state.tsx +6 -3
  233. package/src/components/table/table-no-results.tsx +10 -5
  234. package/src/components/table/types.ts +0 -5
  235. package/src/components/taxes/tax-list-table/locales/de.ts +1 -0
  236. package/src/components/taxes/tax-list-table/locales/es.ts +1 -0
  237. package/src/components/taxes/tax-list-table/locales/fr.ts +1 -0
  238. package/src/components/taxes/tax-list-table/locales/hr.ts +1 -0
  239. package/src/components/taxes/tax-list-table/locales/it.ts +1 -0
  240. package/src/components/taxes/tax-list-table/locales/nl.ts +1 -0
  241. package/src/components/taxes/tax-list-table/locales/pl.ts +1 -0
  242. package/src/components/taxes/tax-list-table/locales/pt.ts +1 -0
  243. package/src/components/taxes/tax-list-table/locales/sl.ts +1 -0
  244. package/src/components/taxes/tax-list-table/tax-list-header.tsx +3 -14
  245. package/src/components/taxes/tax-list-table/tax-list-table.tsx +3 -3
  246. package/src/components/ui/popover.tsx +3 -1
  247. package/src/components/ui/tooltip.tsx +3 -1
  248. package/src/generated/schemas/advanceinvoice.ts +4 -2
  249. package/src/generated/schemas/creditnote.ts +2 -1
  250. package/src/generated/schemas/deliverynote.ts +2 -1
  251. package/src/generated/schemas/estimate.ts +4 -2
  252. package/src/generated/schemas/index.ts +1 -1
  253. package/src/generated/schemas/invoice.ts +2 -1
  254. package/src/generated/schemas/renderadvanceinvoicepreview_body.ts +17 -23
  255. package/src/generated/schemas/rendercreditnotepreview_body.ts +17 -23
  256. package/src/generated/schemas/renderdeliverynotepreview_body.ts +17 -23
  257. package/src/generated/schemas/renderestimatepreview_body.ts +17 -23
  258. package/src/generated/schemas/renderinvoicepreview_body.ts +19 -23
  259. package/src/hooks/use-duplicate-document.ts +56 -14
  260. package/src/hooks/use-vies-check.ts +3 -0
  261. package/src/lib/fiscalization.ts +12 -0
  262. package/src/lib/schemas/advance-invoice.ts +0 -1
  263. package/src/components/table/sortable-header.tsx +0 -56
@@ -1,4 +1,5 @@
1
1
  import type { CreditNote } from "@spaceinvoices/js-sdk";
2
+ import { AlertTriangle } from "lucide-react";
2
3
  import { useCallback, useMemo, useState } from "react";
3
4
  import { DataTable } from "@/ui/components/table/data-table";
4
5
  import { FormattedDate } from "@/ui/components/table/date-cell";
@@ -13,6 +14,8 @@ import type {
13
14
  } from "@/ui/components/table/types";
14
15
  import { Badge } from "@/ui/components/ui/badge";
15
16
  import { Button } from "@/ui/components/ui/button";
17
+ import { Tooltip, TooltipContent, TooltipTrigger } from "@/ui/components/ui/tooltip";
18
+ import { getFiscalizationFailureType } from "@/ui/lib/fiscalization";
16
19
  import { createTranslation } from "@/ui/lib/translation";
17
20
  import { useSDK } from "@/ui/providers/sdk-provider";
18
21
 
@@ -53,6 +56,11 @@ type CreditNoteListTableProps = {
53
56
  onDownloadSuccess?: (fileName: string) => void;
54
57
  onDownloadError?: (error: string) => void;
55
58
  onExportSelected?: (documentIds: string[]) => void;
59
+ onRetryFiscalization?: (documentIds: string[]) => void;
60
+ fiscalizationFeatures?: ("furs" | "fina")[];
61
+ onCreateNew?: () => void;
62
+ onVoid?: (creditNote: CreditNote) => void;
63
+ isVoiding?: boolean;
56
64
  } & ListTableProps<CreditNote>;
57
65
 
58
66
  export default function CreditNoteListTable({
@@ -67,6 +75,11 @@ export default function CreditNoteListTable({
67
75
  onDownloadSuccess,
68
76
  onDownloadError,
69
77
  onExportSelected,
78
+ onRetryFiscalization,
79
+ fiscalizationFeatures,
80
+ onCreateNew,
81
+ onVoid,
82
+ isVoiding,
70
83
  ...i18nProps
71
84
  }: CreditNoteListTableProps) {
72
85
  const t = createTranslation({
@@ -86,9 +99,9 @@ export default function CreditNoteListTable({
86
99
  limit: params.limit,
87
100
  next_cursor: params.next_cursor,
88
101
  prev_cursor: params.prev_cursor,
89
- order_by: params.order_by,
90
102
  search: params.search,
91
103
  query: params.query,
104
+ include: "document_relations",
92
105
  });
93
106
  return response as unknown as TableQueryResponse<CreditNote>;
94
107
  }, entityId);
@@ -115,15 +128,42 @@ export default function CreditNoteListTable({
115
128
  }, []);
116
129
 
117
130
  const selectionToolbar = useCallback(
118
- (count: number) => (
119
- <SelectionToolbar
120
- selectedCount={count}
121
- onExportPdfs={onExportSelected ? handleExportPdfs : undefined}
122
- onDeselectAll={handleDeselectAll}
123
- t={t}
124
- />
125
- ),
126
- [handleExportPdfs, handleDeselectAll, onExportSelected, t],
131
+ (count: number, data: CreditNote[]) => {
132
+ const selectedDocs = data.filter((d) => selectedIds.has(d.id));
133
+ const failedDocs = selectedDocs.filter((d) => {
134
+ const failureType = getFiscalizationFailureType(d as any);
135
+ return failureType && fiscalizationFeatures?.includes(failureType);
136
+ });
137
+
138
+ const hasRetry = onRetryFiscalization && fiscalizationFeatures?.length;
139
+ const failedCount = failedDocs.length;
140
+ const allFailed = failedCount > 0 && failedCount === selectedDocs.length;
141
+ const someFailed = failedCount > 0 && failedCount < selectedDocs.length;
142
+ const showRetry = hasRetry && failedCount > 0;
143
+
144
+ return (
145
+ <SelectionToolbar
146
+ selectedCount={count}
147
+ onExportPdfs={onExportSelected ? handleExportPdfs : undefined}
148
+ onRetryFiscalization={showRetry ? () => onRetryFiscalization(failedDocs.map((d) => d.id)) : undefined}
149
+ retryFiscalizationDisabled={someFailed && !allFailed}
150
+ retryFiscalizationTooltip={
151
+ someFailed ? t("Some selected documents don't have failed fiscalization") : undefined
152
+ }
153
+ onDeselectAll={handleDeselectAll}
154
+ t={t}
155
+ />
156
+ );
157
+ },
158
+ [
159
+ handleExportPdfs,
160
+ handleDeselectAll,
161
+ onExportSelected,
162
+ onRetryFiscalization,
163
+ fiscalizationFeatures,
164
+ selectedIds,
165
+ t,
166
+ ],
127
167
  );
128
168
 
129
169
  const columns: Column<CreditNote>[] = useMemo(
@@ -131,22 +171,35 @@ export default function CreditNoteListTable({
131
171
  {
132
172
  id: "number",
133
173
  header: t("Number"),
134
- sortable: true,
135
- cell: (creditNote) => (
136
- <div className="flex items-center gap-2">
137
- <Button variant="link" className="cursor-pointer py-0 underline" onClick={() => onRowClick?.(creditNote)}>
138
- {creditNote.number}
139
- </Button>
140
- {(creditNote as any).is_draft && (
141
- <Badge
142
- variant="outline"
143
- className="border-amber-500 bg-amber-50 text-amber-700 dark:bg-amber-950 dark:text-amber-400"
144
- >
145
- {t("Draft")}
146
- </Badge>
147
- )}
148
- </div>
149
- ),
174
+ cell: (creditNote) => {
175
+ const failureType = getFiscalizationFailureType(creditNote as any);
176
+ const showWarning = failureType && fiscalizationFeatures?.includes(failureType);
177
+ return (
178
+ <div className="flex items-center gap-2">
179
+ <Button variant="link" className="cursor-pointer py-0 underline" onClick={() => onRowClick?.(creditNote)}>
180
+ {creditNote.number}
181
+ </Button>
182
+ {(creditNote as any).is_draft && (
183
+ <Badge
184
+ variant="outline"
185
+ className="border-amber-500 bg-amber-50 text-amber-700 dark:bg-amber-950 dark:text-amber-400"
186
+ >
187
+ {t("Draft")}
188
+ </Badge>
189
+ )}
190
+ {showWarning && (
191
+ <Tooltip>
192
+ <TooltipTrigger>
193
+ <AlertTriangle className="size-4 text-orange-500" />
194
+ </TooltipTrigger>
195
+ <TooltipContent>
196
+ {t(failureType === "furs" ? "FURS fiscalization failed" : "FINA fiscalization failed")}
197
+ </TooltipContent>
198
+ </Tooltip>
199
+ )}
200
+ </div>
201
+ );
202
+ },
150
203
  },
151
204
  {
152
205
  id: "customer",
@@ -156,22 +209,19 @@ export default function CreditNoteListTable({
156
209
  {
157
210
  id: "date",
158
211
  header: t("Date"),
159
- sortable: true,
160
212
  cell: (creditNote) => <FormattedDate date={creditNote.date} />,
161
213
  },
162
214
  {
163
215
  id: "total",
164
216
  header: t("Total"),
165
- sortable: true,
166
217
  align: "right",
167
- cell: (creditNote) => creditNote.total,
218
+ cell: (creditNote) => -creditNote.total,
168
219
  },
169
220
  {
170
221
  id: "total_with_tax",
171
222
  header: t("Total with Tax"),
172
- sortable: true,
173
223
  align: "right",
174
- cell: (creditNote) => creditNote.total_with_tax,
224
+ cell: (creditNote) => -creditNote.total_with_tax,
175
225
  },
176
226
  {
177
227
  id: "status",
@@ -191,6 +241,8 @@ export default function CreditNoteListTable({
191
241
  onDownloadStart={onDownloadStart}
192
242
  onDownloadSuccess={onDownloadSuccess}
193
243
  onDownloadError={onDownloadError}
244
+ onVoid={onVoid}
245
+ isVoiding={isVoiding}
194
246
  t={t}
195
247
  locale={i18nProps.locale}
196
248
  />
@@ -206,7 +258,10 @@ export default function CreditNoteListTable({
206
258
  onDownloadStart,
207
259
  onDownloadSuccess,
208
260
  onDownloadError,
261
+ onVoid,
262
+ isVoiding,
209
263
  i18nProps.locale,
264
+ fiscalizationFeatures,
210
265
  ],
211
266
  );
212
267
 
@@ -217,13 +272,14 @@ export default function CreditNoteListTable({
217
272
  resourceName="credit_note"
218
273
  cacheKey="credit-notes"
219
274
  createNewLink={entityId ? `/app/${entityId}/documents/add/credit_note` : undefined}
275
+ onCreateNew={onCreateNew}
220
276
  onFetch={handleFetch}
221
277
  onChangeParams={onChangeParams}
222
278
  entityId={entityId}
223
279
  filterConfig={filterConfig}
224
280
  t={t}
225
281
  locale={i18nProps.locale}
226
- selectable={!!onExportSelected}
282
+ selectable={!!(onExportSelected || onRetryFiscalization)}
227
283
  selectedIds={selectedIds}
228
284
  onSelectionChange={setSelectedIds}
229
285
  selectionToolbar={selectionToolbar}
@@ -243,6 +299,11 @@ function CreditNoteStatusBadge({ creditNote, t }: { creditNote: CreditNote; t: (
243
299
  if ((creditNote as any).is_draft) {
244
300
  return null;
245
301
  }
302
+ // Hide payment badges for void-created credit notes (has "credit_for" relation)
303
+ const isVoidCreated = (creditNote as any).document_relations?.some((rel: any) => rel.relation_type === "credit_for");
304
+ if (isVoidCreated) {
305
+ return null;
306
+ }
246
307
  if (creditNote.paid_in_full) {
247
308
  return (
248
309
  <Badge
@@ -38,7 +38,14 @@ export default {
38
38
  "No results found": "Keine Gutschriften gefunden",
39
39
  "Try adjusting your search criteria": "Versuchen Sie, Ihre Suchkriterien anzupassen",
40
40
  "Clear search": "Suche zurücksetzen",
41
+ "Clear all": "Alles zurücksetzen",
41
42
  selected: "ausgewählt",
42
43
  "Export PDFs": "PDFs exportieren",
43
44
  "Deselect all": "Auswahl aufheben",
45
+ "FURS fiscalization failed": "FURS fiscalization failed",
46
+ "FINA fiscalization failed": "FINA fiscalization failed",
47
+ "Retry Fiscalization": "Retry Fiscalization",
48
+ "Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
49
+ Void: "Stornieren",
50
+ "Cannot void a fiscalized credit note": "Stornierung einer fiskalisierten Gutschrift nicht möglich",
44
51
  } as const;
@@ -10,4 +10,10 @@ export default {
10
10
  "Deselect all": "Deselect all",
11
11
  "Partially Paid": "Partially Paid",
12
12
  Voided: "Voided",
13
+ "FURS fiscalization failed": "FURS fiscalization failed",
14
+ "FINA fiscalization failed": "FINA fiscalization failed",
15
+ "Retry Fiscalization": "Retry Fiscalization",
16
+ "Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
17
+ Void: "Void",
18
+ "Cannot void a fiscalized credit note": "Cannot void a fiscalized credit note",
13
19
  } as const;
@@ -38,7 +38,14 @@ export default {
38
38
  "No results found": "No se encontraron notas de credito",
39
39
  "Try adjusting your search criteria": "Intente ajustar sus criterios de busqueda",
40
40
  "Clear search": "Limpiar busqueda",
41
+ "Clear all": "Borrar todo",
41
42
  selected: "seleccionados",
42
43
  "Export PDFs": "Exportar PDFs",
43
44
  "Deselect all": "Deseleccionar todo",
45
+ "FURS fiscalization failed": "FURS fiscalization failed",
46
+ "FINA fiscalization failed": "FINA fiscalization failed",
47
+ "Retry Fiscalization": "Retry Fiscalization",
48
+ "Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
49
+ Void: "Anular",
50
+ "Cannot void a fiscalized credit note": "No se puede anular una nota de crédito fiscalizada",
44
51
  } as const;
@@ -38,7 +38,14 @@ export default {
38
38
  "No results found": "Aucun avoir trouve",
39
39
  "Try adjusting your search criteria": "Essayez de modifier vos criteres de recherche",
40
40
  "Clear search": "Effacer la recherche",
41
+ "Clear all": "Tout effacer",
41
42
  selected: "sélectionnés",
42
43
  "Export PDFs": "Exporter les PDF",
43
44
  "Deselect all": "Tout désélectionner",
45
+ "FURS fiscalization failed": "FURS fiscalization failed",
46
+ "FINA fiscalization failed": "FINA fiscalization failed",
47
+ "Retry Fiscalization": "Retry Fiscalization",
48
+ "Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
49
+ Void: "Annuler",
50
+ "Cannot void a fiscalized credit note": "Impossible d'annuler un avoir fiscalisé",
44
51
  } as const;
@@ -38,7 +38,14 @@ export default {
38
38
  "No results found": "Nije pronadjeno nijedno odobrenje",
39
39
  "Try adjusting your search criteria": "Pokusajte prilagoditi kriterije pretrazivanja",
40
40
  "Clear search": "Ocisti pretragu",
41
+ "Clear all": "Očisti sve",
41
42
  selected: "odabranih",
42
43
  "Export PDFs": "Izvezi PDF-ove",
43
44
  "Deselect all": "Poništi odabir",
45
+ "FURS fiscalization failed": "FURS fiskalizacija nije uspjela",
46
+ "FINA fiscalization failed": "FINA fiskalizacija nije uspjela",
47
+ "Retry Fiscalization": "Ponovi fiskalizaciju",
48
+ "Some selected documents don't have failed fiscalization": "Neki odabrani dokumenti nemaju neuspjelu fiskalizaciju",
49
+ Void: "Storniraj",
50
+ "Cannot void a fiscalized credit note": "Nije moguće poništiti fiskalizirani dobropis",
44
51
  } as const;
@@ -38,7 +38,14 @@ export default {
38
38
  "No results found": "Nessuna nota di credito trovata",
39
39
  "Try adjusting your search criteria": "Prova a modificare i criteri di ricerca",
40
40
  "Clear search": "Cancella ricerca",
41
+ "Clear all": "Cancella tutto",
41
42
  selected: "selezionati",
42
43
  "Export PDFs": "Esporta PDF",
43
44
  "Deselect all": "Deseleziona tutto",
45
+ "FURS fiscalization failed": "FURS fiscalization failed",
46
+ "FINA fiscalization failed": "FINA fiscalization failed",
47
+ "Retry Fiscalization": "Retry Fiscalization",
48
+ "Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
49
+ Void: "Annulla",
50
+ "Cannot void a fiscalized credit note": "Impossibile annullare una nota di credito fiscalizzata",
44
51
  } as const;
@@ -38,7 +38,14 @@ export default {
38
38
  "No results found": "Geen creditnota's gevonden",
39
39
  "Try adjusting your search criteria": "Probeer uw zoekcriteria aan te passen",
40
40
  "Clear search": "Zoekopdracht wissen",
41
+ "Clear all": "Alles wissen",
41
42
  selected: "geselecteerd",
42
43
  "Export PDFs": "PDFs exporteren",
43
44
  "Deselect all": "Alles deselecteren",
45
+ "FURS fiscalization failed": "FURS fiscalization failed",
46
+ "FINA fiscalization failed": "FINA fiscalization failed",
47
+ "Retry Fiscalization": "Retry Fiscalization",
48
+ "Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
49
+ Void: "Nietig verklaren",
50
+ "Cannot void a fiscalized credit note": "Kan een gefiscaliseerde creditnota niet ongeldig maken",
44
51
  } as const;
@@ -38,7 +38,14 @@ export default {
38
38
  "No results found": "Nie znaleziono not kredytowych",
39
39
  "Try adjusting your search criteria": "Sprobuj dostosowac kryteria wyszukiwania",
40
40
  "Clear search": "Wyczysc wyszukiwanie",
41
+ "Clear all": "Wyczyść wszystko",
41
42
  selected: "wybranych",
42
43
  "Export PDFs": "Eksportuj PDF-y",
43
44
  "Deselect all": "Odznacz wszystko",
45
+ "FURS fiscalization failed": "FURS fiscalization failed",
46
+ "FINA fiscalization failed": "FINA fiscalization failed",
47
+ "Retry Fiscalization": "Retry Fiscalization",
48
+ "Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
49
+ Void: "Anuluj",
50
+ "Cannot void a fiscalized credit note": "Nie można anulować zafiskalizowanej noty kredytowej",
44
51
  } as const;
@@ -38,7 +38,14 @@ export default {
38
38
  "No results found": "Nenhuma nota de credito encontrada",
39
39
  "Try adjusting your search criteria": "Tente ajustar os seus criterios de pesquisa",
40
40
  "Clear search": "Limpar pesquisa",
41
+ "Clear all": "Limpar tudo",
41
42
  selected: "selecionados",
42
43
  "Export PDFs": "Exportar PDFs",
43
44
  "Deselect all": "Desselecionar tudo",
45
+ "FURS fiscalization failed": "FURS fiscalization failed",
46
+ "FINA fiscalization failed": "FINA fiscalization failed",
47
+ "Retry Fiscalization": "Retry Fiscalization",
48
+ "Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
49
+ Void: "Anular",
50
+ "Cannot void a fiscalized credit note": "Não é possível anular uma nota de crédito fiscalizada",
44
51
  } as const;
@@ -38,7 +38,14 @@ export default {
38
38
  "No results found": "Ni najdenih dobropisov",
39
39
  "Try adjusting your search criteria": "Poskusite prilagoditi iskalne kriterije",
40
40
  "Clear search": "Počisti iskanje",
41
+ "Clear all": "Počisti vse",
41
42
  selected: "izbranih",
42
43
  "Export PDFs": "Izvozi PDF-je",
43
44
  "Deselect all": "Počisti izbiro",
45
+ "FURS fiscalization failed": "FURS davčno potrjevanje ni uspelo",
46
+ "FINA fiscalization failed": "FINA fiskalizacija ni uspela",
47
+ "Retry Fiscalization": "Ponovi fiskalizacijo",
48
+ "Some selected documents don't have failed fiscalization": "Nekateri izbrani dokumenti nimajo neuspele fiskalizacije",
49
+ Void: "Storniraj",
50
+ "Cannot void a fiscalized credit note": "Ni mogoče razveljaviti fiskalizirane dobropisa",
44
51
  } as const;
@@ -69,7 +69,6 @@ export default function CustomerListTable({
69
69
  limit: params.limit,
70
70
  next_cursor: params.next_cursor,
71
71
  prev_cursor: params.prev_cursor,
72
- order_by: params.order_by,
73
72
  search: params.search,
74
73
  query: params.query,
75
74
  });
@@ -81,7 +80,6 @@ export default function CustomerListTable({
81
80
  {
82
81
  id: "name",
83
82
  header: t("Name"),
84
- sortable: true,
85
83
  cell: (customer) => (
86
84
  <Button variant="link" className="cursor-pointer py-0 underline" onClick={() => onRowClick?.(customer)}>
87
85
  <User className="h-4 w-4 flex-shrink-0" />
@@ -92,7 +90,6 @@ export default function CustomerListTable({
92
90
  {
93
91
  id: "address",
94
92
  header: t("Address"),
95
- sortable: true,
96
93
  cell: (customer) => customer.address,
97
94
  },
98
95
  {
@@ -22,4 +22,5 @@ export default {
22
22
  "No results found": "Keine Kunden gefunden",
23
23
  "Try adjusting your search criteria": "Versuchen Sie, Ihre Suchkriterien anzupassen",
24
24
  "Clear search": "Suche zurücksetzen",
25
+ "Clear all": "Alles zurücksetzen",
25
26
  } as const;
@@ -22,4 +22,5 @@ export default {
22
22
  "No results found": "No se encontraron clientes",
23
23
  "Try adjusting your search criteria": "Intente ajustar sus criterios de busqueda",
24
24
  "Clear search": "Limpiar busqueda",
25
+ "Clear all": "Borrar todo",
25
26
  } as const;
@@ -22,4 +22,5 @@ export default {
22
22
  "No results found": "Aucun client trouve",
23
23
  "Try adjusting your search criteria": "Essayez de modifier vos criteres de recherche",
24
24
  "Clear search": "Effacer la recherche",
25
+ "Clear all": "Tout effacer",
25
26
  } as const;
@@ -22,4 +22,5 @@ export default {
22
22
  "No results found": "Nije pronadjen nijedan kupac",
23
23
  "Try adjusting your search criteria": "Pokusajte prilagoditi kriterije pretrazivanja",
24
24
  "Clear search": "Ocisti pretragu",
25
+ "Clear all": "Očisti sve",
25
26
  } as const;
@@ -22,4 +22,5 @@ export default {
22
22
  "No results found": "Nessun cliente trovato",
23
23
  "Try adjusting your search criteria": "Prova a modificare i criteri di ricerca",
24
24
  "Clear search": "Cancella ricerca",
25
+ "Clear all": "Cancella tutto",
25
26
  } as const;
@@ -22,4 +22,5 @@ export default {
22
22
  "No results found": "Geen klanten gevonden",
23
23
  "Try adjusting your search criteria": "Probeer uw zoekcriteria aan te passen",
24
24
  "Clear search": "Zoekopdracht wissen",
25
+ "Clear all": "Alles wissen",
25
26
  } as const;
@@ -22,4 +22,5 @@ export default {
22
22
  "No results found": "Nie znaleziono klientow",
23
23
  "Try adjusting your search criteria": "Sprobuj dostosowac kryteria wyszukiwania",
24
24
  "Clear search": "Wyczysc wyszukiwanie",
25
+ "Clear all": "Wyczyść wszystko",
25
26
  } as const;
@@ -22,4 +22,5 @@ export default {
22
22
  "No results found": "Nenhum cliente encontrado",
23
23
  "Try adjusting your search criteria": "Tente ajustar os seus criterios de pesquisa",
24
24
  "Clear search": "Limpar pesquisa",
25
+ "Clear all": "Limpar tudo",
25
26
  } as const;
@@ -22,4 +22,5 @@ export default {
22
22
  "No results found": "Ni najdenih strank",
23
23
  "Try adjusting your search criteria": "Poskusite prilagoditi iskalne kriterije",
24
24
  "Clear search": "Počisti iskanje",
25
+ "Clear all": "Počisti vse",
25
26
  } as const;
@@ -20,7 +20,7 @@ export function useCollectionRateData(entityId: string | undefined) {
20
20
 
21
21
  const queries = useQueries({
22
22
  queries: [
23
- // Total invoiced (non-voided)
23
+ // Total invoiced (including voided — counter credit notes cancel them out)
24
24
  {
25
25
  queryKey: [STATS_QUERY_CACHE_KEY, entityId, "total-invoiced"],
26
26
  queryFn: async () => {
@@ -29,7 +29,7 @@ export function useCollectionRateData(entityId: string | undefined) {
29
29
  {
30
30
  metrics: [{ type: "sum", field: "total_with_tax", alias: "total" }],
31
31
  table: "invoices",
32
- filters: { is_draft: false, voided_at: null },
32
+ filters: { is_draft: false },
33
33
  },
34
34
  { entity_id: entityId },
35
35
  );
@@ -37,15 +37,50 @@ export function useCollectionRateData(entityId: string | undefined) {
37
37
  enabled: !!entityId && !!sdk,
38
38
  staleTime: 120_000,
39
39
  },
40
- // Total collected (payments)
40
+ // Invoice payments (credit_note_id IS NULL)
41
41
  {
42
- queryKey: [STATS_QUERY_CACHE_KEY, entityId, "total-collected"],
42
+ queryKey: [STATS_QUERY_CACHE_KEY, entityId, "invoice-payments"],
43
43
  queryFn: async () => {
44
44
  if (!entityId || !sdk) throw new Error("Missing entity or SDK");
45
45
  return sdk.entityStats.queryEntityStats(
46
46
  {
47
47
  metrics: [{ type: "sum", field: "amount", alias: "total" }],
48
48
  table: "payments",
49
+ filters: { credit_note_id: null },
50
+ },
51
+ { entity_id: entityId },
52
+ );
53
+ },
54
+ enabled: !!entityId && !!sdk,
55
+ staleTime: 120_000,
56
+ },
57
+ // Credit note payments / refunds (credit_note_id IS NOT NULL)
58
+ {
59
+ queryKey: [STATS_QUERY_CACHE_KEY, entityId, "cn-payments"],
60
+ queryFn: async () => {
61
+ if (!entityId || !sdk) throw new Error("Missing entity or SDK");
62
+ return sdk.entityStats.queryEntityStats(
63
+ {
64
+ metrics: [{ type: "sum", field: "amount", alias: "total" }],
65
+ table: "payments",
66
+ filters: { credit_note_id: { not: null } },
67
+ },
68
+ { entity_id: entityId },
69
+ );
70
+ },
71
+ enabled: !!entityId && !!sdk,
72
+ staleTime: 120_000,
73
+ },
74
+ // Credit notes total (subtracted from invoiced to get net revenue)
75
+ {
76
+ queryKey: [STATS_QUERY_CACHE_KEY, entityId, "cn-total"],
77
+ queryFn: async () => {
78
+ if (!entityId || !sdk) throw new Error("Missing entity or SDK");
79
+ return sdk.entityStats.queryEntityStats(
80
+ {
81
+ metrics: [{ type: "sum", field: "total_with_tax", alias: "total" }],
82
+ table: "credit_notes",
83
+ filters: { is_draft: false },
49
84
  },
50
85
  { entity_id: entityId },
51
86
  );
@@ -56,17 +91,21 @@ export function useCollectionRateData(entityId: string | undefined) {
56
91
  ],
57
92
  });
58
93
 
59
- const [invoicedQuery, collectedQuery] = queries;
94
+ const [invoicedQuery, invoicePaymentsQuery, cnPaymentsQuery, cnQuery] = queries;
60
95
 
61
96
  const totalInvoiced = Number(invoicedQuery.data?.data?.[0]?.total) || 0;
62
- const totalCollected = Number(collectedQuery.data?.data?.[0]?.total) || 0;
63
- const collectionRate = totalInvoiced > 0 ? (totalCollected / totalInvoiced) * 100 : 0;
97
+ const invoicePayments = Number(invoicePaymentsQuery.data?.data?.[0]?.total) || 0;
98
+ const cnPayments = Number(cnPaymentsQuery.data?.data?.[0]?.total) || 0;
99
+ const cnTotal = Number(cnQuery.data?.data?.[0]?.total) || 0;
100
+ const netInvoiced = totalInvoiced - cnTotal;
101
+ const netCollected = invoicePayments - cnPayments;
102
+ const collectionRate = netInvoiced > 0 ? (netCollected / netInvoiced) * 100 : 0;
64
103
 
65
104
  return {
66
105
  data: {
67
106
  collectionRate,
68
- totalCollected,
69
- totalInvoiced,
107
+ totalCollected: netCollected,
108
+ totalInvoiced: netInvoiced,
70
109
  currency: "EUR", // TODO: Get from entity settings
71
110
  } as CollectionRateData,
72
111
  isLoading: queries.some((q) => q.isLoading),