@happyvertical/smrt-commerce 0.53.4 → 0.53.6
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/AGENTS.md +19 -3
- package/README.md +29 -1
- package/agents/commercial-ui.md +78 -0
- package/agents/customer-vendor-ui.md +76 -0
- package/agents/invoice-calculations.md +17 -0
- package/agents/invoice-preparation.md +86 -0
- package/agents/invoice-quantity.md +46 -0
- package/agents/pricing-versions.md +28 -0
- package/agents/purchasing-ui.md +82 -0
- package/agents/quote-ui.md +82 -0
- package/dist/billing/units.d.ts +1 -7
- package/dist/billing/units.d.ts.map +1 -1
- package/dist/chunks/calculations-DPuldr1J.js +242 -0
- package/dist/chunks/calculations-DPuldr1J.js.map +1 -0
- package/dist/chunks/types-CRnln577.js.map +1 -1
- package/dist/chunks/{units-CpBepqG1.js → units-CJcAOQm1.js} +3 -39
- package/dist/chunks/units-CJcAOQm1.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +164 -44
- package/dist/index.js.map +1 -1
- package/dist/invoices.d.ts +3 -0
- package/dist/invoices.d.ts.map +1 -0
- package/dist/invoices.js +2 -0
- package/dist/manifest.json +66 -8
- package/dist/migrations/invoiceEditorStorage.d.ts +39 -0
- package/dist/migrations/invoiceEditorStorage.d.ts.map +1 -0
- package/dist/models/ContractLineItem.d.ts +1 -1
- package/dist/models/InvoiceLineItem.d.ts +18 -36
- package/dist/models/InvoiceLineItem.d.ts.map +1 -1
- package/dist/playground.js +201 -3
- package/dist/playground.js.map +1 -1
- package/dist/smrt-knowledge.json +109 -7
- package/dist/svelte/components/CustomerDetail.svelte +150 -0
- package/dist/svelte/components/CustomerDetail.svelte.d.ts +28 -0
- package/dist/svelte/components/CustomerDetail.svelte.d.ts.map +1 -0
- package/dist/svelte/components/CustomerDirectory.svelte +177 -0
- package/dist/svelte/components/CustomerDirectory.svelte.d.ts +42 -0
- package/dist/svelte/components/CustomerDirectory.svelte.d.ts.map +1 -0
- package/dist/svelte/components/CustomerForm.svelte +234 -0
- package/dist/svelte/components/CustomerForm.svelte.d.ts +44 -0
- package/dist/svelte/components/CustomerForm.svelte.d.ts.map +1 -0
- package/dist/svelte/components/InvoiceAllocationFields.svelte +72 -0
- package/dist/svelte/components/InvoiceAllocationFields.svelte.d.ts +8 -0
- package/dist/svelte/components/InvoiceAllocationFields.svelte.d.ts.map +1 -0
- package/dist/svelte/components/InvoiceCard.svelte +2 -2
- package/dist/svelte/components/InvoiceEditor.svelte +134 -0
- package/dist/svelte/components/InvoiceEditor.svelte.d.ts +8 -0
- package/dist/svelte/components/InvoiceEditor.svelte.d.ts.map +1 -0
- package/dist/svelte/components/InvoiceLineEditor.svelte +85 -0
- package/dist/svelte/components/InvoiceLineEditor.svelte.d.ts +8 -0
- package/dist/svelte/components/InvoiceLineEditor.svelte.d.ts.map +1 -0
- package/dist/svelte/components/InvoiceReview.svelte +23 -0
- package/dist/svelte/components/InvoiceReview.svelte.d.ts +10 -0
- package/dist/svelte/components/InvoiceReview.svelte.d.ts.map +1 -0
- package/dist/svelte/components/PartyAddressFields.svelte +95 -0
- package/dist/svelte/components/PartyAddressFields.svelte.d.ts +25 -0
- package/dist/svelte/components/PartyAddressFields.svelte.d.ts.map +1 -0
- package/dist/svelte/components/PartyContactFields.svelte +153 -0
- package/dist/svelte/components/PartyContactFields.svelte.d.ts +28 -0
- package/dist/svelte/components/PartyContactFields.svelte.d.ts.map +1 -0
- package/dist/svelte/components/PricingVersionDecision.svelte +88 -0
- package/dist/svelte/components/PricingVersionDecision.svelte.d.ts +35 -0
- package/dist/svelte/components/PricingVersionDecision.svelte.d.ts.map +1 -0
- package/dist/svelte/components/PricingVersionSummary.svelte +46 -0
- package/dist/svelte/components/PricingVersionSummary.svelte.d.ts +9 -0
- package/dist/svelte/components/PricingVersionSummary.svelte.d.ts.map +1 -0
- package/dist/svelte/components/PurchaseOrderEditor.svelte +210 -0
- package/dist/svelte/components/PurchaseOrderEditor.svelte.d.ts +79 -0
- package/dist/svelte/components/PurchaseOrderEditor.svelte.d.ts.map +1 -0
- package/dist/svelte/components/PurchaseSourceSelector.svelte +56 -0
- package/dist/svelte/components/PurchaseSourceSelector.svelte.d.ts +30 -0
- package/dist/svelte/components/PurchaseSourceSelector.svelte.d.ts.map +1 -0
- package/dist/svelte/components/PurchasingPlayground.svelte +133 -0
- package/dist/svelte/components/PurchasingPlayground.svelte.d.ts +9 -0
- package/dist/svelte/components/PurchasingPlayground.svelte.d.ts.map +1 -0
- package/dist/svelte/components/QuoteEditor.svelte +177 -0
- package/dist/svelte/components/QuoteEditor.svelte.d.ts +76 -0
- package/dist/svelte/components/QuoteEditor.svelte.d.ts.map +1 -0
- package/dist/svelte/components/QuotePlayground.svelte +108 -0
- package/dist/svelte/components/QuotePlayground.svelte.d.ts +10 -0
- package/dist/svelte/components/QuotePlayground.svelte.d.ts.map +1 -0
- package/dist/svelte/components/QuoteRevisionComparison.svelte +44 -0
- package/dist/svelte/components/QuoteRevisionComparison.svelte.d.ts +14 -0
- package/dist/svelte/components/QuoteRevisionComparison.svelte.d.ts.map +1 -0
- package/dist/svelte/components/QuoteRevisionHistory.svelte +55 -0
- package/dist/svelte/components/QuoteRevisionHistory.svelte.d.ts +15 -0
- package/dist/svelte/components/QuoteRevisionHistory.svelte.d.ts.map +1 -0
- package/dist/svelte/components/VendorDetail.svelte +134 -0
- package/dist/svelte/components/VendorDetail.svelte.d.ts +26 -0
- package/dist/svelte/components/VendorDetail.svelte.d.ts.map +1 -0
- package/dist/svelte/components/VendorDirectory.svelte +178 -0
- package/dist/svelte/components/VendorDirectory.svelte.d.ts +42 -0
- package/dist/svelte/components/VendorDirectory.svelte.d.ts.map +1 -0
- package/dist/svelte/components/VendorForm.svelte +224 -0
- package/dist/svelte/components/VendorForm.svelte.d.ts +42 -0
- package/dist/svelte/components/VendorForm.svelte.d.ts.map +1 -0
- package/dist/svelte/i18n.d.ts +102 -0
- package/dist/svelte/i18n.d.ts.map +1 -1
- package/dist/svelte/i18n.js +102 -0
- package/dist/svelte/index.d.ts +52 -0
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +49 -0
- package/dist/svelte/invoices/calculations.d.ts +121 -0
- package/dist/svelte/invoices/calculations.d.ts.map +1 -0
- package/dist/svelte/invoices/calculations.js +259 -0
- package/dist/svelte/invoices/currency.d.ts +9 -0
- package/dist/svelte/invoices/currency.d.ts.map +1 -0
- package/dist/svelte/invoices/currency.js +55 -0
- package/dist/svelte/invoices/fields.d.ts +6 -0
- package/dist/svelte/invoices/fields.d.ts.map +1 -0
- package/dist/svelte/invoices/fields.js +22 -0
- package/dist/svelte/invoices/messages.d.ts +53 -0
- package/dist/svelte/invoices/messages.d.ts.map +1 -0
- package/dist/svelte/invoices/messages.js +53 -0
- package/dist/svelte/invoices/types.d.ts +194 -0
- package/dist/svelte/invoices/types.d.ts.map +1 -0
- package/dist/svelte/invoices/types.js +1 -0
- package/dist/svelte/party-types.d.ts +203 -0
- package/dist/svelte/party-types.d.ts.map +1 -0
- package/dist/svelte/party-types.js +82 -0
- package/dist/svelte/playground/InvoicePreparationPreview.svelte +116 -0
- package/dist/svelte/playground/InvoicePreparationPreview.svelte.d.ts +4 -0
- package/dist/svelte/playground/InvoicePreparationPreview.svelte.d.ts.map +1 -0
- package/dist/svelte/playground/PartyFormPreview.svelte +211 -0
- package/dist/svelte/playground/PartyFormPreview.svelte.d.ts +8 -0
- package/dist/svelte/playground/PartyFormPreview.svelte.d.ts.map +1 -0
- package/dist/svelte/playground/PricingVersionPreview.svelte +55 -0
- package/dist/svelte/playground/PricingVersionPreview.svelte.d.ts +4 -0
- package/dist/svelte/playground/PricingVersionPreview.svelte.d.ts.map +1 -0
- package/dist/svelte/playground.d.ts +442 -3
- package/dist/svelte/playground.d.ts.map +1 -1
- package/dist/svelte/playground.js +199 -3
- package/dist/svelte/pricing-i18n.d.ts +10 -0
- package/dist/svelte/pricing-i18n.d.ts.map +1 -0
- package/dist/svelte/pricing-i18n.js +10 -0
- package/dist/svelte/pricing-types.d.ts +38 -0
- package/dist/svelte/pricing-types.d.ts.map +1 -0
- package/dist/svelte/pricing-types.js +1 -0
- package/dist/svelte/purchasing-i18n.d.ts +53 -0
- package/dist/svelte/purchasing-i18n.d.ts.map +1 -0
- package/dist/svelte/purchasing-i18n.js +53 -0
- package/dist/svelte/purchasing-types.d.ts +91 -0
- package/dist/svelte/purchasing-types.d.ts.map +1 -0
- package/dist/svelte/purchasing-types.js +13 -0
- package/dist/svelte/quote-i18n.d.ts +49 -0
- package/dist/svelte/quote-i18n.d.ts.map +1 -0
- package/dist/svelte/quote-i18n.js +49 -0
- package/dist/svelte/quote-types.d.ts +81 -0
- package/dist/svelte/quote-types.d.ts.map +1 -0
- package/dist/svelte/quote-types.js +51 -0
- package/dist/types/index.d.ts +13 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +150 -6
- package/dist/ui.js.map +1 -1
- package/package.json +25 -13
- package/dist/chunks/units-CpBepqG1.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/svelte/invoices/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
/** Identity categories used by the presentation adapter. They do not create or migrate Profile records. */
|
|
3
|
+
export type PartyIdentityKind = 'business' | 'person';
|
|
4
|
+
/** Public Profile-shaped identity data accepted by customer and vendor surfaces. */
|
|
5
|
+
export interface PartyProfileData {
|
|
6
|
+
id?: string;
|
|
7
|
+
name: string;
|
|
8
|
+
email?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
identityKind?: PartyIdentityKind;
|
|
11
|
+
}
|
|
12
|
+
/** Consumer-supplied contact projection. Persistence and relationship semantics stay with the caller. */
|
|
13
|
+
export interface PartyContactData {
|
|
14
|
+
id?: string;
|
|
15
|
+
name?: string;
|
|
16
|
+
label?: string;
|
|
17
|
+
email?: string;
|
|
18
|
+
phone?: string;
|
|
19
|
+
address?: string;
|
|
20
|
+
}
|
|
21
|
+
/** A postal address matching Commerce's public Address shape. */
|
|
22
|
+
export interface PartyAddressData {
|
|
23
|
+
street1?: string;
|
|
24
|
+
street2?: string;
|
|
25
|
+
city?: string;
|
|
26
|
+
state?: string;
|
|
27
|
+
postalCode?: string;
|
|
28
|
+
country?: string;
|
|
29
|
+
}
|
|
30
|
+
/** Customer DTO for UI rendering. Money is always an integer count of currency minor units. */
|
|
31
|
+
export interface CustomerDisplayData {
|
|
32
|
+
id: string;
|
|
33
|
+
profileId?: string;
|
|
34
|
+
profile: PartyProfileData;
|
|
35
|
+
status: string;
|
|
36
|
+
customerType?: string;
|
|
37
|
+
/** Credit limit in integer minor units, never decimal major units. */
|
|
38
|
+
creditLimitMinor?: number;
|
|
39
|
+
paymentTerms?: string;
|
|
40
|
+
taxExempt?: boolean;
|
|
41
|
+
defaultShippingAddress?: PartyAddressData;
|
|
42
|
+
defaultBillingAddress?: PartyAddressData;
|
|
43
|
+
notes?: string;
|
|
44
|
+
contacts?: PartyContactData[];
|
|
45
|
+
}
|
|
46
|
+
/** Vendor DTO for UI rendering. Money is always an integer count of currency minor units. */
|
|
47
|
+
export interface VendorDisplayData {
|
|
48
|
+
id: string;
|
|
49
|
+
profileId?: string;
|
|
50
|
+
profile: PartyProfileData;
|
|
51
|
+
status: string;
|
|
52
|
+
leadTimeDays?: number;
|
|
53
|
+
/** Minimum order in integer minor units, never decimal major units. */
|
|
54
|
+
minimumOrderMinor?: number;
|
|
55
|
+
paymentTerms?: string;
|
|
56
|
+
currency?: string;
|
|
57
|
+
defaultContactEmail?: string;
|
|
58
|
+
defaultContactPhone?: string;
|
|
59
|
+
notes?: string;
|
|
60
|
+
contacts?: PartyContactData[];
|
|
61
|
+
}
|
|
62
|
+
/** Server-returned errors and retained form values. Keys are semantic field keys, independent of HTML names. */
|
|
63
|
+
export interface PartyFormErrors {
|
|
64
|
+
form?: string;
|
|
65
|
+
fields?: Record<string, string | undefined>;
|
|
66
|
+
contacts?: Array<Record<string, string | undefined> | undefined>;
|
|
67
|
+
}
|
|
68
|
+
/** Customer form values exactly as entered. Currency text remains a string until the caller parses it. */
|
|
69
|
+
export interface CustomerFormValues {
|
|
70
|
+
profileId?: string;
|
|
71
|
+
identityKind?: PartyIdentityKind | '';
|
|
72
|
+
name?: string;
|
|
73
|
+
email?: string;
|
|
74
|
+
description?: string;
|
|
75
|
+
status?: string;
|
|
76
|
+
customerType?: string;
|
|
77
|
+
/** User-entered major-unit currency text, for example `1250.00`. */
|
|
78
|
+
creditLimit?: string;
|
|
79
|
+
paymentTerms?: string;
|
|
80
|
+
taxExempt?: boolean;
|
|
81
|
+
notes?: string;
|
|
82
|
+
shippingAddress?: PartyAddressData;
|
|
83
|
+
billingAddress?: PartyAddressData;
|
|
84
|
+
contacts?: PartyContactData[];
|
|
85
|
+
}
|
|
86
|
+
/** Vendor form values exactly as entered. Currency text remains a string until the caller parses it. */
|
|
87
|
+
export interface VendorFormValues {
|
|
88
|
+
profileId?: string;
|
|
89
|
+
identityKind?: PartyIdentityKind | '';
|
|
90
|
+
name?: string;
|
|
91
|
+
email?: string;
|
|
92
|
+
description?: string;
|
|
93
|
+
status?: string;
|
|
94
|
+
leadTimeDays?: string;
|
|
95
|
+
/** User-entered major-unit currency text, for example `500.00`. */
|
|
96
|
+
minimumOrder?: string;
|
|
97
|
+
paymentTerms?: string;
|
|
98
|
+
currency?: string;
|
|
99
|
+
defaultContactEmail?: string;
|
|
100
|
+
defaultContactPhone?: string;
|
|
101
|
+
notes?: string;
|
|
102
|
+
contacts?: PartyContactData[];
|
|
103
|
+
}
|
|
104
|
+
/** Caller-controlled native form transport. Hidden values commonly carry tenant and request tokens. */
|
|
105
|
+
export interface PartyFormTransport {
|
|
106
|
+
action?: string;
|
|
107
|
+
method?: 'get' | 'post';
|
|
108
|
+
hiddenFields?: Record<string, string>;
|
|
109
|
+
intentName?: string;
|
|
110
|
+
saveIntent?: string;
|
|
111
|
+
addContactIntent?: string;
|
|
112
|
+
removeContactIntent?: (index: number) => string;
|
|
113
|
+
}
|
|
114
|
+
/** Adaptable common field names. Repeated contact names are submitted in DOM order. */
|
|
115
|
+
export interface PartyFieldNames {
|
|
116
|
+
profileId: string;
|
|
117
|
+
identityKind: string;
|
|
118
|
+
name: string;
|
|
119
|
+
email: string;
|
|
120
|
+
description: string;
|
|
121
|
+
contactId: string;
|
|
122
|
+
contactName: string;
|
|
123
|
+
contactLabel: string;
|
|
124
|
+
contactEmail: string;
|
|
125
|
+
contactPhone: string;
|
|
126
|
+
contactAddress: string;
|
|
127
|
+
}
|
|
128
|
+
/** Customer-specific field names. */
|
|
129
|
+
export interface CustomerFieldNames extends PartyFieldNames {
|
|
130
|
+
status: string;
|
|
131
|
+
customerType: string;
|
|
132
|
+
creditLimit: string;
|
|
133
|
+
paymentTerms: string;
|
|
134
|
+
taxExempt: string;
|
|
135
|
+
notes: string;
|
|
136
|
+
shippingStreet1: string;
|
|
137
|
+
shippingStreet2: string;
|
|
138
|
+
shippingCity: string;
|
|
139
|
+
shippingState: string;
|
|
140
|
+
shippingPostalCode: string;
|
|
141
|
+
shippingCountry: string;
|
|
142
|
+
billingStreet1: string;
|
|
143
|
+
billingStreet2: string;
|
|
144
|
+
billingCity: string;
|
|
145
|
+
billingState: string;
|
|
146
|
+
billingPostalCode: string;
|
|
147
|
+
billingCountry: string;
|
|
148
|
+
}
|
|
149
|
+
/** Vendor-specific field names. */
|
|
150
|
+
export interface VendorFieldNames extends PartyFieldNames {
|
|
151
|
+
status: string;
|
|
152
|
+
leadTimeDays: string;
|
|
153
|
+
minimumOrder: string;
|
|
154
|
+
paymentTerms: string;
|
|
155
|
+
currency: string;
|
|
156
|
+
defaultContactEmail: string;
|
|
157
|
+
defaultContactPhone: string;
|
|
158
|
+
notes: string;
|
|
159
|
+
}
|
|
160
|
+
/** Labels applications can override, including replacing “Customer” with “Client”. */
|
|
161
|
+
export interface PartySurfaceLabels {
|
|
162
|
+
singular?: string;
|
|
163
|
+
plural?: string;
|
|
164
|
+
add?: string;
|
|
165
|
+
edit?: string;
|
|
166
|
+
save?: string;
|
|
167
|
+
cancel?: string;
|
|
168
|
+
search?: string;
|
|
169
|
+
empty?: string;
|
|
170
|
+
loading?: string;
|
|
171
|
+
previous?: string;
|
|
172
|
+
next?: string;
|
|
173
|
+
}
|
|
174
|
+
/** Labels for the shared repeatable contact editor. */
|
|
175
|
+
export interface PartyContactLabels {
|
|
176
|
+
heading?: string;
|
|
177
|
+
empty?: string;
|
|
178
|
+
contact?: string;
|
|
179
|
+
name?: string;
|
|
180
|
+
role?: string;
|
|
181
|
+
email?: string;
|
|
182
|
+
phone?: string;
|
|
183
|
+
address?: string;
|
|
184
|
+
add?: string;
|
|
185
|
+
remove?: string;
|
|
186
|
+
}
|
|
187
|
+
/** Directory item shared by customer and vendor list components. */
|
|
188
|
+
export interface PartyDirectoryItem<T> {
|
|
189
|
+
data: T;
|
|
190
|
+
href?: string;
|
|
191
|
+
}
|
|
192
|
+
/** Optional consumer content appended to a directory row. */
|
|
193
|
+
export type PartyDirectoryExtension<T> = Snippet<[T]>;
|
|
194
|
+
/** Optional consumer content appended to a detail or form. */
|
|
195
|
+
export type PartyExtension<T> = Snippet<[T]>;
|
|
196
|
+
export declare const DEFAULT_PARTY_FIELD_NAMES: PartyFieldNames;
|
|
197
|
+
export declare const DEFAULT_CUSTOMER_FIELD_NAMES: CustomerFieldNames;
|
|
198
|
+
export declare const DEFAULT_VENDOR_FIELD_NAMES: VendorFieldNames;
|
|
199
|
+
/** Format explicit minor units for display without changing the transport value. */
|
|
200
|
+
export declare function formatPartyMinorUnits(amountMinor: number, currency: string, minorUnitExponent?: number, locale?: string): string;
|
|
201
|
+
/** Compact a postal address for read-only display. */
|
|
202
|
+
export declare function formatPartyAddress(address?: PartyAddressData): string;
|
|
203
|
+
//# sourceMappingURL=party-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"party-types.d.ts","sourceRoot":"","sources":["../../src/svelte/party-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,2GAA2G;AAC3G,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEtD,oFAAoF;AACpF,MAAM,WAAW,gBAAgB;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED,yGAAyG;AACzG,MAAM,WAAW,gBAAgB;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,iEAAiE;AACjE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+FAA+F;AAC/F,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sBAAsB,CAAC,EAAE,gBAAgB,CAAC;IAC1C,qBAAqB,CAAC,EAAE,gBAAgB,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC/B;AAED,6FAA6F;AAC7F,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC/B;AAED,gHAAgH;AAChH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5C,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC;CAClE;AAED,0GAA0G;AAC1G,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,iBAAiB,GAAG,EAAE,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC/B;AAED,wGAAwG;AACxG,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,iBAAiB,GAAG,EAAE,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC/B;AAED,uGAAuG;AACvG,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACjD;AAED,uFAAuF;AACvF,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,qCAAqC;AACrC,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,mCAAmC;AACnC,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,sFAAsF;AACtF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,uDAAuD;AACvD,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oEAAoE;AACpE,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,6DAA6D;AAC7D,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtD,8DAA8D;AAC9D,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7C,eAAO,MAAM,yBAAyB,EAAE,eAYvC,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,kBAoB1C,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,gBAUxC,CAAC;AAEF,oFAAoF;AACpF,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,iBAAiB,SAAI,EACrB,MAAM,SAAO,GACZ,MAAM,CAuBR;AAED,sDAAsD;AACtD,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAWrE"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export const DEFAULT_PARTY_FIELD_NAMES = {
|
|
2
|
+
profileId: 'profileId',
|
|
3
|
+
identityKind: 'identityKind',
|
|
4
|
+
name: 'name',
|
|
5
|
+
email: 'email',
|
|
6
|
+
description: 'description',
|
|
7
|
+
contactId: 'contactId',
|
|
8
|
+
contactName: 'contactName',
|
|
9
|
+
contactLabel: 'contactLabel',
|
|
10
|
+
contactEmail: 'contactEmail',
|
|
11
|
+
contactPhone: 'contactPhone',
|
|
12
|
+
contactAddress: 'contactAddress',
|
|
13
|
+
};
|
|
14
|
+
export const DEFAULT_CUSTOMER_FIELD_NAMES = {
|
|
15
|
+
...DEFAULT_PARTY_FIELD_NAMES,
|
|
16
|
+
status: 'status',
|
|
17
|
+
customerType: 'customerType',
|
|
18
|
+
creditLimit: 'creditLimit',
|
|
19
|
+
paymentTerms: 'paymentTerms',
|
|
20
|
+
taxExempt: 'taxExempt',
|
|
21
|
+
notes: 'notes',
|
|
22
|
+
shippingStreet1: 'shippingStreet1',
|
|
23
|
+
shippingStreet2: 'shippingStreet2',
|
|
24
|
+
shippingCity: 'shippingCity',
|
|
25
|
+
shippingState: 'shippingState',
|
|
26
|
+
shippingPostalCode: 'shippingPostalCode',
|
|
27
|
+
shippingCountry: 'shippingCountry',
|
|
28
|
+
billingStreet1: 'billingStreet1',
|
|
29
|
+
billingStreet2: 'billingStreet2',
|
|
30
|
+
billingCity: 'billingCity',
|
|
31
|
+
billingState: 'billingState',
|
|
32
|
+
billingPostalCode: 'billingPostalCode',
|
|
33
|
+
billingCountry: 'billingCountry',
|
|
34
|
+
};
|
|
35
|
+
export const DEFAULT_VENDOR_FIELD_NAMES = {
|
|
36
|
+
...DEFAULT_PARTY_FIELD_NAMES,
|
|
37
|
+
status: 'status',
|
|
38
|
+
leadTimeDays: 'leadTimeDays',
|
|
39
|
+
minimumOrder: 'minimumOrder',
|
|
40
|
+
paymentTerms: 'paymentTerms',
|
|
41
|
+
currency: 'currency',
|
|
42
|
+
defaultContactEmail: 'defaultContactEmail',
|
|
43
|
+
defaultContactPhone: 'defaultContactPhone',
|
|
44
|
+
notes: 'notes',
|
|
45
|
+
};
|
|
46
|
+
/** Format explicit minor units for display without changing the transport value. */
|
|
47
|
+
export function formatPartyMinorUnits(amountMinor, currency, minorUnitExponent = 2, locale = 'en') {
|
|
48
|
+
if (!Number.isSafeInteger(amountMinor))
|
|
49
|
+
throw new RangeError('Party amountMinor must be a safe integer');
|
|
50
|
+
if (!Number.isInteger(minorUnitExponent) || minorUnitExponent < 0)
|
|
51
|
+
throw new RangeError('Party minorUnitExponent must be a non-negative integer');
|
|
52
|
+
const formatter = new Intl.NumberFormat(locale, {
|
|
53
|
+
style: 'currency',
|
|
54
|
+
currency,
|
|
55
|
+
minimumFractionDigits: minorUnitExponent,
|
|
56
|
+
maximumFractionDigits: minorUnitExponent,
|
|
57
|
+
});
|
|
58
|
+
const negative = amountMinor < 0;
|
|
59
|
+
const raw = BigInt(Math.abs(amountMinor))
|
|
60
|
+
.toString()
|
|
61
|
+
.padStart(minorUnitExponent + 1, '0');
|
|
62
|
+
const majorUnits = minorUnitExponent
|
|
63
|
+
? `${negative ? '-' : ''}${raw.slice(0, -minorUnitExponent)}.${raw.slice(-minorUnitExponent)}`
|
|
64
|
+
: `${negative ? '-' : ''}${raw}`;
|
|
65
|
+
// Node 26's ECMA-402 implementation accepts a decimal string without
|
|
66
|
+
// coercing it through Number, preserving all safe-integer minor units.
|
|
67
|
+
return formatter.format(majorUnits);
|
|
68
|
+
}
|
|
69
|
+
/** Compact a postal address for read-only display. */
|
|
70
|
+
export function formatPartyAddress(address) {
|
|
71
|
+
if (!address)
|
|
72
|
+
return '';
|
|
73
|
+
return [
|
|
74
|
+
address.street1,
|
|
75
|
+
address.street2,
|
|
76
|
+
[address.city, address.state].filter(Boolean).join(', '),
|
|
77
|
+
address.postalCode,
|
|
78
|
+
address.country,
|
|
79
|
+
]
|
|
80
|
+
.filter(Boolean)
|
|
81
|
+
.join('\n');
|
|
82
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Checkbox } from '@happyvertical/smrt-ui/forms';
|
|
3
|
+
import InvoiceAllocationFields from '../components/InvoiceAllocationFields.svelte';
|
|
4
|
+
import InvoiceEditor from '../components/InvoiceEditor.svelte';
|
|
5
|
+
import {
|
|
6
|
+
invoiceFieldNames,
|
|
7
|
+
invoiceLineFieldNames,
|
|
8
|
+
} from '../invoices/fields.js';
|
|
9
|
+
import type {
|
|
10
|
+
InvoiceAllocationDraft,
|
|
11
|
+
InvoiceDraftValues,
|
|
12
|
+
} from '../invoices/types.js';
|
|
13
|
+
|
|
14
|
+
let values = $state<InvoiceDraftValues>({
|
|
15
|
+
customerId: 'customer',
|
|
16
|
+
issuedOn: '2026-10-03',
|
|
17
|
+
dueOn: '2026-11-03',
|
|
18
|
+
currency: 'CAD',
|
|
19
|
+
paymentTerms: 'Net 30',
|
|
20
|
+
taxRate: '5',
|
|
21
|
+
lines: [
|
|
22
|
+
{
|
|
23
|
+
key: 'first',
|
|
24
|
+
description: 'Consulting services',
|
|
25
|
+
sku: 'SERVICE',
|
|
26
|
+
quantity: '1.5',
|
|
27
|
+
unitPrice: '100.00',
|
|
28
|
+
discountType: 'percent',
|
|
29
|
+
discountValue: '10',
|
|
30
|
+
taxMode: 'inherit',
|
|
31
|
+
taxRate: '0',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
let allocations = $state<InvoiceAllocationDraft[]>([
|
|
36
|
+
{ key: 'allocation', sourceId: 'reviewed-expense', amount: '125.00' },
|
|
37
|
+
]);
|
|
38
|
+
let mayReadSources = $state(true);
|
|
39
|
+
let canEdit = $state(true);
|
|
40
|
+
let message = $state('');
|
|
41
|
+
let sequence = 1;
|
|
42
|
+
function submit(event: SubmitEvent & { currentTarget: HTMLFormElement }) {
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
const data = new FormData(event.currentTarget, event.submitter);
|
|
45
|
+
const text = (name: string) => String(data.get(name) ?? '');
|
|
46
|
+
values = {
|
|
47
|
+
...values,
|
|
48
|
+
...Object.fromEntries(
|
|
49
|
+
Object.entries(invoiceFieldNames)
|
|
50
|
+
.filter(([key]) => key !== 'intent')
|
|
51
|
+
.map(([key, name]) => [key, text(name)]),
|
|
52
|
+
),
|
|
53
|
+
lines: data
|
|
54
|
+
.getAll('lineKey')
|
|
55
|
+
.map(
|
|
56
|
+
(_, index) =>
|
|
57
|
+
Object.fromEntries(
|
|
58
|
+
Object.entries(invoiceLineFieldNames).map(([key, name]) => [
|
|
59
|
+
key,
|
|
60
|
+
String(data.getAll(name)[index] ?? ''),
|
|
61
|
+
]),
|
|
62
|
+
) as unknown as InvoiceDraftValues['lines'][number],
|
|
63
|
+
),
|
|
64
|
+
};
|
|
65
|
+
allocations = data.getAll('sourceId').map((sourceId, index) => ({
|
|
66
|
+
key: allocations[index]?.key ?? `allocation-${sequence++}`,
|
|
67
|
+
sourceId: String(sourceId),
|
|
68
|
+
amount: String(data.getAll('allocationAmount')[index] ?? ''),
|
|
69
|
+
remove: data.getAll('removeRow').includes(String(index)),
|
|
70
|
+
}));
|
|
71
|
+
const intent = text('intent');
|
|
72
|
+
if (intent === 'addLine')
|
|
73
|
+
values = {
|
|
74
|
+
...values,
|
|
75
|
+
lines: [
|
|
76
|
+
...values.lines,
|
|
77
|
+
{
|
|
78
|
+
key: `line-${sequence++}`,
|
|
79
|
+
description: '',
|
|
80
|
+
sku: '',
|
|
81
|
+
quantity: '1',
|
|
82
|
+
unitPrice: '',
|
|
83
|
+
discountType: 'flat',
|
|
84
|
+
discountValue: '0',
|
|
85
|
+
taxMode: 'inherit',
|
|
86
|
+
taxRate: '0',
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
else if (intent.startsWith('removeLine:'))
|
|
91
|
+
values = {
|
|
92
|
+
...values,
|
|
93
|
+
lines: values.lines.filter(
|
|
94
|
+
(line) => line.key !== intent.slice('removeLine:'.length),
|
|
95
|
+
),
|
|
96
|
+
};
|
|
97
|
+
else if (intent === 'addAllocation')
|
|
98
|
+
allocations = [
|
|
99
|
+
...allocations,
|
|
100
|
+
{ key: `allocation-${sequence++}`, sourceId: '', amount: '' },
|
|
101
|
+
];
|
|
102
|
+
else
|
|
103
|
+
message =
|
|
104
|
+
'Example server rejection: entries and request token retained. The server revalidates customer, prices and tax before saving.';
|
|
105
|
+
}
|
|
106
|
+
</script>
|
|
107
|
+
<div class="preview">
|
|
108
|
+
<Checkbox label="May read allocation sources" bind:checked={mayReadSources} />
|
|
109
|
+
<Checkbox label="May edit invoice" bind:checked={canEdit} />
|
|
110
|
+
<InvoiceEditor action="" {values} {canEdit} {message} customers={[{ id: 'customer', label: 'Example customer' }]} hiddenFields={[{ name: 'requestId', value: 'demo-request-retained' }]} onsubmit={submit}>
|
|
111
|
+
{#snippet children(current)}
|
|
112
|
+
<InvoiceAllocationFields currency={current.currency} {allocations} {canEdit} {mayReadSources} sources={[{ id: 'reviewed-expense', label: 'Reviewed supplier expense', availableMinor: 25000 }]} />
|
|
113
|
+
{/snippet}
|
|
114
|
+
</InvoiceEditor>
|
|
115
|
+
</div>
|
|
116
|
+
<style>.preview { display: grid; gap: var(--smrt-spacing-4); }</style>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const InvoicePreparationPreview: import("svelte").Component<Record<string, never>, {}, "">;
|
|
2
|
+
type InvoicePreparationPreview = ReturnType<typeof InvoicePreparationPreview>;
|
|
3
|
+
export default InvoicePreparationPreview;
|
|
4
|
+
//# sourceMappingURL=InvoicePreparationPreview.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvoicePreparationPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/InvoicePreparationPreview.svelte.ts"],"names":[],"mappings":"AAgIA,QAAA,MAAM,yBAAyB,2DAAwC,CAAC;AACxE,KAAK,yBAAyB,GAAG,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC9E,eAAe,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useI18n } from '@happyvertical/smrt-ui/i18n';
|
|
3
|
+
import CustomerForm from '../components/CustomerForm.svelte';
|
|
4
|
+
import VendorForm from '../components/VendorForm.svelte';
|
|
5
|
+
import { M } from '../i18n.js';
|
|
6
|
+
import type {
|
|
7
|
+
CustomerFormValues,
|
|
8
|
+
PartyAddressData,
|
|
9
|
+
PartyContactData,
|
|
10
|
+
PartyFormErrors,
|
|
11
|
+
VendorFormValues,
|
|
12
|
+
} from '../party-types.js';
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
/** Selects the in-memory customer or vendor form demonstration. */
|
|
16
|
+
kind: 'customer' | 'vendor';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let { kind }: Props = $props();
|
|
20
|
+
const { t } = useI18n();
|
|
21
|
+
let errors = $state<PartyFormErrors>({});
|
|
22
|
+
let customerValues = $state<CustomerFormValues>({
|
|
23
|
+
profileId: 'profile-riverstone',
|
|
24
|
+
identityKind: 'business',
|
|
25
|
+
name: 'Riverstone Newsroom',
|
|
26
|
+
email: 'accounts@riverstone.example',
|
|
27
|
+
status: 'active',
|
|
28
|
+
customerType: 'wholesale',
|
|
29
|
+
creditLimit: '2500.00',
|
|
30
|
+
paymentTerms: 'Net 30',
|
|
31
|
+
shippingAddress: {
|
|
32
|
+
street1: '100 Main Street',
|
|
33
|
+
city: 'Vancouver',
|
|
34
|
+
state: 'BC',
|
|
35
|
+
postalCode: 'V6B 1A1',
|
|
36
|
+
country: 'CA',
|
|
37
|
+
},
|
|
38
|
+
contacts: [
|
|
39
|
+
{
|
|
40
|
+
id: 'contact-avery',
|
|
41
|
+
name: 'Avery Chen',
|
|
42
|
+
label: 'Accounts payable',
|
|
43
|
+
email: 'avery@riverstone.example',
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
let vendorValues = $state<VendorFormValues>({
|
|
48
|
+
profileId: 'profile-northstar',
|
|
49
|
+
identityKind: 'business',
|
|
50
|
+
name: 'Northstar Supply',
|
|
51
|
+
email: 'orders@northstar.example',
|
|
52
|
+
status: 'active',
|
|
53
|
+
leadTimeDays: '7',
|
|
54
|
+
minimumOrder: '500.00',
|
|
55
|
+
currency: 'CAD',
|
|
56
|
+
paymentTerms: 'Net 45',
|
|
57
|
+
contacts: [
|
|
58
|
+
{
|
|
59
|
+
id: 'contact-morgan',
|
|
60
|
+
name: 'Morgan Lee',
|
|
61
|
+
label: 'Order desk',
|
|
62
|
+
email: 'morgan@northstar.example',
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
function field(data: FormData, name: string): string {
|
|
68
|
+
return String(data.get(name) ?? '');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function contacts(data: FormData): PartyContactData[] {
|
|
72
|
+
const ids = data.getAll('contactId');
|
|
73
|
+
const names = data.getAll('contactName');
|
|
74
|
+
const labels = data.getAll('contactLabel');
|
|
75
|
+
const emails = data.getAll('contactEmail');
|
|
76
|
+
const phones = data.getAll('contactPhone');
|
|
77
|
+
const addresses = data.getAll('contactAddress');
|
|
78
|
+
return names.map((name, index) => ({
|
|
79
|
+
id: String(ids[index] ?? ''),
|
|
80
|
+
name: String(name),
|
|
81
|
+
label: String(labels[index] ?? ''),
|
|
82
|
+
email: String(emails[index] ?? ''),
|
|
83
|
+
phone: String(phones[index] ?? ''),
|
|
84
|
+
address: String(addresses[index] ?? ''),
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function address(
|
|
89
|
+
data: FormData,
|
|
90
|
+
prefix: 'shipping' | 'billing',
|
|
91
|
+
): PartyAddressData {
|
|
92
|
+
return {
|
|
93
|
+
street1: field(data, `${prefix}Street1`),
|
|
94
|
+
street2: field(data, `${prefix}Street2`),
|
|
95
|
+
city: field(data, `${prefix}City`),
|
|
96
|
+
state: field(data, `${prefix}State`),
|
|
97
|
+
postalCode: field(data, `${prefix}PostalCode`),
|
|
98
|
+
country: field(data, `${prefix}Country`),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function retainedCustomer(data: FormData): CustomerFormValues {
|
|
103
|
+
return {
|
|
104
|
+
...customerValues,
|
|
105
|
+
identityKind: field(
|
|
106
|
+
data,
|
|
107
|
+
'identityKind',
|
|
108
|
+
) as CustomerFormValues['identityKind'],
|
|
109
|
+
name: field(data, 'name'),
|
|
110
|
+
email: field(data, 'email'),
|
|
111
|
+
description: field(data, 'description'),
|
|
112
|
+
status: field(data, 'status'),
|
|
113
|
+
customerType: field(data, 'customerType'),
|
|
114
|
+
creditLimit: field(data, 'creditLimit'),
|
|
115
|
+
paymentTerms: field(data, 'paymentTerms'),
|
|
116
|
+
taxExempt: data.has('taxExempt'),
|
|
117
|
+
notes: field(data, 'notes'),
|
|
118
|
+
shippingAddress: address(data, 'shipping'),
|
|
119
|
+
billingAddress: address(data, 'billing'),
|
|
120
|
+
contacts: contacts(data),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function retainedVendor(data: FormData): VendorFormValues {
|
|
125
|
+
return {
|
|
126
|
+
...vendorValues,
|
|
127
|
+
identityKind: field(
|
|
128
|
+
data,
|
|
129
|
+
'identityKind',
|
|
130
|
+
) as VendorFormValues['identityKind'],
|
|
131
|
+
name: field(data, 'name'),
|
|
132
|
+
email: field(data, 'email'),
|
|
133
|
+
description: field(data, 'description'),
|
|
134
|
+
status: field(data, 'status'),
|
|
135
|
+
leadTimeDays: field(data, 'leadTimeDays'),
|
|
136
|
+
minimumOrder: field(data, 'minimumOrder'),
|
|
137
|
+
currency: field(data, 'currency'),
|
|
138
|
+
paymentTerms: field(data, 'paymentTerms'),
|
|
139
|
+
defaultContactEmail: field(data, 'defaultContactEmail'),
|
|
140
|
+
defaultContactPhone: field(data, 'defaultContactPhone'),
|
|
141
|
+
notes: field(data, 'notes'),
|
|
142
|
+
contacts: contacts(data),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function applyIntent(intent: string): void {
|
|
147
|
+
const current =
|
|
148
|
+
kind === 'customer'
|
|
149
|
+
? (customerValues.contacts ?? [])
|
|
150
|
+
: (vendorValues.contacts ?? []);
|
|
151
|
+
if (intent === 'addContact') {
|
|
152
|
+
const next = [...current, { id: `demo-contact-${current.length + 1}` }];
|
|
153
|
+
if (kind === 'customer')
|
|
154
|
+
customerValues = { ...customerValues, contacts: next };
|
|
155
|
+
else vendorValues = { ...vendorValues, contacts: next };
|
|
156
|
+
errors = { form: t(M['commerce.party.demo_contact_added']) };
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (intent.startsWith('removeContact:')) {
|
|
160
|
+
const index = Number(intent.slice('removeContact:'.length));
|
|
161
|
+
const next = current.filter((_, contactIndex) => contactIndex !== index);
|
|
162
|
+
if (kind === 'customer')
|
|
163
|
+
customerValues = { ...customerValues, contacts: next };
|
|
164
|
+
else vendorValues = { ...vendorValues, contacts: next };
|
|
165
|
+
errors = { form: t(M['commerce.party.demo_contact_removed']) };
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
errors = {
|
|
169
|
+
form: t(M['commerce.party.demo_rejected']),
|
|
170
|
+
fields: {
|
|
171
|
+
[kind === 'customer' ? 'creditLimit' : 'minimumOrder']: t(
|
|
172
|
+
M['commerce.party.demo_invalid_amount'],
|
|
173
|
+
),
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function handleSubmit(event: SubmitEvent): void {
|
|
179
|
+
event.preventDefault();
|
|
180
|
+
const form = event.target as HTMLFormElement;
|
|
181
|
+
const data = new FormData(form);
|
|
182
|
+
if (kind === 'customer') customerValues = retainedCustomer(data);
|
|
183
|
+
else vendorValues = retainedVendor(data);
|
|
184
|
+
const submitter = event.submitter as HTMLButtonElement | null;
|
|
185
|
+
applyIntent(submitter?.value ?? 'save');
|
|
186
|
+
}
|
|
187
|
+
</script>
|
|
188
|
+
|
|
189
|
+
<div class="party-form-preview" onsubmit={handleSubmit}>
|
|
190
|
+
{#if kind === 'customer'}
|
|
191
|
+
<CustomerForm
|
|
192
|
+
mode="edit"
|
|
193
|
+
values={customerValues}
|
|
194
|
+
{errors}
|
|
195
|
+
transport={{
|
|
196
|
+
action: '?/customer-demo',
|
|
197
|
+
hiddenFields: { requestId: 'demo-request' },
|
|
198
|
+
}}
|
|
199
|
+
/>
|
|
200
|
+
{:else}
|
|
201
|
+
<VendorForm
|
|
202
|
+
mode="edit"
|
|
203
|
+
values={vendorValues}
|
|
204
|
+
{errors}
|
|
205
|
+
transport={{
|
|
206
|
+
action: '?/vendor-demo',
|
|
207
|
+
hiddenFields: { expectedTenantId: 'tenant-demo' },
|
|
208
|
+
}}
|
|
209
|
+
/>
|
|
210
|
+
{/if}
|
|
211
|
+
</div>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/** Selects the in-memory customer or vendor form demonstration. */
|
|
3
|
+
kind: 'customer' | 'vendor';
|
|
4
|
+
}
|
|
5
|
+
declare const PartyFormPreview: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type PartyFormPreview = ReturnType<typeof PartyFormPreview>;
|
|
7
|
+
export default PartyFormPreview;
|
|
8
|
+
//# sourceMappingURL=PartyFormPreview.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PartyFormPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/PartyFormPreview.svelte.ts"],"names":[],"mappings":"AAgBA,UAAU,KAAK;IACb,mEAAmE;IACnE,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAC;CAC7B;AAmMD,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
|