@spaceinvoices/react-ui 0.4.2 → 0.4.4

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 (267) 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 +0 -1
  5. package/src/components/advance-invoices/create/locales/de.ts +2 -0
  6. package/src/components/advance-invoices/create/locales/es.ts +2 -0
  7. package/src/components/advance-invoices/create/locales/fr.ts +2 -0
  8. package/src/components/advance-invoices/create/locales/hr.ts +1 -0
  9. package/src/components/advance-invoices/create/locales/it.ts +2 -0
  10. package/src/components/advance-invoices/create/locales/nl.ts +2 -0
  11. package/src/components/advance-invoices/create/locales/pl.ts +1 -0
  12. package/src/components/advance-invoices/create/locales/pt.ts +1 -0
  13. package/src/components/advance-invoices/create/locales/sl.ts +1 -0
  14. package/src/components/advance-invoices/create/prepare-advance-invoice-submission.ts +0 -1
  15. package/src/components/advance-invoices/list/list-table.tsx +130 -40
  16. package/src/components/advance-invoices/list/locales/de.ts +6 -0
  17. package/src/components/advance-invoices/list/locales/en.ts +5 -0
  18. package/src/components/advance-invoices/list/locales/es.ts +6 -0
  19. package/src/components/advance-invoices/list/locales/fr.ts +6 -0
  20. package/src/components/advance-invoices/list/locales/hr.ts +6 -0
  21. package/src/components/advance-invoices/list/locales/it.ts +6 -0
  22. package/src/components/advance-invoices/list/locales/nl.ts +6 -0
  23. package/src/components/advance-invoices/list/locales/pl.ts +6 -0
  24. package/src/components/advance-invoices/list/locales/pt.ts +6 -0
  25. package/src/components/advance-invoices/list/locales/sl.ts +6 -0
  26. package/src/components/credit-notes/create/create-credit-note-form.tsx +114 -3
  27. package/src/components/credit-notes/create/locales/de.ts +2 -0
  28. package/src/components/credit-notes/create/locales/es.ts +2 -0
  29. package/src/components/credit-notes/create/locales/fr.ts +2 -0
  30. package/src/components/credit-notes/create/locales/hr.ts +1 -0
  31. package/src/components/credit-notes/create/locales/it.ts +2 -0
  32. package/src/components/credit-notes/create/locales/nl.ts +2 -0
  33. package/src/components/credit-notes/create/locales/pl.ts +1 -0
  34. package/src/components/credit-notes/create/locales/pt.ts +1 -0
  35. package/src/components/credit-notes/create/locales/sl.ts +1 -0
  36. package/src/components/credit-notes/credit-notes.hooks.ts +30 -0
  37. package/src/components/credit-notes/list/list-table.tsx +111 -36
  38. package/src/components/credit-notes/list/locales/de.ts +6 -1
  39. package/src/components/credit-notes/list/locales/en.ts +6 -0
  40. package/src/components/credit-notes/list/locales/es.ts +6 -1
  41. package/src/components/credit-notes/list/locales/fr.ts +6 -1
  42. package/src/components/credit-notes/list/locales/hr.ts +6 -1
  43. package/src/components/credit-notes/list/locales/it.ts +6 -1
  44. package/src/components/credit-notes/list/locales/nl.ts +6 -1
  45. package/src/components/credit-notes/list/locales/pl.ts +6 -1
  46. package/src/components/credit-notes/list/locales/pt.ts +6 -1
  47. package/src/components/credit-notes/list/locales/sl.ts +6 -1
  48. package/src/components/customers/customer-list-table/customer-list-table.tsx +0 -3
  49. package/src/components/customers/customer-list-table/locales/de.ts +1 -0
  50. package/src/components/customers/customer-list-table/locales/es.ts +1 -0
  51. package/src/components/customers/customer-list-table/locales/fr.ts +1 -0
  52. package/src/components/customers/customer-list-table/locales/hr.ts +1 -0
  53. package/src/components/customers/customer-list-table/locales/it.ts +1 -0
  54. package/src/components/customers/customer-list-table/locales/nl.ts +1 -0
  55. package/src/components/customers/customer-list-table/locales/pl.ts +1 -0
  56. package/src/components/customers/customer-list-table/locales/pt.ts +1 -0
  57. package/src/components/customers/customer-list-table/locales/sl.ts +1 -0
  58. package/src/components/dashboard/collection-rate-card/use-collection-rate.ts +2 -2
  59. package/src/components/dashboard/invoice-status-chart/use-invoice-status.ts +3 -3
  60. package/src/components/dashboard/payment-methods-chart/use-payment-methods.ts +1 -1
  61. package/src/components/dashboard/payment-trend-chart/use-payment-trend.ts +1 -1
  62. package/src/components/dashboard/revenue-trend-chart/use-revenue-trend.ts +1 -1
  63. package/src/components/dashboard/shared/use-revenue-data.ts +4 -4
  64. package/src/components/dashboard/shared/use-stats-counts.ts +4 -4
  65. package/src/components/dashboard/shared/use-stats-query.ts +1 -1
  66. package/src/components/dashboard/tax-collected-card/use-tax-collected.ts +2 -2
  67. package/src/components/dashboard/top-customers-chart/use-top-customers.ts +1 -1
  68. package/src/components/delivery-notes/create/create-delivery-note-form.tsx +332 -0
  69. package/src/components/delivery-notes/create/locales/de.ts +50 -0
  70. package/src/components/delivery-notes/create/locales/es.ts +49 -0
  71. package/src/components/delivery-notes/create/locales/fr.ts +50 -0
  72. package/src/components/delivery-notes/create/locales/hr.ts +49 -0
  73. package/src/components/delivery-notes/create/locales/it.ts +49 -0
  74. package/src/components/delivery-notes/create/locales/nl.ts +50 -0
  75. package/src/components/delivery-notes/create/locales/pl.ts +49 -0
  76. package/src/components/delivery-notes/create/locales/pt.ts +50 -0
  77. package/src/components/delivery-notes/create/locales/sl.ts +49 -0
  78. package/src/components/delivery-notes/create/prepare-delivery-note-submission.ts +38 -0
  79. package/src/components/delivery-notes/create/use-delivery-note-customer-form.ts +1 -0
  80. package/src/components/delivery-notes/delivery-notes.hooks.ts +15 -0
  81. package/src/components/delivery-notes/list/index.ts +3 -0
  82. package/src/components/delivery-notes/list/list-row-actions.tsx +122 -0
  83. package/src/components/delivery-notes/list/list-table.tsx +247 -0
  84. package/src/components/delivery-notes/list/locales/de.ts +13 -0
  85. package/src/components/delivery-notes/list/locales/en.ts +13 -0
  86. package/src/components/delivery-notes/list/locales/es.ts +13 -0
  87. package/src/components/delivery-notes/list/locales/fr.ts +13 -0
  88. package/src/components/delivery-notes/list/locales/hr.ts +13 -0
  89. package/src/components/delivery-notes/list/locales/it.ts +13 -0
  90. package/src/components/delivery-notes/list/locales/nl.ts +13 -0
  91. package/src/components/delivery-notes/list/locales/pl.ts +13 -0
  92. package/src/components/delivery-notes/list/locales/pt.ts +13 -0
  93. package/src/components/delivery-notes/list/locales/sl.ts +13 -0
  94. package/src/components/delivery-notes/list/use-delivery-note-download.ts +63 -0
  95. package/src/components/documents/create/document-details-section.tsx +76 -58
  96. package/src/components/documents/create/linked-documents-info.tsx +82 -0
  97. package/src/components/documents/create/live-preview.tsx +38 -11
  98. package/src/components/documents/create/prepare-document-submission.ts +1 -1
  99. package/src/components/documents/documents.hooks.ts +2 -1
  100. package/src/components/documents/shared/document-preview-display.tsx +12 -5
  101. package/src/components/documents/types.ts +12 -3
  102. package/src/components/documents/view/document-activities-list.tsx +65 -47
  103. package/src/components/documents/view/document-details-card.tsx +102 -77
  104. package/src/components/documents/view/document-payments-list.tsx +102 -68
  105. package/src/components/documents/view/document-relations-list.tsx +120 -0
  106. package/src/components/documents/view/document-sidebar.tsx +151 -0
  107. package/src/components/documents/view/index.ts +2 -0
  108. package/src/components/documents/view/locales/de.ts +23 -0
  109. package/src/components/documents/view/locales/es.ts +23 -0
  110. package/src/components/documents/view/locales/fr.ts +23 -0
  111. package/src/components/documents/view/locales/hr.ts +23 -0
  112. package/src/components/documents/view/locales/it.ts +23 -0
  113. package/src/components/documents/view/locales/nl.ts +23 -0
  114. package/src/components/documents/view/locales/pl.ts +23 -0
  115. package/src/components/documents/view/locales/pt.ts +23 -0
  116. package/src/components/documents/view/locales/sl.ts +23 -0
  117. package/src/components/documents/view/use-document-download.ts +8 -5
  118. package/src/components/entities/create-entity-form.tsx +165 -13
  119. package/src/components/entities/entity-settings-form/entity-settings-form.tsx +101 -1
  120. package/src/components/entities/entity-settings-form/locales/de.ts +9 -0
  121. package/src/components/entities/entity-settings-form/locales/es.ts +9 -0
  122. package/src/components/entities/entity-settings-form/locales/fr.ts +9 -0
  123. package/src/components/entities/entity-settings-form/locales/hr.ts +9 -0
  124. package/src/components/entities/entity-settings-form/locales/it.ts +9 -0
  125. package/src/components/entities/entity-settings-form/locales/nl.ts +9 -0
  126. package/src/components/entities/entity-settings-form/locales/pl.ts +9 -0
  127. package/src/components/entities/entity-settings-form/locales/pt.ts +9 -0
  128. package/src/components/entities/entity-settings-form/locales/sl.ts +9 -0
  129. package/src/components/entities/fina-settings-form/fina-settings-form.tsx +83 -71
  130. package/src/components/entities/fina-settings-form/fina-settings.hooks.ts +7 -2
  131. package/src/components/entities/fina-settings-form/locales/de.ts +2 -2
  132. package/src/components/entities/fina-settings-form/locales/en.ts +2 -2
  133. package/src/components/entities/fina-settings-form/locales/es.ts +2 -2
  134. package/src/components/entities/fina-settings-form/locales/fr.ts +2 -2
  135. package/src/components/entities/fina-settings-form/locales/hr.ts +2 -2
  136. package/src/components/entities/fina-settings-form/locales/it.ts +2 -2
  137. package/src/components/entities/fina-settings-form/locales/nl.ts +2 -2
  138. package/src/components/entities/fina-settings-form/locales/pl.ts +2 -2
  139. package/src/components/entities/fina-settings-form/locales/pt.ts +2 -2
  140. package/src/components/entities/fina-settings-form/locales/sl.ts +2 -2
  141. package/src/components/entities/furs-settings-form/furs-settings-form.tsx +10 -1
  142. package/src/components/entities/furs-settings-form/furs-settings.hooks.ts +7 -2
  143. package/src/components/entities/furs-settings-form/locales/en.ts +0 -1
  144. package/src/components/entities/furs-settings-form/sections/general-settings-section.tsx +12 -4
  145. package/src/components/entities/settings/pdf-template-selector/locales/de.ts +3 -1
  146. package/src/components/entities/settings/pdf-template-selector/locales/es.ts +3 -1
  147. package/src/components/entities/settings/pdf-template-selector/locales/fr.ts +4 -1
  148. package/src/components/entities/settings/pdf-template-selector/locales/hr.ts +4 -1
  149. package/src/components/entities/settings/pdf-template-selector/locales/it.ts +3 -1
  150. package/src/components/entities/settings/pdf-template-selector/locales/nl.ts +3 -1
  151. package/src/components/entities/settings/pdf-template-selector/locales/pl.ts +3 -1
  152. package/src/components/entities/settings/pdf-template-selector/locales/pt.ts +3 -1
  153. package/src/components/entities/settings/pdf-template-selector/locales/sl.ts +3 -1
  154. package/src/components/entities/settings/pdf-template-selector/pdf-template-cards.tsx +1 -0
  155. package/src/components/estimates/create/create-estimate-form.tsx +29 -2
  156. package/src/components/estimates/list/list-table.tsx +3 -6
  157. package/src/components/estimates/list/locales/de.ts +1 -0
  158. package/src/components/estimates/list/locales/es.ts +1 -0
  159. package/src/components/estimates/list/locales/fr.ts +1 -0
  160. package/src/components/estimates/list/locales/hr.ts +1 -0
  161. package/src/components/estimates/list/locales/it.ts +1 -0
  162. package/src/components/estimates/list/locales/nl.ts +1 -0
  163. package/src/components/estimates/list/locales/pl.ts +1 -0
  164. package/src/components/estimates/list/locales/pt.ts +1 -0
  165. package/src/components/estimates/list/locales/sl.ts +1 -0
  166. package/src/components/export/document-export-form.tsx +9 -2
  167. package/src/components/export/index.ts +2 -0
  168. package/src/components/export/sales-per-item-export-form.tsx +223 -0
  169. package/src/components/invoices/create/create-invoice-form.tsx +48 -1
  170. package/src/components/invoices/create/locales/de.ts +11 -0
  171. package/src/components/invoices/create/locales/es.ts +11 -0
  172. package/src/components/invoices/create/locales/fr.ts +11 -0
  173. package/src/components/invoices/create/locales/hr.ts +10 -0
  174. package/src/components/invoices/create/locales/it.ts +11 -0
  175. package/src/components/invoices/create/locales/nl.ts +11 -0
  176. package/src/components/invoices/create/locales/pl.ts +10 -0
  177. package/src/components/invoices/create/locales/pt.ts +10 -0
  178. package/src/components/invoices/create/locales/sl.ts +10 -0
  179. package/src/components/invoices/invoices-furs.hooks.ts +27 -9
  180. package/src/components/invoices/list/list-row-actions.tsx +3 -3
  181. package/src/components/invoices/list/list-table.tsx +132 -21
  182. package/src/components/invoices/list/locales/de.ts +6 -0
  183. package/src/components/invoices/list/locales/en.ts +5 -0
  184. package/src/components/invoices/list/locales/es.ts +6 -0
  185. package/src/components/invoices/list/locales/fr.ts +6 -0
  186. package/src/components/invoices/list/locales/hr.ts +6 -0
  187. package/src/components/invoices/list/locales/it.ts +6 -0
  188. package/src/components/invoices/list/locales/nl.ts +6 -0
  189. package/src/components/invoices/list/locales/pl.ts +6 -0
  190. package/src/components/invoices/list/locales/pt.ts +6 -0
  191. package/src/components/invoices/list/locales/sl.ts +6 -0
  192. package/src/components/invoices/view/fiscalization-status-card.tsx +42 -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-row-actions.tsx +3 -2
  196. package/src/components/items/item-list-table/item-list-row.tsx +3 -2
  197. package/src/components/items/item-list-table/item-list-table.tsx +3 -3
  198. package/src/components/items/item-list-table/locales/de.ts +1 -0
  199. package/src/components/items/item-list-table/locales/es.ts +1 -0
  200. package/src/components/items/item-list-table/locales/fr.ts +1 -0
  201. package/src/components/items/item-list-table/locales/hr.ts +1 -0
  202. package/src/components/items/item-list-table/locales/it.ts +1 -0
  203. package/src/components/items/item-list-table/locales/nl.ts +1 -0
  204. package/src/components/items/item-list-table/locales/pl.ts +1 -0
  205. package/src/components/items/item-list-table/locales/pt.ts +1 -0
  206. package/src/components/items/item-list-table/locales/sl.ts +1 -0
  207. package/src/components/payments/list/list-table.tsx +0 -4
  208. package/src/components/payments/list/locales/de.ts +1 -0
  209. package/src/components/payments/list/locales/es.ts +1 -0
  210. package/src/components/payments/list/locales/fr.ts +1 -0
  211. package/src/components/payments/list/locales/hr.ts +1 -0
  212. package/src/components/payments/list/locales/it.ts +1 -0
  213. package/src/components/payments/list/locales/nl.ts +1 -0
  214. package/src/components/payments/list/locales/pl.ts +1 -0
  215. package/src/components/payments/list/locales/pt.ts +1 -0
  216. package/src/components/payments/list/locales/sl.ts +1 -0
  217. package/src/components/recurring-invoices/list/list-table.tsx +0 -7
  218. package/src/components/recurring-invoices/list/locales/de.ts +1 -0
  219. package/src/components/recurring-invoices/list/locales/es.ts +1 -0
  220. package/src/components/recurring-invoices/list/locales/fr.ts +1 -0
  221. package/src/components/recurring-invoices/list/locales/hr.ts +1 -0
  222. package/src/components/recurring-invoices/list/locales/it.ts +1 -0
  223. package/src/components/recurring-invoices/list/locales/nl.ts +1 -0
  224. package/src/components/recurring-invoices/list/locales/pl.ts +1 -0
  225. package/src/components/recurring-invoices/list/locales/pt.ts +1 -0
  226. package/src/components/recurring-invoices/list/locales/sl.ts +1 -0
  227. package/src/components/request-logs/request-log-list-table.tsx +0 -3
  228. package/src/components/table/README.md +14 -121
  229. package/src/components/table/data-table.tsx +22 -37
  230. package/src/components/table/hooks/use-table-state.ts +3 -27
  231. package/src/components/table/index.ts +0 -2
  232. package/src/components/table/selection-toolbar.tsx +35 -1
  233. package/src/components/table/table-empty-state.tsx +6 -3
  234. package/src/components/table/table-no-results.tsx +10 -5
  235. package/src/components/table/types.ts +0 -5
  236. package/src/components/taxes/tax-list-table/locales/de.ts +1 -0
  237. package/src/components/taxes/tax-list-table/locales/es.ts +1 -0
  238. package/src/components/taxes/tax-list-table/locales/fr.ts +1 -0
  239. package/src/components/taxes/tax-list-table/locales/hr.ts +1 -0
  240. package/src/components/taxes/tax-list-table/locales/it.ts +1 -0
  241. package/src/components/taxes/tax-list-table/locales/nl.ts +1 -0
  242. package/src/components/taxes/tax-list-table/locales/pl.ts +1 -0
  243. package/src/components/taxes/tax-list-table/locales/pt.ts +1 -0
  244. package/src/components/taxes/tax-list-table/locales/sl.ts +1 -0
  245. package/src/components/taxes/tax-list-table/tax-list-header.tsx +3 -14
  246. package/src/components/taxes/tax-list-table/tax-list-table.tsx +3 -3
  247. package/src/components/ui/popover.tsx +3 -1
  248. package/src/components/ui/tooltip.tsx +3 -1
  249. package/src/generated/schemas/deliverynote.ts +134 -0
  250. package/src/generated/schemas/entity.ts +4 -0
  251. package/src/generated/schemas/index.ts +3 -0
  252. package/src/generated/schemas/order.ts +5 -3
  253. package/src/generated/schemas/payment.ts +22 -2
  254. package/src/generated/schemas/renderadvanceinvoicepreview_body.ts +1 -0
  255. package/src/generated/schemas/rendercreditnotepreview_body.ts +1 -0
  256. package/src/generated/schemas/renderdeliverynotepreview_body.ts +185 -0
  257. package/src/generated/schemas/renderestimatepreview_body.ts +1 -0
  258. package/src/generated/schemas/renderinvoicepreview_body.ts +1 -0
  259. package/src/generated/schemas/startpdfexport_body.ts +18 -2
  260. package/src/generated/schemas/userfinasettings.ts +19 -0
  261. package/src/generated/schemas/webhook.ts +12 -0
  262. package/src/hooks/use-duplicate-document.ts +49 -6
  263. package/src/hooks/use-next-document-number.ts +2 -2
  264. package/src/lib/fiscalization.ts +12 -0
  265. package/src/lib/schemas/advance-invoice.ts +0 -1
  266. package/src/providers/sdk-provider.tsx +5 -7
  267. package/src/components/table/sortable-header.tsx +0 -56
