@merchi/sdk 1.42.14 → 1.42.16
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/dist/constants/auto_assign_production_on_actions.d.ts +6 -0
- package/dist/constants/call_to_actions.d.ts +14 -0
- package/dist/constants/call_to_actions.test.d.ts +1 -0
- package/dist/constants/discount_types.d.ts +5 -0
- package/dist/constants/discount_types.test.d.ts +1 -0
- package/dist/constants/domain_types.d.ts +12 -0
- package/dist/constants/domain_types.test.d.ts +1 -0
- package/dist/constants/errors.d.ts +26 -0
- package/dist/constants/event_types.d.ts +5 -0
- package/dist/constants/event_types.test.d.ts +1 -0
- package/dist/constants/field_types.d.ts +18 -0
- package/dist/constants/field_types.js +1 -0
- package/dist/constants/field_types.test.d.ts +1 -0
- package/dist/constants/index.d.ts +25 -0
- package/dist/constants/input_types.d.ts +13 -0
- package/dist/constants/input_types.test.d.ts +1 -0
- package/dist/constants/inventory_status.test.d.ts +1 -0
- package/dist/constants/inventory_statuses.d.ts +6 -0
- package/dist/constants/invoice_types.d.ts +5 -0
- package/dist/constants/invoice_types.test.d.ts +1 -0
- package/dist/constants/item_types.d.ts +5 -0
- package/dist/constants/item_types.test.d.ts +1 -0
- package/dist/constants/job/drafting_status.d.ts +7 -0
- package/dist/constants/job/drafting_status.test.d.ts +1 -0
- package/dist/constants/job/payment_status.d.ts +7 -0
- package/dist/constants/job/payment_status.test.d.ts +1 -0
- package/dist/constants/job/production_status.d.ts +12 -0
- package/dist/constants/job/production_status.test.d.ts +1 -0
- package/dist/constants/job/shipment_status.d.ts +11 -0
- package/dist/constants/job/shipment_status.test.d.ts +1 -0
- package/dist/constants/job/supply_chain_request_status.d.ts +6 -0
- package/dist/constants/job/supply_chain_request_status.test.d.ts +1 -0
- package/dist/constants/job_priorities.d.ts +6 -0
- package/dist/constants/job_priorities.test.d.ts +1 -0
- package/dist/constants/job_status.d.ts +45 -0
- package/dist/constants/job_status.test.d.ts +1 -0
- package/dist/constants/job_types.d.ts +16 -0
- package/dist/constants/job_types.test.d.ts +1 -0
- package/dist/constants/notification_sections.d.ts +13 -0
- package/dist/constants/notification_sections.test.d.ts +1 -0
- package/dist/constants/notification_types.d.ts +101 -0
- package/dist/constants/notification_types.test.d.ts +1 -0
- package/dist/constants/notification_urgencies.d.ts +6 -0
- package/dist/constants/notification_urgencies.test.d.ts +1 -0
- package/dist/constants/payment_types.d.ts +10 -0
- package/dist/constants/payment_types.test.d.ts +1 -0
- package/dist/constants/platform.d.ts +5 -0
- package/dist/constants/platform.test.d.ts +1 -0
- package/dist/constants/product_types.d.ts +26 -0
- package/dist/constants/product_types.test.d.ts +1 -0
- package/dist/constants/rights.d.ts +5 -0
- package/dist/constants/rights.test.d.ts +1 -0
- package/dist/constants/robots_meta_directives.d.ts +1 -0
- package/dist/constants/robots_meta_directives.test.d.ts +1 -0
- package/dist/constants/roles.d.ts +20 -0
- package/dist/constants/roles.test.d.ts +1 -0
- package/dist/constants/shipment_companies.d.ts +19 -0
- package/dist/constants/shipment_companies.test.d.ts +1 -0
- package/dist/constants/shipment_services.d.ts +3 -0
- package/dist/constants/shipment_services.test.d.ts +1 -0
- package/dist/constants/system_roles.d.ts +3 -0
- package/dist/constants/system_roles.test.d.ts +1 -0
- package/dist/constants/theme_status.d.ts +5 -0
- package/dist/constants/theme_status.test.d.ts +1 -0
- package/dist/constants/user_types.d.ts +17 -0
- package/dist/constants/user_types.test.d.ts +1 -0
- package/dist/constants/white_label_accessibilities.d.ts +5 -0
- package/dist/constants/white_label_accessibilities.test.d.ts +1 -0
- package/dist/cookie.d.ts +1 -0
- package/dist/cookie.test.d.ts +1 -0
- package/dist/entities/address.d.ts +30 -0
- package/dist/entities/address.test.d.ts +1 -0
- package/dist/entities/agent_conversation.d.ts +18 -0
- package/dist/entities/agent_conversation.test.d.ts +1 -0
- package/dist/entities/agent_skill.d.ts +33 -0
- package/dist/entities/agent_skill.test.d.ts +1 -0
- package/dist/entities/agent_skill_approval.d.ts +13 -0
- package/dist/entities/agent_skill_version.d.ts +18 -0
- package/dist/entities/agent_token_analytics.d.ts +50 -0
- package/dist/entities/agent_token_usage.d.ts +31 -0
- package/dist/entities/agent_token_usage.test.d.ts +1 -0
- package/dist/entities/assignment.d.ts +40 -0
- package/dist/entities/assignment.test.d.ts +1 -0
- package/dist/entities/automatic_payment_relationship.d.ts +14 -0
- package/dist/entities/automatic_payment_relationship.test.d.ts +1 -0
- package/dist/entities/bank.d.ts +20 -0
- package/dist/entities/bank.test.d.ts +1 -0
- package/dist/entities/cart.d.ts +50 -0
- package/dist/entities/cart.test.d.ts +1 -0
- package/dist/entities/cart_item.d.ts +33 -0
- package/dist/entities/cart_item.test.d.ts +1 -0
- package/dist/entities/cart_shipment_group.d.ts +12 -0
- package/dist/entities/cart_shipment_quote.d.ts +16 -0
- package/dist/entities/category.d.ts +26 -0
- package/dist/entities/category.test.d.ts +1 -0
- package/dist/entities/company.d.ts +137 -0
- package/dist/entities/company.test.d.ts +1 -0
- package/dist/entities/company_invitation.d.ts +16 -0
- package/dist/entities/company_invitation.test.d.ts +1 -0
- package/dist/entities/country_tax.d.ts +20 -0
- package/dist/entities/country_tax.test.d.ts +1 -0
- package/dist/entities/discount.d.ts +19 -0
- package/dist/entities/discount.test.d.ts +1 -0
- package/dist/entities/discount_group.d.ts +20 -0
- package/dist/entities/discount_group.test.d.ts +1 -0
- package/dist/entities/domain.d.ts +629 -0
- package/dist/entities/domain.test.d.ts +1 -0
- package/dist/entities/domain_chat_settings.d.ts +33 -0
- package/dist/entities/domain_chat_settings.test.d.ts +1 -0
- package/dist/entities/domain_invitation.d.ts +17 -0
- package/dist/entities/domain_invitation.test.d.ts +1 -0
- package/dist/entities/domain_tag.d.ts +21 -0
- package/dist/entities/domain_tag.test.d.ts +1 -0
- package/dist/entities/draft.d.ts +31 -0
- package/dist/entities/draft.test.d.ts +1 -0
- package/dist/entities/draft_comment.d.ts +28 -0
- package/dist/entities/draft_comment.test.d.ts +1 -0
- package/dist/entities/draft_preview.d.ts +18 -0
- package/dist/entities/draft_preview.test.d.ts +1 -0
- package/dist/entities/draft_preview_layer.d.ts +12 -0
- package/dist/entities/draft_preview_layer.test.d.ts +1 -0
- package/dist/entities/draft_template.d.ts +31 -0
- package/dist/entities/draft_template.js +8 -0
- package/dist/entities/draft_template.test.d.ts +1 -0
- package/dist/entities/email_address.d.ts +13 -0
- package/dist/entities/email_address.test.d.ts +1 -0
- package/dist/entities/email_counter.d.ts +11 -0
- package/dist/entities/email_counter.test.d.ts +1 -0
- package/dist/entities/enrolled_domain.d.ts +16 -0
- package/dist/entities/enrolled_domain.test.d.ts +1 -0
- package/dist/entities/exchange_rate.d.ts +11 -0
- package/dist/entities/exchange_rate.test.d.ts +1 -0
- package/dist/entities/file.d.ts +65 -0
- package/dist/entities/file.test.d.ts +1 -0
- package/dist/entities/internal_tag.d.ts +26 -0
- package/dist/entities/internal_tag.test.d.ts +1 -0
- package/dist/entities/inventory.d.ts +27 -0
- package/dist/entities/inventory.test.d.ts +1 -0
- package/dist/entities/inventory_group.d.ts +19 -0
- package/dist/entities/inventory_group.test.d.ts +1 -0
- package/dist/entities/inventory_unit_variation.d.ts +13 -0
- package/dist/entities/inventory_unit_variation.test.d.ts +1 -0
- package/dist/entities/invoice.d.ts +80 -0
- package/dist/entities/invoice.test.d.ts +1 -0
- package/dist/entities/item.d.ts +24 -0
- package/dist/entities/item.test.d.ts +1 -0
- package/dist/entities/job.d.ts +156 -0
- package/dist/entities/job.test.d.ts +1 -0
- package/dist/entities/job_comment.d.ts +24 -0
- package/dist/entities/job_comment.test.d.ts +1 -0
- package/dist/entities/job_note.d.ts +19 -0
- package/dist/entities/job_operation_log.d.ts +18 -0
- package/dist/entities/job_operation_log.test.d.ts +1 -0
- package/dist/entities/matching_inventory.d.ts +16 -0
- package/dist/entities/notification.d.ts +47 -0
- package/dist/entities/notification.test.d.ts +1 -0
- package/dist/entities/payment.d.ts +28 -0
- package/dist/entities/payment.test.d.ts +1 -0
- package/dist/entities/payment_device.d.ts +14 -0
- package/dist/entities/payment_device.test.d.ts +1 -0
- package/dist/entities/phone_number.d.ts +17 -0
- package/dist/entities/phone_number.test.d.ts +1 -0
- package/dist/entities/product.d.ts +148 -0
- package/dist/entities/product.test.d.ts +1 -0
- package/dist/entities/product_form.d.ts +22 -0
- package/dist/entities/product_form_version.d.ts +20 -0
- package/dist/entities/product_review.d.ts +74 -0
- package/dist/entities/production_comment.d.ts +24 -0
- package/dist/entities/production_comment.test.d.ts +1 -0
- package/dist/entities/quote.d.ts +29 -0
- package/dist/entities/quote.test.d.ts +1 -0
- package/dist/entities/quote_item.d.ts +24 -0
- package/dist/entities/quote_item.test.d.ts +1 -0
- package/dist/entities/reminder.d.ts +35 -0
- package/dist/entities/reminder.test.d.ts +1 -0
- package/dist/entities/session.d.ts +15 -0
- package/dist/entities/session.test.d.ts +1 -0
- package/dist/entities/shipment.d.ts +76 -0
- package/dist/entities/shipment.test.d.ts +1 -0
- package/dist/entities/shipment_item.d.ts +10 -0
- package/dist/entities/shipment_item.test.d.ts +1 -0
- package/dist/entities/shipment_item_fulfillment.d.ts +10 -0
- package/dist/entities/shipment_item_fulfillment.test.d.ts +1 -0
- package/dist/entities/shipment_log.d.ts +15 -0
- package/dist/entities/shipment_method.d.ts +28 -0
- package/dist/entities/shipment_method.test.d.ts +1 -0
- package/dist/entities/shipment_method_variation.d.ts +18 -0
- package/dist/entities/shipment_method_variation.test.d.ts +1 -0
- package/dist/entities/short_url.d.ts +17 -0
- package/dist/entities/short_url.test.d.ts +1 -0
- package/dist/entities/subscription_plan.d.ts +30 -0
- package/dist/entities/subscription_plan.test.d.ts +1 -0
- package/dist/entities/supply_domain.d.ts +14 -0
- package/dist/entities/supply_domain.test.d.ts +1 -0
- package/dist/entities/support_conversation.d.ts +30 -0
- package/dist/entities/support_conversation.test.d.ts +1 -0
- package/dist/entities/support_message.d.ts +15 -0
- package/dist/entities/support_message.test.d.ts +1 -0
- package/dist/entities/system_role.d.ts +10 -0
- package/dist/entities/system_role.test.d.ts +1 -0
- package/dist/entities/theme.d.ts +26 -0
- package/dist/entities/theme.test.d.ts +1 -0
- package/dist/entities/theme_css_setting.d.ts +12 -0
- package/dist/entities/theme_css_setting.test.d.ts +1 -0
- package/dist/entities/user.d.ts +142 -0
- package/dist/entities/user.test.d.ts +1 -0
- package/dist/entities/user_company.d.ts +14 -0
- package/dist/entities/user_company.test.d.ts +1 -0
- package/dist/entities/variation.d.ts +29 -0
- package/dist/entities/variation.test.d.ts +1 -0
- package/dist/entities/variation_field.d.ts +87 -0
- package/dist/entities/variation_field.js +33 -0
- package/dist/entities/variation_field.test.d.ts +1 -0
- package/dist/entities/variation_fields_option.d.ts +36 -0
- package/dist/entities/variation_fields_option.js +4 -0
- package/dist/entities/variation_fields_option.test.d.ts +1 -0
- package/dist/entities/variation_option.d.ts +23 -0
- package/dist/entities/variation_option.test.d.ts +1 -0
- package/dist/entities/variations_group.d.ts +20 -0
- package/dist/entities/variations_group.test.d.ts +1 -0
- package/dist/entity.d.ts +208 -0
- package/dist/entity.js +6 -4
- package/dist/index.d.ts +88 -0
- package/dist/merchi.d.ts +179 -0
- package/dist/merchi.test.d.ts +1 -0
- package/dist/pricing/discount.d.ts +2 -0
- package/dist/pricing/discount.test.d.ts +1 -0
- package/dist/pricing/estimate.d.ts +2 -0
- package/dist/pricing/estimate.js +56 -0
- package/dist/pricing/estimate.test.d.ts +1 -0
- package/dist/pricing/estimate.test.js +81 -0
- package/dist/pricing/golden.test.d.ts +1 -0
- package/dist/pricing/index.d.ts +7 -0
- package/dist/pricing/index.test.d.ts +1 -0
- package/dist/pricing/inventory.d.ts +2 -0
- package/dist/pricing/inventory.test.d.ts +1 -0
- package/dist/pricing/matrix.d.ts +10 -0
- package/dist/pricing/matrix.test.d.ts +1 -0
- package/dist/pricing/round.d.ts +13 -0
- package/dist/pricing/round.test.d.ts +1 -0
- package/dist/pricing/types.d.ts +137 -0
- package/dist/pricing/visibility.d.ts +3 -0
- package/dist/pricing/visibility.test.d.ts +1 -0
- package/dist/request.d.ts +56 -0
- package/dist/request.test.d.ts +1 -0
- package/dist/test_util.d.ts +3 -0
- package/dist/toasts.d.ts +14 -0
- package/dist/toasts.test.d.ts +1 -0
- package/dist/util/float.d.ts +1 -0
- package/dist/util/index.d.ts +3 -0
- package/dist/util/query_string.d.ts +1 -0
- package/dist/util/query_string.test.d.ts +1 -0
- package/dist/util/validation.d.ts +1 -0
- package/dist/util/validation.test.d.ts +1 -0
- package/dist/uuid.d.ts +1 -0
- package/dist/uuid.test.d.ts +1 -0
- package/package.json +2 -1
- package/src/constants/field_types.ts +1 -0
- package/src/entities/draft_template.ts +6 -0
- package/src/entities/variation_field.ts +25 -0
- package/src/entities/variation_fields_option.ts +3 -0
- package/src/entity.ts +6 -5
- package/src/pricing/estimate.test.ts +95 -0
- package/src/pricing/estimate.ts +73 -0
- package/src/pricing/types.ts +10 -0
- package/tsconfig.json +1 -0
package/dist/uuid.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateUUID(): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -41,6 +41,12 @@ export class DraftTemplate extends Entity {
|
|
|
41
41
|
@DraftTemplate.property()
|
|
42
42
|
public width?: number;
|
|
43
43
|
|
|
44
|
+
@DraftTemplate.property({type: Number})
|
|
45
|
+
public widthMm?: number | null;
|
|
46
|
+
|
|
47
|
+
@DraftTemplate.property({type: Number})
|
|
48
|
+
public heightMm?: number | null;
|
|
49
|
+
|
|
44
50
|
@DraftTemplate.property({type: MerchiFile})
|
|
45
51
|
public file?: MerchiFile;
|
|
46
52
|
|
|
@@ -192,6 +192,27 @@ export class VariationField extends Entity {
|
|
|
192
192
|
@VariationField.property({type: Number})
|
|
193
193
|
public aspectRatio?: number | null;
|
|
194
194
|
|
|
195
|
+
@VariationField.property()
|
|
196
|
+
public embroideryInputMode?: string;
|
|
197
|
+
|
|
198
|
+
@VariationField.property({type: Number})
|
|
199
|
+
public stitchDensity?: number;
|
|
200
|
+
|
|
201
|
+
@VariationField.property({type: Number})
|
|
202
|
+
public averageStitchLengthMm?: number;
|
|
203
|
+
|
|
204
|
+
@VariationField.property()
|
|
205
|
+
public stitchVariationCost?: number;
|
|
206
|
+
|
|
207
|
+
@VariationField.property({type: 'DiscountGroup'})
|
|
208
|
+
public stitchVariationCostDiscountGroup?: DiscountGroup | null;
|
|
209
|
+
|
|
210
|
+
@VariationField.property()
|
|
211
|
+
public stitchVariationUnitCost?: number;
|
|
212
|
+
|
|
213
|
+
@VariationField.property({type: 'DiscountGroup'})
|
|
214
|
+
public stitchVariationUnitCostDiscountGroup?: DiscountGroup | null;
|
|
215
|
+
|
|
195
216
|
@VariationField.property()
|
|
196
217
|
public product?: Product;
|
|
197
218
|
|
|
@@ -252,6 +273,10 @@ export class VariationField extends Entity {
|
|
|
252
273
|
} else if (this.fieldType === FieldType.AREA) {
|
|
253
274
|
result.value = this.defaultValue;
|
|
254
275
|
result.onceOffCost = 0;
|
|
276
|
+
} else if (this.fieldType === FieldType.EMBROIDERY) {
|
|
277
|
+
result.value = '';
|
|
278
|
+
result.onceOffCost = 0;
|
|
279
|
+
result.variationFiles = [];
|
|
255
280
|
} else if (this.isSelectable()) {
|
|
256
281
|
let onceOffCost = 0;
|
|
257
282
|
const value = [];
|
|
@@ -67,6 +67,9 @@ export class VariationFieldsOption extends Entity {
|
|
|
67
67
|
@VariationFieldsOption.property({type: MerchiFile})
|
|
68
68
|
public linkedFile?: MerchiFile | null;
|
|
69
69
|
|
|
70
|
+
@VariationFieldsOption.property({type: MerchiFile})
|
|
71
|
+
public linkedProductImage?: MerchiFile | null;
|
|
72
|
+
|
|
70
73
|
@VariationFieldsOption.property({arrayType: 'Variation'})
|
|
71
74
|
public selectedByVariations?: Variation[];
|
|
72
75
|
|
package/src/entity.ts
CHANGED
|
@@ -45,7 +45,7 @@ interface FromJsonOptions {
|
|
|
45
45
|
makeDirty?: boolean;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
interface CreateOptions {
|
|
48
|
+
export interface CreateOptions {
|
|
49
49
|
withRights?: boolean;
|
|
50
50
|
embed?: EmbedDescriptor;
|
|
51
51
|
}
|
|
@@ -862,10 +862,11 @@ export class Entity {
|
|
|
862
862
|
});
|
|
863
863
|
propertyInfo.currentValue = newValue;
|
|
864
864
|
} else if (this.isSingleEntityProperty(propertyInfo)) {
|
|
865
|
-
//
|
|
866
|
-
//
|
|
867
|
-
|
|
868
|
-
|
|
865
|
+
// null clears the link. An empty entity would omit the clear
|
|
866
|
+
// sentinel from toFormData, so the saved photo would stick.
|
|
867
|
+
if (value === null) {
|
|
868
|
+
propertyInfo.currentValue = null;
|
|
869
|
+
} else if (propertyInfo.currentValue) {
|
|
869
870
|
propertyInfo.currentValue.fromJson(value, options);
|
|
870
871
|
} else {
|
|
871
872
|
const nested = new (propertyInfo.type as any)(this.merchi);
|
|
@@ -555,3 +555,98 @@ test('group field visibility is scoped per group (no cross-group leak)', () => {
|
|
|
555
555
|
expect(r.groupCosts).toEqual([0, 5]);
|
|
556
556
|
expect(r.cost).toBe(5);
|
|
557
557
|
});
|
|
558
|
+
|
|
559
|
+
test('embroidery prices stitches and colours from the saved size', () => {
|
|
560
|
+
const rules: PricingRules = {
|
|
561
|
+
...base,
|
|
562
|
+
fields: [{
|
|
563
|
+
id: 16, originalId: 16, position: 0, fieldType: 16, independent: true,
|
|
564
|
+
isSelectable: false, selectedBy: [],
|
|
565
|
+
variationCost: 15, variationUnitCost: 0,
|
|
566
|
+
variationCostDiscountGroup: null, variationUnitCostDiscountGroup: null,
|
|
567
|
+
stitchDensity: 2.5,
|
|
568
|
+
stitchVariationCost: 12, stitchVariationUnitCost: 0.8,
|
|
569
|
+
stitchVariationCostDiscountGroup: null, stitchVariationUnitCostDiscountGroup: null,
|
|
570
|
+
colourVariationCost: 5, colourVariationUnitCost: 0.4,
|
|
571
|
+
colourVariationCostDiscountGroup: null, colourVariationUnitCostDiscountGroup: null,
|
|
572
|
+
options: [],
|
|
573
|
+
}],
|
|
574
|
+
};
|
|
575
|
+
const value = JSON.stringify({
|
|
576
|
+
text: 'ACME', widthMm: 80, heightMm: 40, colours: ['#111111', '#CC0000'], coverage: 0.5,
|
|
577
|
+
});
|
|
578
|
+
const r = estimateQuote(rules, {
|
|
579
|
+
quantity: 1,
|
|
580
|
+
fieldValues: { 16: { value, colourCount: 2, coverage: 0.5 } },
|
|
581
|
+
}) as QuoteResult;
|
|
582
|
+
expect(r.cost).toBe(87);
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
test('embroidery counts colours on the saved value when colourCount is omitted', () => {
|
|
586
|
+
const rules: PricingRules = {
|
|
587
|
+
...base,
|
|
588
|
+
fields: [{
|
|
589
|
+
id: 16, originalId: 16, position: 0, fieldType: 16, independent: true,
|
|
590
|
+
isSelectable: false, selectedBy: [],
|
|
591
|
+
variationCost: 15, variationUnitCost: 0,
|
|
592
|
+
variationCostDiscountGroup: null, variationUnitCostDiscountGroup: null,
|
|
593
|
+
stitchDensity: 2.5,
|
|
594
|
+
stitchVariationCost: 12, stitchVariationUnitCost: 0.8,
|
|
595
|
+
stitchVariationCostDiscountGroup: null, stitchVariationUnitCostDiscountGroup: null,
|
|
596
|
+
colourVariationCost: 5, colourVariationUnitCost: 0.4,
|
|
597
|
+
colourVariationCostDiscountGroup: null, colourVariationUnitCostDiscountGroup: null,
|
|
598
|
+
options: [],
|
|
599
|
+
}],
|
|
600
|
+
};
|
|
601
|
+
const value = JSON.stringify({
|
|
602
|
+
text: 'ACME', widthMm: 80, heightMm: 40, colours: ['#111111', '#CC0000'], coverage: 0.5,
|
|
603
|
+
});
|
|
604
|
+
const r = estimateQuote(rules, {
|
|
605
|
+
quantity: 1,
|
|
606
|
+
fieldValues: { 16: { value, coverage: 0.5 } },
|
|
607
|
+
}) as QuoteResult;
|
|
608
|
+
expect(r.cost).toBe(87);
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
test('embroidery ignores a null or non-array colour list', () => {
|
|
612
|
+
const rules: PricingRules = {
|
|
613
|
+
...base,
|
|
614
|
+
fields: [{
|
|
615
|
+
id: 16, originalId: 16, position: 0, fieldType: 16, independent: true,
|
|
616
|
+
isSelectable: false, selectedBy: [],
|
|
617
|
+
variationCost: 15, variationUnitCost: 0,
|
|
618
|
+
variationCostDiscountGroup: null, variationUnitCostDiscountGroup: null,
|
|
619
|
+
stitchDensity: 2.5,
|
|
620
|
+
stitchVariationCost: 12, stitchVariationUnitCost: 0.8,
|
|
621
|
+
stitchVariationCostDiscountGroup: null, stitchVariationUnitCostDiscountGroup: null,
|
|
622
|
+
colourVariationCost: 5, colourVariationUnitCost: 0.4,
|
|
623
|
+
colourVariationCostDiscountGroup: null, colourVariationUnitCostDiscountGroup: null,
|
|
624
|
+
options: [],
|
|
625
|
+
}],
|
|
626
|
+
};
|
|
627
|
+
const missing = estimateQuote(rules, {
|
|
628
|
+
quantity: 1,
|
|
629
|
+
fieldValues: { 16: { value: null, colourCount: 2, coverage: 0.5 } },
|
|
630
|
+
}) as QuoteResult;
|
|
631
|
+
// No saved size, so the stitch price cannot be calculated.
|
|
632
|
+
expect(missing.cost).toBe(10);
|
|
633
|
+
|
|
634
|
+
const notColours = JSON.stringify({
|
|
635
|
+
text: 'ACME', widthMm: 80, heightMm: 40, colours: 'red', coverage: 0.5,
|
|
636
|
+
});
|
|
637
|
+
const uncounted = estimateQuote(rules, {
|
|
638
|
+
quantity: 1,
|
|
639
|
+
fieldValues: { 16: { value: notColours, coverage: 0.5 } },
|
|
640
|
+
}) as QuoteResult;
|
|
641
|
+
// 10 + 15 + 12*4 + 0.8*4 = 76.2; a non-array colour list adds no colour fee.
|
|
642
|
+
expect(uncounted.cost).toBe(76.2);
|
|
643
|
+
|
|
644
|
+
const explicitZero = JSON.stringify({
|
|
645
|
+
text: 'ACME', widthMm: 80, heightMm: 40, colours: ['#111111', '#CC0000'], coverage: 0.5,
|
|
646
|
+
});
|
|
647
|
+
const zero = estimateQuote(rules, {
|
|
648
|
+
quantity: 1,
|
|
649
|
+
fieldValues: { 16: { value: explicitZero, colourCount: 0, coverage: 0.5 } },
|
|
650
|
+
}) as QuoteResult;
|
|
651
|
+
expect(zero.cost).toBe(76.2);
|
|
652
|
+
});
|
package/src/pricing/estimate.ts
CHANGED
|
@@ -183,6 +183,76 @@ function colourExtractCostFactor(
|
|
|
183
183
|
return { setup, unitList };
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
function parseEmbroidery(value: string | number | null | undefined): Record<string, any> | null {
|
|
187
|
+
if (value === undefined || value === null || value === '') return null;
|
|
188
|
+
try {
|
|
189
|
+
const parsed = JSON.parse(String(value));
|
|
190
|
+
return parsed && typeof parsed === 'object' ? parsed : null;
|
|
191
|
+
} catch {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function embroideryCostFactor(
|
|
197
|
+
field: PricingField,
|
|
198
|
+
sel: FieldSelection | undefined,
|
|
199
|
+
groupQuantities: number[]
|
|
200
|
+
): { setup: number; unitList: number[] } {
|
|
201
|
+
const n = groupQuantities.length;
|
|
202
|
+
const zeros = { setup: 0, unitList: new Array(n).fill(0) };
|
|
203
|
+
const parsed = parseEmbroidery(sel?.value ?? null);
|
|
204
|
+
const width = Number(parsed?.widthMm);
|
|
205
|
+
const height = Number(parsed?.heightMm);
|
|
206
|
+
const coverage = Number(sel?.coverage ?? parsed?.coverage);
|
|
207
|
+
// An explicit colourCount, including 0, wins. Otherwise count the saved
|
|
208
|
+
// colour list. A null value or a non-array list contributes no colours.
|
|
209
|
+
const savedColours = parsed?.colours;
|
|
210
|
+
const colourCount = Number(
|
|
211
|
+
sel?.colourCount ?? (Array.isArray(savedColours) ? savedColours.length : 0)
|
|
212
|
+
);
|
|
213
|
+
const hasDesign = Boolean(String(parsed?.text || '').trim()) || Boolean(sel?.hasFiles) || colourCount > 0;
|
|
214
|
+
if (!(width > 0) || !(height > 0) || !(coverage > 0) || !hasDesign) return zeros;
|
|
215
|
+
|
|
216
|
+
const density = Number(field.stitchDensity) > 0 ? Number(field.stitchDensity) : 2.5;
|
|
217
|
+
const thousands = Math.round(width * height * coverage * density) / 1000;
|
|
218
|
+
const totalQty = groupQuantities.reduce((a, b) => a + b, 0);
|
|
219
|
+
let setup = variationSetupCost(field, totalQty);
|
|
220
|
+
const unitList = variationUnitCosts(field, groupQuantities);
|
|
221
|
+
const stitchSetup = variationSetupCost(
|
|
222
|
+
{
|
|
223
|
+
variationCost: field.stitchVariationCost || 0,
|
|
224
|
+
variationCostDiscountGroup: field.stitchVariationCostDiscountGroup ?? null,
|
|
225
|
+
},
|
|
226
|
+
totalQty
|
|
227
|
+
);
|
|
228
|
+
const stitchUnits = variationUnitCosts(
|
|
229
|
+
{
|
|
230
|
+
variationUnitCost: field.stitchVariationUnitCost || 0,
|
|
231
|
+
variationUnitCostDiscountGroup: field.stitchVariationUnitCostDiscountGroup ?? null,
|
|
232
|
+
},
|
|
233
|
+
groupQuantities
|
|
234
|
+
);
|
|
235
|
+
const colourSetup = variationSetupCost(
|
|
236
|
+
{
|
|
237
|
+
variationCost: field.colourVariationCost || 0,
|
|
238
|
+
variationCostDiscountGroup: field.colourVariationCostDiscountGroup ?? null,
|
|
239
|
+
},
|
|
240
|
+
totalQty
|
|
241
|
+
);
|
|
242
|
+
const colourUnits = variationUnitCosts(
|
|
243
|
+
{
|
|
244
|
+
variationUnitCost: field.colourVariationUnitCost || 0,
|
|
245
|
+
variationUnitCostDiscountGroup: field.colourVariationUnitCostDiscountGroup ?? null,
|
|
246
|
+
},
|
|
247
|
+
groupQuantities
|
|
248
|
+
);
|
|
249
|
+
setup += stitchSetup * thousands + colourSetup * colourCount;
|
|
250
|
+
for (let i = 0; i < n; i++) {
|
|
251
|
+
unitList[i] += stitchUnits[i] * thousands + colourUnits[i] * colourCount;
|
|
252
|
+
}
|
|
253
|
+
return { setup, unitList };
|
|
254
|
+
}
|
|
255
|
+
|
|
186
256
|
function costFactor(
|
|
187
257
|
field: PricingField,
|
|
188
258
|
sel: FieldSelection | undefined,
|
|
@@ -196,6 +266,9 @@ function costFactor(
|
|
|
196
266
|
if (Number(field.fieldType) === FieldType.COLOUR_EXTRACT) {
|
|
197
267
|
return colourExtractCostFactor(field, sel, groupQuantities);
|
|
198
268
|
}
|
|
269
|
+
if (Number(field.fieldType) === FieldType.EMBROIDERY) {
|
|
270
|
+
return embroideryCostFactor(field, sel, groupQuantities);
|
|
271
|
+
}
|
|
199
272
|
if (isEmpty(field, sel)) {
|
|
200
273
|
return { setup: 0, unitList: new Array(n).fill(0) };
|
|
201
274
|
}
|
package/src/pricing/types.ts
CHANGED
|
@@ -50,6 +50,14 @@ export interface PricingField {
|
|
|
50
50
|
colourVariationUnitCost?: number;
|
|
51
51
|
colourVariationCostDiscountGroup?: DiscountGroup | null;
|
|
52
52
|
colourVariationUnitCostDiscountGroup?: DiscountGroup | null;
|
|
53
|
+
/** Embroidery (fieldType 16): per 1,000 stitches, plus the per-colour rates. */
|
|
54
|
+
embroideryInputMode?: 'text' | 'file' | string;
|
|
55
|
+
stitchDensity?: number;
|
|
56
|
+
averageStitchLengthMm?: number;
|
|
57
|
+
stitchVariationCost?: number;
|
|
58
|
+
stitchVariationUnitCost?: number;
|
|
59
|
+
stitchVariationCostDiscountGroup?: DiscountGroup | null;
|
|
60
|
+
stitchVariationUnitCostDiscountGroup?: DiscountGroup | null;
|
|
53
61
|
options: PricingOption[];
|
|
54
62
|
}
|
|
55
63
|
|
|
@@ -91,6 +99,8 @@ export interface FieldSelection {
|
|
|
91
99
|
colourCount?: number;
|
|
92
100
|
/** Colour extract: an artwork file is attached, even if no colour was kept. */
|
|
93
101
|
hasFiles?: boolean;
|
|
102
|
+
/** Embroidery: fraction of the size box that is ink. */
|
|
103
|
+
coverage?: number;
|
|
94
104
|
}
|
|
95
105
|
|
|
96
106
|
export interface GroupSelection {
|