@spaceinvoices/react-ui 0.4.4 → 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.
- package/cli/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +61 -11
- package/src/components/advance-invoices/create/locales/de.ts +15 -0
- package/src/components/advance-invoices/create/locales/es.ts +15 -0
- package/src/components/advance-invoices/create/locales/fr.ts +15 -0
- package/src/components/advance-invoices/create/locales/hr.ts +15 -0
- package/src/components/advance-invoices/create/locales/it.ts +15 -0
- package/src/components/advance-invoices/create/locales/nl.ts +15 -0
- package/src/components/advance-invoices/create/locales/pl.ts +15 -0
- package/src/components/advance-invoices/create/locales/pt.ts +15 -0
- package/src/components/advance-invoices/create/locales/sl.ts +15 -0
- package/src/components/advance-invoices/list/list-row-actions.tsx +48 -1
- package/src/components/advance-invoices/list/list-table.tsx +21 -1
- package/src/components/advance-invoices/list/locales/de.ts +4 -0
- package/src/components/advance-invoices/list/locales/en.ts +3 -0
- package/src/components/advance-invoices/list/locales/es.ts +4 -0
- package/src/components/advance-invoices/list/locales/fr.ts +4 -0
- package/src/components/advance-invoices/list/locales/hr.ts +3 -0
- package/src/components/advance-invoices/list/locales/it.ts +4 -0
- package/src/components/advance-invoices/list/locales/nl.ts +4 -0
- package/src/components/advance-invoices/list/locales/pl.ts +3 -0
- package/src/components/advance-invoices/list/locales/pt.ts +4 -0
- package/src/components/advance-invoices/list/locales/sl.ts +3 -0
- package/src/components/credit-notes/create/create-credit-note-form.tsx +71 -8
- package/src/components/credit-notes/create/locales/de.ts +16 -0
- package/src/components/credit-notes/create/locales/es.ts +16 -0
- package/src/components/credit-notes/create/locales/fr.ts +16 -0
- package/src/components/credit-notes/create/locales/hr.ts +16 -0
- package/src/components/credit-notes/create/locales/it.ts +16 -0
- package/src/components/credit-notes/create/locales/nl.ts +16 -0
- package/src/components/credit-notes/create/locales/pl.ts +16 -0
- package/src/components/credit-notes/create/locales/pt.ts +16 -0
- package/src/components/credit-notes/create/locales/sl.ts +17 -1
- package/src/components/credit-notes/list/list-row-actions.tsx +44 -1
- package/src/components/credit-notes/list/list-table.tsx +16 -2
- package/src/components/credit-notes/list/locales/de.ts +2 -0
- package/src/components/credit-notes/list/locales/en.ts +2 -0
- package/src/components/credit-notes/list/locales/es.ts +2 -0
- package/src/components/credit-notes/list/locales/fr.ts +2 -0
- package/src/components/credit-notes/list/locales/hr.ts +2 -0
- package/src/components/credit-notes/list/locales/it.ts +2 -0
- package/src/components/credit-notes/list/locales/nl.ts +2 -0
- package/src/components/credit-notes/list/locales/pl.ts +2 -0
- package/src/components/credit-notes/list/locales/pt.ts +2 -0
- package/src/components/credit-notes/list/locales/sl.ts +2 -0
- package/src/components/dashboard/collection-rate-card/use-collection-rate.ts +48 -9
- package/src/components/dashboard/revenue-trend-chart/use-revenue-trend.ts +77 -48
- package/src/components/dashboard/shared/use-revenue-data.ts +77 -9
- package/src/components/delivery-notes/create/create-delivery-note-form.tsx +67 -7
- package/src/components/delivery-notes/create/locales/de.ts +16 -0
- package/src/components/delivery-notes/create/locales/es.ts +16 -0
- package/src/components/delivery-notes/create/locales/fr.ts +16 -0
- package/src/components/delivery-notes/create/locales/hr.ts +16 -0
- package/src/components/delivery-notes/create/locales/it.ts +16 -0
- package/src/components/delivery-notes/create/locales/nl.ts +16 -0
- package/src/components/delivery-notes/create/locales/pl.ts +16 -0
- package/src/components/delivery-notes/create/locales/pt.ts +16 -0
- package/src/components/delivery-notes/create/locales/sl.ts +17 -1
- package/src/components/delivery-notes/list/list-table.tsx +17 -8
- package/src/components/delivery-notes/list/locales/de.ts +32 -1
- package/src/components/delivery-notes/list/locales/en.ts +31 -0
- package/src/components/delivery-notes/list/locales/es.ts +32 -1
- package/src/components/delivery-notes/list/locales/fr.ts +32 -1
- package/src/components/delivery-notes/list/locales/hr.ts +32 -1
- package/src/components/delivery-notes/list/locales/it.ts +32 -1
- package/src/components/delivery-notes/list/locales/nl.ts +32 -1
- package/src/components/delivery-notes/list/locales/pl.ts +32 -1
- package/src/components/delivery-notes/list/locales/pt.ts +32 -1
- package/src/components/delivery-notes/list/locales/sl.ts +32 -1
- package/src/components/documents/create/document-add-item-form.tsx +70 -0
- package/src/components/documents/create/document-details-section.tsx +122 -2
- package/src/components/documents/create/document-items-section.tsx +21 -4
- package/src/components/documents/create/live-preview.tsx +24 -4
- package/src/components/documents/create/mark-as-paid-section.tsx +29 -20
- package/src/components/documents/create/prepare-document-submission.ts +19 -7
- package/src/components/documents/shared/document-preview-display.tsx +3 -4
- package/src/components/documents/view/document-actions-bar.tsx +7 -27
- package/src/components/documents/view/document-details-card.tsx +26 -9
- package/src/components/documents/view/locales/de.ts +2 -0
- package/src/components/documents/view/locales/es.ts +2 -0
- package/src/components/documents/view/locales/fr.ts +2 -0
- package/src/components/documents/view/locales/hr.ts +2 -0
- package/src/components/documents/view/locales/it.ts +2 -0
- package/src/components/documents/view/locales/nl.ts +2 -0
- package/src/components/documents/view/locales/pl.ts +2 -0
- package/src/components/documents/view/locales/pt.ts +2 -0
- package/src/components/documents/view/locales/sl.ts +3 -1
- package/src/components/documents/view/use-document-download.ts +6 -3
- package/src/components/entities/create-entity-form.tsx +2 -1
- package/src/components/entities/entity-settings-form/input-with-preview.tsx +30 -2
- package/src/components/entities/entity-settings-form/locales/de.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/es.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/fr.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/hr.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/it.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/nl.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/pl.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/pt.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/sl.ts +1 -0
- package/src/components/entities/settings/company-settings-form.tsx +173 -20
- package/src/components/estimates/create/create-estimate-form.tsx +64 -6
- package/src/components/estimates/create/locales/de.ts +16 -0
- package/src/components/estimates/create/locales/es.ts +16 -0
- package/src/components/estimates/create/locales/fr.ts +16 -0
- package/src/components/estimates/create/locales/hr.ts +16 -0
- package/src/components/estimates/create/locales/it.ts +16 -0
- package/src/components/estimates/create/locales/nl.ts +16 -0
- package/src/components/estimates/create/locales/pl.ts +16 -0
- package/src/components/estimates/create/locales/pt.ts +16 -0
- package/src/components/estimates/create/locales/sl.ts +17 -1
- package/src/components/estimates/list/list-table.tsx +11 -2
- package/src/components/estimates/list/locales/de.ts +1 -0
- package/src/components/estimates/list/locales/en.ts +1 -0
- package/src/components/estimates/list/locales/es.ts +1 -0
- package/src/components/estimates/list/locales/fr.ts +1 -0
- package/src/components/estimates/list/locales/hr.ts +1 -0
- package/src/components/estimates/list/locales/it.ts +1 -0
- package/src/components/estimates/list/locales/nl.ts +1 -0
- package/src/components/estimates/list/locales/pl.ts +1 -0
- package/src/components/estimates/list/locales/pt.ts +1 -0
- package/src/components/estimates/list/locales/sl.ts +1 -0
- package/src/components/export/document-export-form.tsx +46 -12
- package/src/components/invoices/create/create-invoice-form.tsx +58 -10
- package/src/components/invoices/create/locales/de.ts +15 -0
- package/src/components/invoices/create/locales/es.ts +15 -0
- package/src/components/invoices/create/locales/fr.ts +15 -0
- package/src/components/invoices/create/locales/hr.ts +15 -0
- package/src/components/invoices/create/locales/it.ts +15 -0
- package/src/components/invoices/create/locales/nl.ts +15 -0
- package/src/components/invoices/create/locales/pl.ts +15 -0
- package/src/components/invoices/create/locales/pt.ts +15 -0
- package/src/components/invoices/create/locales/sl.ts +16 -1
- package/src/components/invoices/view/fiscalization-status-card.tsx +10 -8
- package/src/components/table/search-input.tsx +17 -0
- package/src/generated/schemas/advanceinvoice.ts +4 -2
- package/src/generated/schemas/creditnote.ts +2 -1
- package/src/generated/schemas/deliverynote.ts +2 -1
- package/src/generated/schemas/estimate.ts +4 -2
- package/src/generated/schemas/invoice.ts +2 -1
- package/src/generated/schemas/renderadvanceinvoicepreview_body.ts +17 -23
- package/src/generated/schemas/rendercreditnotepreview_body.ts +17 -23
- package/src/generated/schemas/renderdeliverynotepreview_body.ts +17 -23
- package/src/generated/schemas/renderestimatepreview_body.ts +17 -23
- package/src/generated/schemas/renderinvoicepreview_body.ts +19 -23
- package/src/hooks/use-duplicate-document.ts +16 -9
- package/src/hooks/use-vies-check.ts +3 -0
|
@@ -17,7 +17,7 @@ export default {
|
|
|
17
17
|
Price: "Cena",
|
|
18
18
|
Unit: "Enota",
|
|
19
19
|
Discount: "Popust",
|
|
20
|
-
Tax: "
|
|
20
|
+
Tax: "DDV",
|
|
21
21
|
"Tax rate": "Davčna stopnja",
|
|
22
22
|
"Add tax": "Dodaj davek",
|
|
23
23
|
"Select tax...": "Izberi davek...",
|
|
@@ -121,4 +121,19 @@ export default {
|
|
|
121
121
|
"Date Range": "Obdobje",
|
|
122
122
|
From: "Od",
|
|
123
123
|
To: "Do",
|
|
124
|
+
// Separator items
|
|
125
|
+
"Add separator": "Dodaj ločilnik",
|
|
126
|
+
"Section header": "Naslov razdelka",
|
|
127
|
+
"Section title...": "Naslov razdelka...",
|
|
128
|
+
// Transaction type
|
|
129
|
+
"Transaction type": "Vrsta transakcije",
|
|
130
|
+
Domestic: "Domača",
|
|
131
|
+
"EU B2B": "EU B2B",
|
|
132
|
+
"EU B2C": "EU B2C",
|
|
133
|
+
Export: "Izvoz",
|
|
134
|
+
"Determining transaction type...": "Določanje vrste transakcije...",
|
|
135
|
+
"This invoice will not be fiscalized (non-domestic transaction)":
|
|
136
|
+
"Ta račun ne bo fiskaliziran (nedomača transakcija)",
|
|
137
|
+
"Tax Clause": "Davčna klavzula",
|
|
138
|
+
"Add tax clause...": "Dodajte davčno klavzulo...",
|
|
124
139
|
} as const;
|
|
@@ -91,10 +91,16 @@ export function FiscalizationStatusCard({
|
|
|
91
91
|
|
|
92
92
|
const bodyContent = (
|
|
93
93
|
<>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
{fiscalizationData.status === "skipped" ? (
|
|
95
|
+
<div className="text-muted-foreground text-sm">
|
|
96
|
+
{label} · {t("Skipped by user")}
|
|
97
|
+
</div>
|
|
98
|
+
) : (
|
|
99
|
+
<div className="text-muted-foreground text-sm">
|
|
100
|
+
{label} ·{" "}
|
|
101
|
+
{fiscalizationData.fiscalized_at && new Date(fiscalizationData.fiscalized_at).toLocaleString(locale)}
|
|
102
|
+
</div>
|
|
103
|
+
)}
|
|
98
104
|
|
|
99
105
|
{fiscalizationData.status === "failed" && fiscalizationData.error && (
|
|
100
106
|
<Alert variant="destructive">
|
|
@@ -103,10 +109,6 @@ export function FiscalizationStatusCard({
|
|
|
103
109
|
</Alert>
|
|
104
110
|
)}
|
|
105
111
|
|
|
106
|
-
{fiscalizationData.status === "skipped" && (fiscalizationData as any).data?.reason && (
|
|
107
|
-
<div className="text-muted-foreground text-sm">{(fiscalizationData as any).data.reason}</div>
|
|
108
|
-
)}
|
|
109
|
-
|
|
110
112
|
{fiscalizationData.status === "failed" && onRetry && (
|
|
111
113
|
<Button variant="outline" size="sm" onClick={onRetry} disabled={isRetrying}>
|
|
112
114
|
{isRetrying ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <RefreshCw className="mr-2 h-4 w-4" />}
|
|
@@ -16,6 +16,7 @@ type SearchInputProps = {
|
|
|
16
16
|
*/
|
|
17
17
|
export function SearchInput({ initialValue = "", onSearch, placeholder = "Search...", debounceMs }: SearchInputProps) {
|
|
18
18
|
const [value, setValue] = useState(initialValue);
|
|
19
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
19
20
|
|
|
20
21
|
// Use ref to keep onSearch stable in useEffect
|
|
21
22
|
const onSearchRef = useRef(onSearch);
|
|
@@ -56,6 +57,9 @@ export function SearchInput({ initialValue = "", onSearch, placeholder = "Search
|
|
|
56
57
|
onSearchRef.current(null);
|
|
57
58
|
}, []);
|
|
58
59
|
|
|
60
|
+
// Show "Enter ↵" hint when input requires Enter to search (no debounce) and user is typing
|
|
61
|
+
const showEnterHint = debounceMs === undefined && value && isFocused;
|
|
62
|
+
|
|
59
63
|
return (
|
|
60
64
|
<form onSubmit={handleSubmit} className="relative inline-block" data-testid="search-form">
|
|
61
65
|
<Search className="pointer-events-none absolute top-1/2 left-2.5 z-10 h-3 w-3 -translate-y-1/2 text-muted-foreground" />
|
|
@@ -66,8 +70,21 @@ export function SearchInput({ initialValue = "", onSearch, placeholder = "Search
|
|
|
66
70
|
placeholder={placeholder}
|
|
67
71
|
value={value}
|
|
68
72
|
onChange={handleChange}
|
|
73
|
+
onFocus={() => setIsFocused(true)}
|
|
74
|
+
onBlur={() => setIsFocused(false)}
|
|
69
75
|
className="h-8 w-[150px] pr-8 pl-8 lg:w-[250px] [&::-webkit-search-cancel-button]:hidden [&::-webkit-search-decoration]:hidden"
|
|
70
76
|
/>
|
|
77
|
+
{/* Overlay that mirrors input padding to position hint right after typed text */}
|
|
78
|
+
{showEnterHint && (
|
|
79
|
+
<span
|
|
80
|
+
aria-hidden="true"
|
|
81
|
+
className="pointer-events-none absolute inset-0 flex items-center overflow-hidden pl-8 text-sm"
|
|
82
|
+
>
|
|
83
|
+
{/* Invisible text matching input value to push hint to the right */}
|
|
84
|
+
<span className="invisible whitespace-pre">{value}</span>
|
|
85
|
+
<span className="ml-1.5 shrink-0 text-muted-foreground/50 text-xs">Enter ↵</span>
|
|
86
|
+
</span>
|
|
87
|
+
)}
|
|
71
88
|
{value && (
|
|
72
89
|
<Button
|
|
73
90
|
type="button"
|
|
@@ -104,11 +104,12 @@ const createAdvanceInvoiceSchemaDefinition = z.object({
|
|
|
104
104
|
items: z
|
|
105
105
|
.array(
|
|
106
106
|
z.object({
|
|
107
|
+
type: z.enum(["separator"]).optional(),
|
|
107
108
|
name: z.string().min(1).optional(),
|
|
108
109
|
description: z.union([z.string().max(4000, "Description must not exceed 4000 characters"), z.null()]).optional(),
|
|
109
110
|
price: z.number().optional(),
|
|
110
111
|
gross_price: z.number().optional(),
|
|
111
|
-
quantity: z.number().gte(-140737488355328).lte(140737488355327),
|
|
112
|
+
quantity: z.number().gte(-140737488355328).lte(140737488355327).optional(),
|
|
112
113
|
unit: z.union([z.string(), z.null()]).optional(),
|
|
113
114
|
taxes: z.array(DocumentItemTax).optional(),
|
|
114
115
|
discounts: z.array(LineDiscount).max(5).optional(),
|
|
@@ -202,11 +203,12 @@ const updateAdvanceInvoiceSchemaDefinition = z
|
|
|
202
203
|
items: z
|
|
203
204
|
.array(
|
|
204
205
|
z.object({
|
|
206
|
+
type: z.enum(["separator"]).optional(),
|
|
205
207
|
name: z.string().min(1).optional(),
|
|
206
208
|
description: z.union([z.string().max(4000, "Description must not exceed 4000 characters"), z.null()]).optional(),
|
|
207
209
|
price: z.number().optional(),
|
|
208
210
|
gross_price: z.number().optional(),
|
|
209
|
-
quantity: z.number().gte(-140737488355328).lte(140737488355327),
|
|
211
|
+
quantity: z.number().gte(-140737488355328).lte(140737488355327).optional(),
|
|
210
212
|
unit: z.union([z.string(), z.null()]).optional(),
|
|
211
213
|
taxes: z.array(DocumentItemTax).optional(),
|
|
212
214
|
discounts: z.array(LineDiscount).max(5).optional(),
|
|
@@ -85,11 +85,12 @@ const updateCreditNoteSchemaDefinition = z
|
|
|
85
85
|
items: z
|
|
86
86
|
.array(
|
|
87
87
|
z.object({
|
|
88
|
+
type: z.enum(["separator"]).optional(),
|
|
88
89
|
name: z.string().min(1).optional(),
|
|
89
90
|
description: z.union([z.string().max(4000, "Description must not exceed 4000 characters"), z.null()]).optional(),
|
|
90
91
|
price: z.number().optional(),
|
|
91
92
|
gross_price: z.number().optional(),
|
|
92
|
-
quantity: z.number().gte(-140737488355328).lte(140737488355327),
|
|
93
|
+
quantity: z.number().gte(-140737488355328).lte(140737488355327).optional(),
|
|
93
94
|
unit: z.union([z.string(), z.null()]).optional(),
|
|
94
95
|
taxes: z.array(DocumentItemTax).optional(),
|
|
95
96
|
discounts: z.array(LineDiscount).max(5).optional(),
|
|
@@ -93,11 +93,12 @@ const createDeliveryNoteSchemaDefinition = z.object({
|
|
|
93
93
|
items: z
|
|
94
94
|
.array(
|
|
95
95
|
z.object({
|
|
96
|
+
type: z.enum(["separator"]).optional(),
|
|
96
97
|
name: z.string().min(1).optional(),
|
|
97
98
|
description: z.union([z.string().max(4000, "Description must not exceed 4000 characters"), z.null()]).optional(),
|
|
98
99
|
price: z.number().optional(),
|
|
99
100
|
gross_price: z.number().optional(),
|
|
100
|
-
quantity: z.number().gte(-140737488355328).lte(140737488355327),
|
|
101
|
+
quantity: z.number().gte(-140737488355328).lte(140737488355327).optional(),
|
|
101
102
|
unit: z.union([z.string(), z.null()]).optional(),
|
|
102
103
|
taxes: z.array(DocumentItemTax).optional(),
|
|
103
104
|
discounts: z.array(LineDiscount).max(5).optional(),
|
|
@@ -96,11 +96,12 @@ const createEstimateSchemaDefinition = z.object({
|
|
|
96
96
|
items: z
|
|
97
97
|
.array(
|
|
98
98
|
z.object({
|
|
99
|
+
type: z.enum(["separator"]).optional(),
|
|
99
100
|
name: z.string().min(1).optional(),
|
|
100
101
|
description: z.union([z.string().max(4000, "Description must not exceed 4000 characters"), z.null()]).optional(),
|
|
101
102
|
price: z.number().optional(),
|
|
102
103
|
gross_price: z.number().optional(),
|
|
103
|
-
quantity: z.number().gte(-140737488355328).lte(140737488355327),
|
|
104
|
+
quantity: z.number().gte(-140737488355328).lte(140737488355327).optional(),
|
|
104
105
|
unit: z.union([z.string(), z.null()]).optional(),
|
|
105
106
|
taxes: z.array(DocumentItemTax).optional(),
|
|
106
107
|
discounts: z.array(LineDiscount).max(5).optional(),
|
|
@@ -155,11 +156,12 @@ const updateEstimateSchemaDefinition = z
|
|
|
155
156
|
items: z
|
|
156
157
|
.array(
|
|
157
158
|
z.object({
|
|
159
|
+
type: z.enum(["separator"]).optional(),
|
|
158
160
|
name: z.string().min(1).optional(),
|
|
159
161
|
description: z.union([z.string().max(4000, "Description must not exceed 4000 characters"), z.null()]).optional(),
|
|
160
162
|
price: z.number().optional(),
|
|
161
163
|
gross_price: z.number().optional(),
|
|
162
|
-
quantity: z.number().gte(-140737488355328).lte(140737488355327),
|
|
164
|
+
quantity: z.number().gte(-140737488355328).lte(140737488355327).optional(),
|
|
163
165
|
unit: z.union([z.string(), z.null()]).optional(),
|
|
164
166
|
taxes: z.array(DocumentItemTax).optional(),
|
|
165
167
|
discounts: z.array(LineDiscount).max(5).optional(),
|
|
@@ -105,11 +105,12 @@ const createInvoiceSchemaDefinition = z.object({
|
|
|
105
105
|
items: z
|
|
106
106
|
.array(
|
|
107
107
|
z.object({
|
|
108
|
+
type: z.enum(["separator"]).optional(),
|
|
108
109
|
name: z.string().min(1).optional(),
|
|
109
110
|
description: z.union([z.string().max(4000, "Description must not exceed 4000 characters"), z.null()]).optional(),
|
|
110
111
|
price: z.number().optional(),
|
|
111
112
|
gross_price: z.number().optional(),
|
|
112
|
-
quantity: z.number().gte(-140737488355328).lte(140737488355327),
|
|
113
|
+
quantity: z.number().gte(-140737488355328).lte(140737488355327).optional(),
|
|
113
114
|
unit: z.union([z.string(), z.null()]).optional(),
|
|
114
115
|
taxes: z.array(DocumentItemTax).optional(),
|
|
115
116
|
discounts: z.array(LineDiscount).max(5).optional(),
|
|
@@ -112,6 +112,7 @@ const PartialAdvanceInvoicePreview = z.object({
|
|
|
112
112
|
.array(
|
|
113
113
|
z
|
|
114
114
|
.object({
|
|
115
|
+
type: z.literal("separator"),
|
|
115
116
|
name: z.string(),
|
|
116
117
|
quantity: z.number(),
|
|
117
118
|
price: z.number(),
|
|
@@ -154,29 +155,22 @@ const LineDiscount = z.object({
|
|
|
154
155
|
|
|
155
156
|
|
|
156
157
|
// Dependency schema for renderadvanceinvoicepreview_body
|
|
157
|
-
const CreateDocumentItem = z
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
z.object({}).partial().passthrough(),
|
|
174
|
-
z.array(z.unknown()),
|
|
175
|
-
z.null(),
|
|
176
|
-
])
|
|
177
|
-
.optional(),
|
|
178
|
-
item_id: z.string().optional(),
|
|
179
|
-
});
|
|
158
|
+
const CreateDocumentItem = z
|
|
159
|
+
.object({
|
|
160
|
+
type: z.literal("separator"),
|
|
161
|
+
name: z.string().min(1),
|
|
162
|
+
description: z.union([z.string(), z.null()]),
|
|
163
|
+
price: z.number(),
|
|
164
|
+
gross_price: z.number(),
|
|
165
|
+
quantity: z.union([z.number(), z.null()]),
|
|
166
|
+
unit: z.union([z.string(), z.null()]),
|
|
167
|
+
taxes: z.array(DocumentItemTax),
|
|
168
|
+
discounts: z.array(LineDiscount).max(5),
|
|
169
|
+
item_id: z.string(),
|
|
170
|
+
metadata: z.union([z.record(z.string(), z.any()), z.null()]),
|
|
171
|
+
save_item: z.boolean().default(true),
|
|
172
|
+
})
|
|
173
|
+
.partial();
|
|
180
174
|
|
|
181
175
|
|
|
182
176
|
// Dependency schema for renderadvanceinvoicepreview_body
|
|
@@ -113,6 +113,7 @@ const PartialCreditNotePreview = z.object({
|
|
|
113
113
|
.array(
|
|
114
114
|
z
|
|
115
115
|
.object({
|
|
116
|
+
type: z.literal("separator"),
|
|
116
117
|
name: z.string(),
|
|
117
118
|
quantity: z.number(),
|
|
118
119
|
price: z.number(),
|
|
@@ -155,29 +156,22 @@ const LineDiscount = z.object({
|
|
|
155
156
|
|
|
156
157
|
|
|
157
158
|
// Dependency schema for rendercreditnotepreview_body
|
|
158
|
-
const CreateDocumentItem = z
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
z.object({}).partial().passthrough(),
|
|
175
|
-
z.array(z.unknown()),
|
|
176
|
-
z.null(),
|
|
177
|
-
])
|
|
178
|
-
.optional(),
|
|
179
|
-
item_id: z.string().optional(),
|
|
180
|
-
});
|
|
159
|
+
const CreateDocumentItem = z
|
|
160
|
+
.object({
|
|
161
|
+
type: z.literal("separator"),
|
|
162
|
+
name: z.string().min(1),
|
|
163
|
+
description: z.union([z.string(), z.null()]),
|
|
164
|
+
price: z.number(),
|
|
165
|
+
gross_price: z.number(),
|
|
166
|
+
quantity: z.union([z.number(), z.null()]),
|
|
167
|
+
unit: z.union([z.string(), z.null()]),
|
|
168
|
+
taxes: z.array(DocumentItemTax),
|
|
169
|
+
discounts: z.array(LineDiscount).max(5),
|
|
170
|
+
item_id: z.string(),
|
|
171
|
+
metadata: z.union([z.record(z.string(), z.any()), z.null()]),
|
|
172
|
+
save_item: z.boolean().default(true),
|
|
173
|
+
})
|
|
174
|
+
.partial();
|
|
181
175
|
|
|
182
176
|
|
|
183
177
|
// Dependency schema for rendercreditnotepreview_body
|
|
@@ -81,6 +81,7 @@ const PartialDeliveryNotePreview = z.object({
|
|
|
81
81
|
.array(
|
|
82
82
|
z
|
|
83
83
|
.object({
|
|
84
|
+
type: z.literal("separator"),
|
|
84
85
|
name: z.string(),
|
|
85
86
|
quantity: z.number(),
|
|
86
87
|
price: z.number(),
|
|
@@ -123,29 +124,22 @@ const LineDiscount = z.object({
|
|
|
123
124
|
|
|
124
125
|
|
|
125
126
|
// Dependency schema for renderdeliverynotepreview_body
|
|
126
|
-
const CreateDocumentItem = z
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
z.object({}).partial().passthrough(),
|
|
143
|
-
z.array(z.unknown()),
|
|
144
|
-
z.null(),
|
|
145
|
-
])
|
|
146
|
-
.optional(),
|
|
147
|
-
item_id: z.string().optional(),
|
|
148
|
-
});
|
|
127
|
+
const CreateDocumentItem = z
|
|
128
|
+
.object({
|
|
129
|
+
type: z.literal("separator"),
|
|
130
|
+
name: z.string().min(1),
|
|
131
|
+
description: z.union([z.string(), z.null()]),
|
|
132
|
+
price: z.number(),
|
|
133
|
+
gross_price: z.number(),
|
|
134
|
+
quantity: z.union([z.number(), z.null()]),
|
|
135
|
+
unit: z.union([z.string(), z.null()]),
|
|
136
|
+
taxes: z.array(DocumentItemTax),
|
|
137
|
+
discounts: z.array(LineDiscount).max(5),
|
|
138
|
+
item_id: z.string(),
|
|
139
|
+
metadata: z.union([z.record(z.string(), z.any()), z.null()]),
|
|
140
|
+
save_item: z.boolean().default(true),
|
|
141
|
+
})
|
|
142
|
+
.partial();
|
|
149
143
|
|
|
150
144
|
|
|
151
145
|
// Dependency schema for renderdeliverynotepreview_body
|
|
@@ -82,6 +82,7 @@ const PartialEstimatePreview = z.object({
|
|
|
82
82
|
.array(
|
|
83
83
|
z
|
|
84
84
|
.object({
|
|
85
|
+
type: z.literal("separator"),
|
|
85
86
|
name: z.string(),
|
|
86
87
|
quantity: z.number(),
|
|
87
88
|
price: z.number(),
|
|
@@ -123,29 +124,22 @@ const LineDiscount = z.object({
|
|
|
123
124
|
|
|
124
125
|
|
|
125
126
|
// Dependency schema for renderestimatepreview_body
|
|
126
|
-
const CreateDocumentItem = z
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
z.object({}).partial().passthrough(),
|
|
143
|
-
z.array(z.unknown()),
|
|
144
|
-
z.null(),
|
|
145
|
-
])
|
|
146
|
-
.optional(),
|
|
147
|
-
item_id: z.string().optional(),
|
|
148
|
-
});
|
|
127
|
+
const CreateDocumentItem = z
|
|
128
|
+
.object({
|
|
129
|
+
type: z.literal("separator"),
|
|
130
|
+
name: z.string().min(1),
|
|
131
|
+
description: z.union([z.string(), z.null()]),
|
|
132
|
+
price: z.number(),
|
|
133
|
+
gross_price: z.number(),
|
|
134
|
+
quantity: z.union([z.number(), z.null()]),
|
|
135
|
+
unit: z.union([z.string(), z.null()]),
|
|
136
|
+
taxes: z.array(DocumentItemTax),
|
|
137
|
+
discounts: z.array(LineDiscount).max(5),
|
|
138
|
+
item_id: z.string(),
|
|
139
|
+
metadata: z.union([z.record(z.string(), z.any()), z.null()]),
|
|
140
|
+
save_item: z.boolean().default(true),
|
|
141
|
+
})
|
|
142
|
+
.partial();
|
|
149
143
|
|
|
150
144
|
|
|
151
145
|
// Dependency schema for renderestimatepreview_body
|
|
@@ -113,6 +113,7 @@ const PartialInvoicePreview = z.object({
|
|
|
113
113
|
.array(
|
|
114
114
|
z
|
|
115
115
|
.object({
|
|
116
|
+
type: z.literal("separator"),
|
|
116
117
|
name: z.string(),
|
|
117
118
|
quantity: z.number(),
|
|
118
119
|
price: z.number(),
|
|
@@ -132,6 +133,7 @@ const PartialInvoicePreview = z.object({
|
|
|
132
133
|
.min(1),
|
|
133
134
|
fina: CreateFinaInvoiceData.optional(),
|
|
134
135
|
expected_total_with_tax: z.number().gt(0).optional(),
|
|
136
|
+
force_linked_documents: z.boolean().optional(),
|
|
135
137
|
});
|
|
136
138
|
|
|
137
139
|
|
|
@@ -155,29 +157,22 @@ const LineDiscount = z.object({
|
|
|
155
157
|
|
|
156
158
|
|
|
157
159
|
// Dependency schema for renderinvoicepreview_body
|
|
158
|
-
const CreateDocumentItem = z
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
z.object({}).partial().passthrough(),
|
|
175
|
-
z.array(z.unknown()),
|
|
176
|
-
z.null(),
|
|
177
|
-
])
|
|
178
|
-
.optional(),
|
|
179
|
-
item_id: z.string().optional(),
|
|
180
|
-
});
|
|
160
|
+
const CreateDocumentItem = z
|
|
161
|
+
.object({
|
|
162
|
+
type: z.literal("separator"),
|
|
163
|
+
name: z.string().min(1),
|
|
164
|
+
description: z.union([z.string(), z.null()]),
|
|
165
|
+
price: z.number(),
|
|
166
|
+
gross_price: z.number(),
|
|
167
|
+
quantity: z.union([z.number(), z.null()]),
|
|
168
|
+
unit: z.union([z.string(), z.null()]),
|
|
169
|
+
taxes: z.array(DocumentItemTax),
|
|
170
|
+
discounts: z.array(LineDiscount).max(5),
|
|
171
|
+
item_id: z.string(),
|
|
172
|
+
metadata: z.union([z.record(z.string(), z.any()), z.null()]),
|
|
173
|
+
save_item: z.boolean().default(true),
|
|
174
|
+
})
|
|
175
|
+
.partial();
|
|
181
176
|
|
|
182
177
|
|
|
183
178
|
// Dependency schema for renderinvoicepreview_body
|
|
@@ -201,6 +196,7 @@ const CompleteInvoicePreview = z.object({
|
|
|
201
196
|
items: z.array(CreateDocumentItem).min(1),
|
|
202
197
|
fina: CreateFinaInvoiceData.optional(),
|
|
203
198
|
expected_total_with_tax: z.number().gt(0).optional(),
|
|
199
|
+
force_linked_documents: z.boolean().optional(),
|
|
204
200
|
});
|
|
205
201
|
|
|
206
202
|
|
|
@@ -64,6 +64,7 @@ function transformDocumentForDuplication(source: Document, targetType: DocumentT
|
|
|
64
64
|
// Transform items - copy only the fields needed for creation
|
|
65
65
|
// Use type assertion for items since all document item types share the same shape
|
|
66
66
|
const sourceItems = source.items as Array<{
|
|
67
|
+
type?: string | null;
|
|
67
68
|
name: string;
|
|
68
69
|
description: string | null;
|
|
69
70
|
quantity: number;
|
|
@@ -72,15 +73,21 @@ function transformDocumentForDuplication(source: Document, targetType: DocumentT
|
|
|
72
73
|
taxes: Array<{ tax_id?: string }>;
|
|
73
74
|
}>;
|
|
74
75
|
const items = sourceItems?.map((item) => ({
|
|
76
|
+
type: item.type ?? undefined,
|
|
75
77
|
name: item.name,
|
|
76
78
|
description: item.description,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
// Separator items skip financial fields
|
|
80
|
+
...(item.type !== "separator"
|
|
81
|
+
? {
|
|
82
|
+
quantity: item.quantity,
|
|
83
|
+
// Use gross_price if set, otherwise use price. The form uses is_gross_price as a UI toggle.
|
|
84
|
+
price: item.gross_price ?? item.price,
|
|
85
|
+
// Copy tax references (tax_id), not computed tax data
|
|
86
|
+
taxes: item.taxes?.map((tax) => ({ tax_id: tax.tax_id })),
|
|
87
|
+
// Derive is_gross_price from whether gross_price is set
|
|
88
|
+
gross_price: item.gross_price ?? undefined,
|
|
89
|
+
}
|
|
90
|
+
: {}),
|
|
84
91
|
}));
|
|
85
92
|
|
|
86
93
|
// Build customer data - always copy if available (form needs this for display)
|
|
@@ -108,8 +115,8 @@ function transformDocumentForDuplication(source: Document, targetType: DocumentT
|
|
|
108
115
|
// The form needs customer data for display, even when customer_id is set
|
|
109
116
|
...(source.customer_id ? { customer_id: source.customer_id } : {}),
|
|
110
117
|
...(customerData ? { customer: customerData } : {}),
|
|
111
|
-
// Items
|
|
112
|
-
items,
|
|
118
|
+
// Items (cast needed: separator items omit financial fields like quantity)
|
|
119
|
+
items: items as any,
|
|
113
120
|
// Currency
|
|
114
121
|
currency_code: source.currency_code,
|
|
115
122
|
// Notes
|
|
@@ -42,6 +42,8 @@ export interface UseViesCheckResult {
|
|
|
42
42
|
reverseChargeApplies: boolean;
|
|
43
43
|
/** Transaction type determined by VIES check */
|
|
44
44
|
transactionType: ViesCheckResponse["transaction_type"] | undefined;
|
|
45
|
+
/** Customer country code returned by VIES check */
|
|
46
|
+
customerCountryCode: string | null;
|
|
45
47
|
/** Warning message from VIES validation */
|
|
46
48
|
warning: string | null;
|
|
47
49
|
/** Whether VIES validation was successful */
|
|
@@ -124,6 +126,7 @@ export function useViesCheck({
|
|
|
124
126
|
error: query.error,
|
|
125
127
|
reverseChargeApplies: query.data?.reverse_charge_applies ?? false,
|
|
126
128
|
transactionType: query.data?.transaction_type,
|
|
129
|
+
customerCountryCode: query.data?.customer_country_code ?? null,
|
|
127
130
|
warning: query.data?.warning ?? null,
|
|
128
131
|
viesValid: query.data?.vies_valid ?? null,
|
|
129
132
|
};
|