@@ -37,6 +37,12 @@ import sl from "./locales/sl";
37
37
  import { prepareEstimateSubmission } from "./prepare-estimate-submission";
38
38
  import { useEstimateCustomerForm } from "./use-estimate-customer-form";
39
39
 
40
+ function calculateDueDate(dateIso: string, days: number): string {
41
+ const date = new Date(dateIso);
42
+ date.setDate(date.getDate() + days);
43
+ return date.toISOString();
44
+ }
45
+
40
46
  const translations = {
41
47
  sl,
42
48
  de,
@@ -101,6 +107,7 @@ export default function CreateEstimateForm({
101
107
 
102
108
  // Get default estimate note from entity settings
103
109
  const defaultEstimateNote = (activeEntity?.settings as any)?.default_estimate_note || "";
110
+ const defaultEstimateValidDays = (activeEntity?.settings as any)?.default_estimate_valid_days ?? 30;
104
111
 
105
112
  // Fetch next estimate number
106
113
  const { data: nextNumberData } = useNextDocumentNumber(entityId, "estimate", {
@@ -139,6 +146,9 @@ export default function CreateEstimateForm({
139
146
  currency_code: initialValues?.currency_code || activeEntity?.currency_code || "EUR",
140
147
  note: initialValues?.note ?? defaultEstimateNote,
141
148
  payment_terms: initialValues?.payment_terms ?? defaultPaymentTerms,
149
+ date_valid_till:
150
+ initialValues?.date_valid_till ||
151
+ calculateDueDate(initialValues?.date || new Date().toISOString(), defaultEstimateValidDays),
142
152
  },
143
153
  });
144
154
 
@@ -165,13 +175,20 @@ export default function CreateEstimateForm({
165
175
  }
166
176
  }, [nextNumberData?.number, form]);
167
177
 
168
- // Update default note when entity loads
178
+ // Update default note and valid-till date when entity loads
169
179
  useEffect(() => {
170
180
  const entityDefaultNote = (activeEntity?.settings as any)?.default_estimate_note;
171
181
  if (entityDefaultNote && !form.getValues("note")) {
172
182
  form.setValue("note", entityDefaultNote);
173
183
  }
174
- }, [activeEntity, form]);
184
+ if (!initialValues?.date_valid_till) {
185
+ const validDays = (activeEntity?.settings as any)?.default_estimate_valid_days ?? 30;
186
+ const currentDate = form.getValues("date");
187
+ if (currentDate) {
188
+ form.setValue("date_valid_till", calculateDueDate(currentDate, validDays));
189
+ }
190
+ }
191
+ }, [activeEntity, form, initialValues?.date_valid_till]);
175
192
 
176
193
  // Auto-add tax field for tax subject entities
177
194
  useEffect(() => {
@@ -300,6 +317,16 @@ export default function CreateEstimateForm({
300
317
  }
301
318
  }, [activeEntity, form]);
302
319
 
320
+ // Recalculate valid-till date when document date changes
321
+ const prevDateRef = useRef(form.getValues("date"));
322
+ useEffect(() => {
323
+ const currentDate = formValues.date;
324
+ if (!currentDate || currentDate === prevDateRef.current) return;
325
+ prevDateRef.current = currentDate;
326
+ const validDays = (activeEntity?.settings as any)?.default_estimate_valid_days ?? 30;
327
+ form.setValue("date_valid_till", calculateDueDate(currentDate, validDays));
328
+ }, [formValues.date, activeEntity, form]);
329
+
303
330
  useEffect(() => {
304
331
  const callback = onChangeRef.current;
305
332
  if (!callback) return;
@@ -52,6 +52,7 @@ type EstimateListTableProps = {
52
52
  onDownloadSuccess?: (fileName: string) => void;
53
53
  onDownloadError?: (error: string) => void;
54
54
  onExportSelected?: (documentIds: string[]) => void;
55
+ onCreateNew?: () => void;
55
56
  } & ListTableProps<Estimate>;
56
57
 
57
58
  export default function EstimateListTable({
@@ -65,6 +66,7 @@ export default function EstimateListTable({
65
66
  onDownloadSuccess,
66
67
  onDownloadError,
67
68
  onExportSelected,
69
+ onCreateNew,
68
70
  ...i18nProps
69
71
  }: EstimateListTableProps) {
70
72
  const t = createTranslation({
@@ -84,7 +86,6 @@ export default function EstimateListTable({
84
86
  limit: params.limit,
85
87
  next_cursor: params.next_cursor,
86
88
  prev_cursor: params.prev_cursor,
87
- order_by: params.order_by,
88
89
  search: params.search,
89
90
  query: params.query,
90
91
  });
@@ -130,7 +131,6 @@ export default function EstimateListTable({
130
131
  {
131
132
  id: "number",
132
133
  header: t("Number"),
133
- sortable: true,
134
134
  cell: (estimate) => (
135
135
  <div className="flex items-center gap-2">
136
136
  <Button variant="link" className="cursor-pointer py-0 underline" onClick={() => onRowClick?.(estimate)}>
@@ -155,26 +155,22 @@ export default function EstimateListTable({
155
155
  {
156
156
  id: "date",
157
157
  header: t("Date"),
158
- sortable: true,
159
158
  cell: (estimate) => <FormattedDate date={estimate.date} />,
160
159
  },
161
160
  {
162
161
  id: "date_valid_till",
163
162
  header: t("Valid Until"),
164
- sortable: true,
165
163
  cell: (estimate) => <FormattedDate date={estimate.date_valid_till} />,
166
164
  },
167
165
  {
168
166
  id: "total",
169
167
  header: t("Total"),
170
- sortable: true,
171
168
  align: "right",
172
169
  cell: (estimate) => estimate.total,
173
170
  },
174
171
  {
175
172
  id: "total_with_tax",
176
173
  header: t("Total with Tax"),
177
- sortable: true,
178
174
  align: "right",
179
175
  cell: (estimate) => estimate.total_with_tax,
180
176
  },
@@ -208,6 +204,7 @@ export default function EstimateListTable({
208
204
  cacheKey="estimates"
209
205
  resourceName="estimate"
210
206
  createNewLink={entityId ? `/app/${entityId}/documents/add/estimate` : undefined}
207
+ onCreateNew={onCreateNew}
211
208
  entityId={entityId}
212
209
  filterConfig={filterConfig}
213
210
  t={t}
@@ -32,6 +32,7 @@ export default {
32
32
  "No results found": "Keine Angebote gefunden",
33
33
  "Try adjusting your search criteria": "Versuchen Sie, Ihre Suchkriterien anzupassen",
34
34
  "Clear search": "Suche zurücksetzen",
35
+ "Clear all": "Alles zurücksetzen",
35
36
  selected: "ausgewählt",
36
37
  "Export PDFs": "PDFs exportieren",
37
38
  "Deselect all": "Auswahl aufheben",
@@ -29,6 +29,7 @@ export default {
29
29
  "No results found": "No se encontraron presupuestos",
30
30
  "Try adjusting your search criteria": "Intente ajustar sus criterios de búsqueda",
31
31
  "Clear search": "Limpiar búsqueda",
32
+ "Clear all": "Borrar todo",
32
33
  selected: "seleccionados",
33
34
  "Export PDFs": "Exportar PDFs",
34
35
  "Deselect all": "Deseleccionar todo",
@@ -29,6 +29,7 @@ export default {
29
29
  "No results found": "Aucun devis trouvé",
30
30
  "Try adjusting your search criteria": "Essayez d'ajuster vos critères de recherche",
31
31
  "Clear search": "Effacer la recherche",
32
+ "Clear all": "Tout effacer",
32
33
  selected: "sélectionnés",
33
34
  "Export PDFs": "Exporter les PDF",
34
35
  "Deselect all": "Tout désélectionner",
@@ -29,6 +29,7 @@ export default {
29
29
  "No results found": "Nisu pronađeni predračuni",
30
30
  "Try adjusting your search criteria": "Pokušajte prilagoditi kriterije pretraživanja",
31
31
  "Clear search": "Očisti pretraživanje",
32
+ "Clear all": "Očisti sve",
32
33
  selected: "odabranih",
33
34
  "Export PDFs": "Izvezi PDF-ove",
34
35
  "Deselect all": "Poništi odabir",
@@ -29,6 +29,7 @@ export default {
29
29
  "No results found": "Nessun preventivo trovato",
30
30
  "Try adjusting your search criteria": "Prova a modificare i criteri di ricerca",
31
31
  "Clear search": "Cancella ricerca",
32
+ "Clear all": "Cancella tutto",
32
33
  selected: "selezionati",
33
34
  "Export PDFs": "Esporta PDF",
34
35
  "Deselect all": "Deseleziona tutto",
@@ -29,6 +29,7 @@ export default {
29
29
  "No results found": "Geen offertes gevonden",
30
30
  "Try adjusting your search criteria": "Probeer uw zoekcriteria aan te passen",
31
31
  "Clear search": "Zoekopdracht wissen",
32
+ "Clear all": "Alles wissen",
32
33
  selected: "geselecteerd",
33
34
  "Export PDFs": "PDFs exporteren",
34
35
  "Deselect all": "Alles deselecteren",
@@ -29,6 +29,7 @@ export default {
29
29
  "No results found": "Nie znaleziono kosztorysów",
30
30
  "Try adjusting your search criteria": "Spróbuj dostosować kryteria wyszukiwania",
31
31
  "Clear search": "Wyczyść wyszukiwanie",
32
+ "Clear all": "Wyczyść wszystko",
32
33
  selected: "wybranych",
33
34
  "Export PDFs": "Eksportuj PDF-y",
34
35
  "Deselect all": "Odznacz wszystko",
@@ -29,6 +29,7 @@ export default {
29
29
  "No results found": "Nenhum orçamento encontrado",
30
30
  "Try adjusting your search criteria": "Tente ajustar os seus critérios de pesquisa",
31
31
  "Clear search": "Limpar pesquisa",
32
+ "Clear all": "Limpar tudo",
32
33
  selected: "selecionados",
33
34
  "Export PDFs": "Exportar PDFs",
34
35
  "Deselect all": "Desselecionar tudo",
@@ -32,6 +32,7 @@ export default {
32
32
  "No results found": "Ni najdenih predračunov",
33
33
  "Try adjusting your search criteria": "Poskusite prilagoditi iskalne kriterije",
34
34
  "Clear search": "Počisti iskanje",
35
+ "Clear all": "Počisti vse",
35
36
  selected: "izbranih",
36
37
  "Export PDFs": "Izvozi PDF-je",
37
38
  "Deselect all": "Počisti izbiro",
@@ -40,8 +40,11 @@ function isDateRangeValid(dateFrom: string, dateTo: string): boolean {
40
40
  export type DocumentExportFormProps = {
41
41
  entityId: string;
42
42
  token: string;
43
+ accountId?: string | null;
43
44
  language: string;
44
45
  t: TFunction;
46
+ /** Base URL for API calls (required in embed context where relative paths don't reach the API) */
47
+ apiBaseUrl?: string;
45
48
  onSuccess?: (fileName: string) => void;
46
49
  onError?: (error: Error) => void;
47
50
  onPdfExportStarted?: (jobId: string) => void;
@@ -51,8 +54,10 @@ export type DocumentExportFormProps = {
51
54
  export function DocumentExportForm({
52
55
  entityId,
53
56
  token,
57
+ accountId,
54
58
  language,
55
59
  t,
60
+ apiBaseUrl = "",
56
61
  onSuccess,
57
62
  onError,
58
63
  onPdfExportStarted,
@@ -86,11 +91,12 @@ export function DocumentExportForm({
86
91
  // PDF export is async - different flow
87
92
  if (exportFormat === "pdf_zip") {
88
93
  try {
89
- const response = await fetch("/documents/export/pdf", {
94
+ const response = await fetch(`${apiBaseUrl}/documents/export/pdf`, {
90
95
  method: "POST",
91
96
  headers: {
92
97
  Authorization: `Bearer ${token}`,
93
98
  "x-entity-id": entityId,
99
+ ...(accountId && { "x-account-id": accountId }),
94
100
  "Content-Type": "application/json",
95
101
  },
96
102
  body: JSON.stringify({
@@ -132,10 +138,11 @@ export function DocumentExportForm({
132
138
  queryParams.date_to = dateTo;
133
139
  }
134
140
 
135
- const response = await fetch(`/documents/export?${new URLSearchParams(queryParams).toString()}`, {
141
+ const response = await fetch(`${apiBaseUrl}/documents/export?${new URLSearchParams(queryParams).toString()}`, {
136
142
  headers: {
137
143
  Authorization: `Bearer ${token}`,
138
144
  "x-entity-id": entityId,
145
+ ...(accountId && { "x-account-id": accountId }),
139
146
  },
140
147
  });
141
148
 
@@ -1,2 +1,4 @@
1
1
  export type { DocumentExportFormProps, DocumentType, ExportFormat } from "./document-export-form";
2
2
  export { DocumentExportForm } from "./document-export-form";
3
+ export type { SalesPerItemExportFormProps } from "./sales-per-item-export-form";
4
+ export { SalesPerItemExportForm } from "./sales-per-item-export-form";
@@ -0,0 +1,223 @@
1
+ type TFunction = (key: string, options?: Record<string, unknown>) => string;
2
+
3
+ import { Calendar, Download, Loader2 } from "lucide-react";
4
+ import { useState } from "react";
5
+ import { Button } from "../ui/button";
6
+ import { Input } from "../ui/input";
7
+ import { Label } from "../ui/label";
8
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select";
9
+
10
+ type ExportFormat = "xlsx" | "csv";
11
+
12
+ // Maximum date range for export (1 year in milliseconds)
13
+ const MAX_DATE_RANGE_MS = 365 * 24 * 60 * 60 * 1000;
14
+
15
+ function formatDateLocal(date: Date): string {
16
+ const year = date.getFullYear();
17
+ const month = String(date.getMonth() + 1).padStart(2, "0");
18
+ const day = String(date.getDate()).padStart(2, "0");
19
+ return `${year}-${month}-${day}`;
20
+ }
21
+
22
+ function getPreviousMonthRange(): { from: string; to: string } {
23
+ const now = new Date();
24
+ const firstDayPrevMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
25
+ const lastDayPrevMonth = new Date(now.getFullYear(), now.getMonth(), 0);
26
+ return {
27
+ from: formatDateLocal(firstDayPrevMonth),
28
+ to: formatDateLocal(lastDayPrevMonth),
29
+ };
30
+ }
31
+
32
+ function isDateRangeValid(dateFrom: string, dateTo: string): boolean {
33
+ if (!dateFrom || !dateTo) return false;
34
+ const from = new Date(dateFrom);
35
+ const to = new Date(dateTo);
36
+ return to.getTime() - from.getTime() <= MAX_DATE_RANGE_MS && to >= from;
37
+ }
38
+
39
+ export type SalesPerItemExportFormProps = {
40
+ entityId: string;
41
+ token: string;
42
+ accountId?: string | null;
43
+ language: string;
44
+ t: TFunction;
45
+ /** Base URL for API calls (required in embed context where relative paths don't reach the API) */
46
+ apiBaseUrl?: string;
47
+ onSuccess?: (fileName: string) => void;
48
+ onError?: (error: Error) => void;
49
+ };
50
+
51
+ export function SalesPerItemExportForm({
52
+ entityId,
53
+ token,
54
+ accountId,
55
+ language,
56
+ t,
57
+ apiBaseUrl = "",
58
+ onSuccess,
59
+ onError,
60
+ }: SalesPerItemExportFormProps) {
61
+ const defaultDates = getPreviousMonthRange();
62
+ const [exportFormat, setExportFormat] = useState<ExportFormat>("xlsx");
63
+ const [dateFrom, setDateFrom] = useState(defaultDates.from);
64
+ const [dateTo, setDateTo] = useState(defaultDates.to);
65
+ const [isExporting, setIsExporting] = useState(false);
66
+ const [dateRangeError, setDateRangeError] = useState(false);
67
+
68
+ const validateDateRange = (from: string, to: string) => {
69
+ const isValid = isDateRangeValid(from, to);
70
+ setDateRangeError(!isValid && !!from && !!to);
71
+ return isValid;
72
+ };
73
+
74
+ const handleExport = async () => {
75
+ if (!dateFrom || !dateTo) {
76
+ onError?.(new Error(t("sales-per-item-export.error.dates-required")));
77
+ return;
78
+ }
79
+
80
+ if (!validateDateRange(dateFrom, dateTo)) {
81
+ onError?.(new Error(t("export-page.error.date-range-exceeded")));
82
+ return;
83
+ }
84
+
85
+ setIsExporting(true);
86
+
87
+ try {
88
+ const exportLanguage = language === "sl" ? "sl" : "en";
89
+ const queryParams: Record<string, string> = {
90
+ format: exportFormat,
91
+ date_from: dateFrom,
92
+ date_to: dateTo,
93
+ language: exportLanguage,
94
+ };
95
+
96
+ const response = await fetch(
97
+ `${apiBaseUrl}/documents/export/sales-per-item?${new URLSearchParams(queryParams).toString()}`,
98
+ {
99
+ headers: {
100
+ Authorization: `Bearer ${token}`,
101
+ "x-entity-id": entityId,
102
+ ...(accountId && { "x-account-id": accountId }),
103
+ },
104
+ },
105
+ );
106
+
107
+ if (!response.ok) {
108
+ throw new Error(`Export failed: ${response.statusText}`);
109
+ }
110
+
111
+ const contentDisposition = response.headers.get("content-disposition");
112
+ let fileName = `sales-per-item.${exportFormat}`;
113
+ if (contentDisposition) {
114
+ const match = contentDisposition.match(/filename="?([^";\n]+)"?/);
115
+ if (match) {
116
+ fileName = match[1];
117
+ }
118
+ }
119
+
120
+ const blob = await response.blob();
121
+ const downloadUrl = window.URL.createObjectURL(blob);
122
+ const link = document.createElement("a");
123
+ link.href = downloadUrl;
124
+ link.download = fileName;
125
+ document.body.appendChild(link);
126
+ link.click();
127
+ setTimeout(() => {
128
+ document.body.removeChild(link);
129
+ window.URL.revokeObjectURL(downloadUrl);
130
+ }, 1000);
131
+
132
+ onSuccess?.(fileName);
133
+ } catch (error) {
134
+ onError?.(error instanceof Error ? error : new Error("Unknown error"));
135
+ } finally {
136
+ setIsExporting(false);
137
+ }
138
+ };
139
+
140
+ const datesProvided = !!dateFrom && !!dateTo;
141
+
142
+ return (
143
+ <div className="space-y-6">
144
+ {/* Export Format */}
145
+ <div className="grid grid-cols-2 gap-4">
146
+ <div className="space-y-2">
147
+ <Label htmlFor="sales-export-format">{t("export-page.format")}</Label>
148
+ <Select value={exportFormat} onValueChange={(v) => setExportFormat(v as ExportFormat)}>
149
+ <SelectTrigger id="sales-export-format">
150
+ <SelectValue />
151
+ </SelectTrigger>
152
+ <SelectContent>
153
+ <SelectItem value="xlsx">{t("export-page.formats.xlsx")}</SelectItem>
154
+ <SelectItem value="csv">{t("export-page.formats.csv")}</SelectItem>
155
+ </SelectContent>
156
+ </Select>
157
+ </div>
158
+ </div>
159
+
160
+ {/* Date Range */}
161
+ <div className="grid grid-cols-2 gap-4">
162
+ <div className="space-y-2">
163
+ <Label htmlFor="sales-date-from">{t("export-page.date-from")}</Label>
164
+ <div className="relative">
165
+ <Input
166
+ id="sales-date-from"
167
+ type="date"
168
+ value={dateFrom}
169
+ onChange={(e) => {
170
+ setDateFrom(e.target.value);
171
+ if (dateTo) validateDateRange(e.target.value, dateTo);
172
+ }}
173
+ onClick={(e) => (e.target as HTMLInputElement).showPicker?.()}
174
+ className="cursor-pointer pr-9 [&::-webkit-calendar-picker-indicator]:hidden"
175
+ />
176
+ <Calendar className="pointer-events-none absolute top-1/2 right-2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
177
+ </div>
178
+ </div>
179
+
180
+ <div className="space-y-2">
181
+ <Label htmlFor="sales-date-to">{t("export-page.date-to")}</Label>
182
+ <div className="relative">
183
+ <Input
184
+ id="sales-date-to"
185
+ type="date"
186
+ value={dateTo}
187
+ onChange={(e) => {
188
+ setDateTo(e.target.value);
189
+ if (dateFrom) validateDateRange(dateFrom, e.target.value);
190
+ }}
191
+ onClick={(e) => (e.target as HTMLInputElement).showPicker?.()}
192
+ className={`cursor-pointer pr-9 [&::-webkit-calendar-picker-indicator]:hidden ${dateRangeError ? "border-destructive" : ""}`}
193
+ />
194
+ <Calendar className="pointer-events-none absolute top-1/2 right-2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
195
+ </div>
196
+ </div>
197
+ </div>
198
+
199
+ {/* Date range error message */}
200
+ {dateRangeError && <p className="text-destructive text-sm">{t("export-page.error.date-range-exceeded")}</p>}
201
+
202
+ {/* Export Button */}
203
+ <Button
204
+ onClick={handleExport}
205
+ disabled={isExporting || dateRangeError || !datesProvided}
206
+ className="w-full"
207
+ size="lg"
208
+ >
209
+ {isExporting ? (
210
+ <>
211
+ <Loader2 className="mr-2 h-4 w-4 animate-spin" />
212
+ {t("export-page.exporting")}
213
+ </>
214
+ ) : (
215
+ <>
216
+ <Download className="mr-2 h-4 w-4" />
217
+ {t("export-page.export-button")}
218
+ </>
219
+ )}
220
+ </Button>
221
+ </div>
222
+ );
223
+ }
@@ -27,6 +27,7 @@ import {
27
27
  } from "../../documents/create/document-details-section";
28
28
  import { DocumentItemsSection, type PriceModesMap } from "../../documents/create/document-items-section";
29
29
  import { DocumentRecipientSection } from "../../documents/create/document-recipient-section";
30
+ import { type LinkedDocumentSummary, LinkedDocumentsInfo } from "../../documents/create/linked-documents-info";
30
31
  import { MarkAsPaidSection } from "../../documents/create/mark-as-paid-section";
31
32
  import type { DocumentTypes } from "../../documents/types";
32
33
  import { useFinaPremises, useFinaSettings } from "../../entities/fina-settings-form/fina-settings.hooks";
@@ -53,6 +54,12 @@ import sl from "./locales/sl";
53
54
  import { prepareInvoiceSubmission } from "./prepare-invoice-submission";
54
55
  import { useInvoiceCustomerForm } from "./use-invoice-customer-form";
55
56
 
57
+ function calculateDueDate(dateIso: string, days: number): string {
58
+ const date = new Date(dateIso);
59
+ date.setDate(date.getDate() + days);
60
+ return date.toISOString();
61
+ }
62
+
56
63
  const translations = {
57
64
  sl,
58
65
  de,
@@ -83,6 +90,10 @@ type DocumentAddFormProps = {
83
90
  onHeaderActionChange?: (action: ReactNode) => void;
84
91
  /** Initial values for form fields (used for document duplication or editing) */
85
92
  initialValues?: Partial<CreateInvoiceRequest> & { number?: string };
93
+ /** Source documents linked to this invoice (e.g., delivery notes merged into this invoice) */
94
+ sourceDocuments?: LinkedDocumentSummary[];
95
+ /** Force linking documents even if an advance invoice is already applied to another invoice */
96
+ forceLinkedDocuments?: boolean;
86
97
  /** Mode: create (default) or edit */
87
98
  mode?: "create" | "edit";
88
99
  /** Document ID for edit mode */
@@ -98,6 +109,8 @@ export default function CreateInvoiceForm({
98
109
  onAddNewTax,
99
110
  onHeaderActionChange,
100
111
  initialValues,
112
+ sourceDocuments,
113
+ forceLinkedDocuments,
101
114
  mode = "create",
102
115
  documentId,
103
116
  t: translateProp,
@@ -118,6 +131,7 @@ export default function CreateInvoiceForm({
118
131
  // Get default invoice note and payment terms from entity settings
119
132
  const defaultInvoiceNote = (activeEntity?.settings as any)?.default_invoice_note || "";
120
133
  const defaultPaymentTerms = (activeEntity?.settings as any)?.default_invoice_payment_terms || "";
134
+ const defaultInvoiceDueDays = (activeEntity?.settings as any)?.default_invoice_due_days ?? 30;
121
135
 
122
136
  // ============================================================================
123
137
  // FURS Settings & Premises
@@ -327,7 +341,11 @@ export default function CreateInvoiceForm({
327
341
  currency_code: initialValues?.currency_code || activeEntity?.currency_code || "EUR",
328
342
  note: initialValues?.note ?? defaultInvoiceNote,
329
343
  payment_terms: initialValues?.payment_terms ?? defaultPaymentTerms,
344
+ date_due:
345
+ initialValues?.date_due ||
346
+ calculateDueDate(initialValues?.date || new Date().toISOString(), defaultInvoiceDueDays),
330
347
  date_service: new Date().toISOString(),
348
+ linked_documents: (initialValues as any)?.linked_documents,
331
349
  },
332
350
  });
333
351
 
@@ -630,6 +648,11 @@ export default function CreateInvoiceForm({
630
648
  isDraft,
631
649
  });
632
650
 
651
+ // Add force_linked_documents if set (used after conflict dialog approval)
652
+ if (forceLinkedDocuments) {
653
+ (payload as any).force_linked_documents = true;
654
+ }
655
+
633
656
  if (isEditMode && documentId) {
634
657
  // In edit mode, use updateInvoice
635
658
  // Remove number from payload as it's not editable
@@ -645,6 +668,7 @@ export default function CreateInvoiceForm({
645
668
  updateInvoice,
646
669
  documentId,
647
670
  eslogValidationEnabled,
671
+ forceLinkedDocuments,
648
672
  form,
649
673
  isEditMode,
650
674
  isEslogAvailable,
@@ -721,6 +745,15 @@ export default function CreateInvoiceForm({
721
745
  form.setValue("payment_terms", entityDefaultPaymentTerms);
722
746
  }
723
747
 
748
+ // Auto-populate due date from entity settings when entity loads async
749
+ if (!isEditMode && !initialValues?.date_due) {
750
+ const dueDays = (activeEntity.settings as any)?.default_invoice_due_days ?? 30;
751
+ const currentDate = form.getValues("date");
752
+ if (currentDate) {
753
+ form.setValue("date_due", calculateDueDate(currentDate, dueDays));
754
+ }
755
+ }
756
+
724
757
  // Auto-add tax field for tax subject entities
725
758
  if (activeEntity.is_tax_subject) {
726
759
  const items = form.getValues("items") || [];
@@ -730,7 +763,17 @@ export default function CreateInvoiceForm({
730
763
  }
731
764
 
732
765
  initialSetupDoneRef.current = true;
733
- }, [activeEntity, form]);
766
+ }, [activeEntity, form, isEditMode, initialValues?.date_due]);
767
+
768
+ // Recalculate due date when document date changes (skip in edit mode)
769
+ const prevDateRef = useRef(form.getValues("date"));
770
+ useEffect(() => {
771
+ if (isEditMode) return;
772
+ if (!watchedDate || watchedDate === prevDateRef.current) return;
773
+ prevDateRef.current = watchedDate;
774
+ const dueDays = (activeEntity?.settings as any)?.default_invoice_due_days ?? 30;
775
+ form.setValue("date_due", calculateDueDate(watchedDate, dueDays));
776
+ }, [watchedDate, activeEntity, isEditMode, form]);
734
777
 
735
778
  // Use form.watch subscription for onChange callback (avoids re-render loops)
736
779
  const prevPayloadRef = useRef<string>("");
@@ -962,6 +1005,10 @@ export default function CreateInvoiceForm({
962
1005
  customer: watchedCustomer as any,
963
1006
  }}
964
1007
  />
1008
+
1009
+ {sourceDocuments && sourceDocuments.length > 0 && (
1010
+ <LinkedDocumentsInfo documents={sourceDocuments} locale={locale || "en"} t={t} />
1011
+ )}
965
1012
  </form>
966
1013
  </Form>
967
1014
  );
@@ -109,6 +109,17 @@ export default {
109
109
  "Net price": "Nettopreis",
110
110
  "Gross price (tax included)": "Bruttopreis (inkl. MwSt.)",
111
111
  "Net price (before tax)": "Nettopreis (exkl. MwSt.)",
112
+ // Linked documents
113
+ "Linked documents": "Verknüpfte Dokumente",
114
+ Type: "Typ",
115
+ Total: "Gesamt",
116
+ "Delivery note": "Lieferschein",
117
+ Invoice: "Rechnung",
118
+ Estimate: "Angebot",
119
+ "Credit note": "Gutschrift",
120
+ "Advance invoice": "Vorausrechnung",
121
+ "FINA fiscalized invoices always use the current date":
122
+ "FINA-fiskalisierte Rechnungen verwenden immer das aktuelle Datum",
112
123
  // Service date
113
124
  "Service Date": "Leistungsdatum",
114
125
  "Single Date": "Datum",
@@ -95,6 +95,17 @@ export default {
95
95
  "Net price": "Precio neto",
96
96
  "Gross price (tax included)": "Precio bruto (impuestos incluidos)",
97
97
  "Net price (before tax)": "Precio neto (antes de impuestos)",
98
+ // Linked documents
99
+ "Linked documents": "Documentos vinculados",
100
+ Type: "Tipo",
101
+ Total: "Total",
102
+ "Delivery note": "Albarán",
103
+ Invoice: "Factura",
104
+ Estimate: "Presupuesto",
105
+ "Credit note": "Nota de crédito",
106
+ "Advance invoice": "Factura anticipada",
107
+ "FINA fiscalized invoices always use the current date":
108
+ "Las facturas fiscalizadas con FINA siempre usan la fecha actual",
98
109
  "Service Date": "Fecha de servicio",
99
110
  "Single Date": "Fecha única",
100
111
  "Date Range": "Rango de fechas",