@lancom/shared 0.0.432 → 0.0.434

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/assets/js/api/index.js +1 -1
  2. package/components/checkout/cart/cart.vue +1 -3
  3. package/components/checkout/cart/cart_entity/cart_entity_color_simple_products/cart-entity-color-simple-products.mixin.js +3 -1
  4. package/components/checkout/cart/cart_entity/cart_entity_color_simple_products/cart-entity-color-simple-products.scss +14 -2
  5. package/components/checkout/cart/cart_entity/cart_entity_color_simple_products/cart-entity-color-simple-products.vue +13 -2
  6. package/components/checkout/cart/cart_entity/cart_entity_color_simple_products/cart_entity_color_simple_product/cart-entity-color-simple-product.scss +2 -2
  7. package/components/checkout/cart/cart_shipping/cart-shipping.vue +1 -1
  8. package/components/checkout/order/order-payment-information/order-payment-information.vue +10 -2
  9. package/components/common/pricing_discounts_table/pricing-discounts-table.vue +6 -2
  10. package/components/customer/customer.vue +13 -17
  11. package/components/customer/customer_form/customer-form.vue +7 -2
  12. package/components/editor/editor_colors/editor-colors.scss +6 -3
  13. package/components/editor/editor_colors/editor-colors.vue +1 -1
  14. package/components/editor/editor_layers/editor-layers.scss +40 -1
  15. package/components/editor/editor_layers/editor-layers.vue +112 -67
  16. package/components/editor/editor_layers/editor_layer_forms/editor_layer_form_text/editor-layer-form-text.scss +19 -1
  17. package/components/editor/editor_layers/editor_layer_forms/editor_layer_form_text/editor-layer-form-text.vue +114 -21
  18. package/components/editor/editor_layers/editor_layers_toolbar/editor-layers-toolbar.scss +15 -1
  19. package/components/editor/editor_layers/editor_layers_toolbar/editor-layers-toolbar.vue +20 -3
  20. package/components/editor/editor_workspace/editor-workspace.vue +17 -6
  21. package/components/editor/editor_workspace/editor_workspace_side/editor-workspace-side.vue +25 -20
  22. package/components/product/editor_pricing/editor-pricing.scss +2 -1
  23. package/components/product/other_products/other_product/other-product.scss +9 -0
  24. package/components/product/other_products/other_product/other-product.vue +21 -12
  25. package/components/product/product_check_delivery/product-check-delivery.scss +115 -0
  26. package/components/product/product_check_delivery/product-check-delivery.vue +135 -30
  27. package/components/product/product_multipacks_carousel/product-multipacks-carousel.vue +4 -47
  28. package/components/product/product_pricing_tiers/product-pricing-tiers.scss +2 -0
  29. package/components/product/product_pricing_tiers/product-pricing-tiers.vue +25 -6
  30. package/components/product/products_size_selector_color/product_size_selector_color/product-size-selector-color.scss +6 -1
  31. package/components/product/wizard/wizard_print_layers/wizard_print_layer/wizard-print-layer.vue +9 -6
  32. package/components/products/children_categories/children-categories.vue +14 -7
  33. package/components/products/products_aside/products-aside.vue +14 -2
  34. package/components/static_page/static-page.scss +15 -1
  35. package/components/static_page/static-page.vue +7 -0
  36. package/mixins/layouts/products.js +3 -2
  37. package/mixins/multipack.mixin.js +61 -0
  38. package/package.json +1 -1
  39. package/plugins/headers.js +1 -0
  40. package/plugins/save-state.js +6 -2
  41. package/static/images/empty-layers.png +0 -0
  42. package/store/cart.js +20 -3
  43. package/store/index.js +1 -1
  44. package/store/product.js +2 -2
@@ -13,57 +13,162 @@
13
13
  </div>
14
14
  </div>
15
15
  <div class="ProductCheckDelivery__postcode">
16
- <postcode-select v-model="postcode" />
16
+ <postcode-select
17
+ v-model="postcode"
18
+ :suburb="suburb"
19
+ :only-postcode="true"
20
+ label-text="Postcode"
21
+ @select="onSelectSuburb" />
17
22
  </div>
18
- <!-- <div class="ProductCheckDelivery__estimates">
19
- <div class="ProductCheckDelivery__estimate">
20
- <div class="ProductCheckDelivery__estimate-icon">
21
- <i class="icon-map"></i>
22
- </div>
23
- <div class="ProductCheckDelivery__estimate-label">
24
- Next day collection
25
- </div>
26
- <div class="ProductCheckDelivery__estimate-info">
27
- - Order before 2pm
28
- </div>
29
- <div class="ProductCheckDelivery__estimate-price">
30
- Free
31
- </div>
32
- </div>
33
- <div class="ProductCheckDelivery__estimate">
34
- <div class="ProductCheckDelivery__estimate-icon">
35
- <i class="icon-local-shipping"></i>
36
- </div>
37
- <div class="ProductCheckDelivery__estimate-label">
38
- Home delivery
39
- </div>
40
- <div class="ProductCheckDelivery__estimate-info">
41
- - Next working day
23
+ <div
24
+ v-if="recalcNeeded"
25
+ class="ProductCheckDelivery__recalc-warning">
26
+ <span class="lc_caption lc_orange">Quantities changed. Shipping may be outdated.</span>
27
+ <btn
28
+ btn-class="purple"
29
+ btn-label="Recalculate"
30
+ @onclick="calculateShipping" />
31
+ </div>
32
+ <div
33
+ v-if="hasSuppliersWithRates && hasSelection"
34
+ class="ProductCheckDelivery__shipping">
35
+ <div
36
+ v-for="(supplier, index) of suppliersWithRates"
37
+ :key="index"
38
+ class="CartShipmentsPricing__supplier">
39
+ <div class="CartShipmentsPricing__supplier-info">
40
+ <div class="CartShipmentsPricing__supplier-brands">
41
+ <div>
42
+ {{ supplier.brands.map(b => b.name) | commaArray }}
43
+ </div>
44
+ </div>
45
+ <div>
46
+ {{ supplier | selectedRatePrice | price(currency) }}
47
+ </div>
42
48
  </div>
43
- <div class="ProductCheckDelivery__estimate-price">
44
- £3.95
49
+ <div
50
+ v-for="(rate, i) of supplier.rates"
51
+ :key="`rate-${i}`"
52
+ class="CartShipmentsPricing__rate CartShipmentsPricing__rate--disabled">
53
+ <div class="CartShipmentsPricing__rate-info">
54
+ <div class="CartShipmentsPricing__rate-name">
55
+ <div>{{ rate.name }}</div>
56
+ <div
57
+ v-if="rate.note"
58
+ class="lc_regular10">
59
+ {{ rate.note }}
60
+ </div>
61
+ </div>
62
+ </div>
63
+ <div class="CartShipmentsPricing__rate-price">
64
+ {{ rate.totalPriceWithoutTax | price(currency) }}
65
+ </div>
45
66
  </div>
46
67
  </div>
47
- </div> -->
68
+ </div>
69
+ <div
70
+ v-else-if="calculating && hasSelection"
71
+ class="ProductCheckDelivery__calculating">
72
+ <div class="lc_body-large lc_gray-main">Calculating shipping...</div>
73
+ </div>
48
74
  </section>
49
75
  </template>
50
76
 
51
77
  <script>
52
78
  import { mapGetters } from 'vuex';
53
79
  import PostcodeSelect from '@lancom/shared/components/common/postcode_select/postcode-select';
80
+ import api from '@lancom/shared/assets/js/api';
81
+ import { getProductsForCalculatePricing } from '@lancom/shared/assets/js/utils/product';
82
+ import { price, commaArray } from '@lancom/shared/assets/js/utils/filters';
54
83
 
55
84
  export default {
56
85
  name: 'ProductCheckDelivery',
57
86
  components: {
58
87
  PostcodeSelect
59
88
  },
89
+ filters: {
90
+ price,
91
+ commaArray,
92
+ selectedRatePrice(supplier) {
93
+ const { totalPriceWithoutTax = 0 } = supplier.rates.find(r => r.selected) || {};
94
+ return totalPriceWithoutTax;
95
+ }
96
+ },
60
97
  data() {
98
+ const postcode = 'SW1A 1AA';
61
99
  return {
62
- postcode: null
100
+ suburb: { postcode },
101
+ pricing: null,
102
+ calculating: false,
103
+ recalcNeeded: false,
104
+ lastUsedSimpleProductsSignature: null
63
105
  };
64
106
  },
65
107
  computed: {
66
- ...mapGetters('product', ['product'])
108
+ ...mapGetters(['shop', 'country', 'currency']),
109
+ ...mapGetters('product', ['product', 'usedSimpleProducts', 'template']),
110
+ hasSelection() {
111
+ return (this.usedSimpleProducts || []).length > 0;
112
+ },
113
+ hasSuppliersWithRates() {
114
+ return this.suppliersWithRates.length > 0;
115
+ },
116
+ suppliersWithRates() {
117
+ return this.pricing?.shipping?.suppliersWithRates || [];
118
+ }
119
+ },
120
+ watch: {
121
+ usedSimpleProducts: {
122
+ handler() {
123
+ const currentSignature = this.buildSignature();
124
+ if (this.hasSelection && currentSignature !== this.lastUsedSimpleProductsSignature) {
125
+ if (this.pricing) {
126
+ this.recalcNeeded = true;
127
+ } else {
128
+ this.calculateShipping();
129
+ }
130
+ }
131
+ },
132
+ deep: true
133
+ }
134
+ },
135
+ mounted() {
136
+ if (this.hasSelection) {
137
+ this.calculateShipping();
138
+ }
139
+ },
140
+ methods: {
141
+ onSelectSuburb(suburb) {
142
+ this.suburb = suburb;
143
+ this.calculateShipping();
144
+ },
145
+ buildSignature() {
146
+ return JSON.stringify((this.usedSimpleProducts || []).map(({ _id, amount }) => ({ _id, amount })));
147
+ },
148
+ async calculateShipping() {
149
+ if (!this.hasSelection) {
150
+ this.pricing = null;
151
+ this.recalcNeeded = false;
152
+ return;
153
+ }
154
+ this.calculating = true;
155
+ this.recalcNeeded = false;
156
+ try {
157
+ const entities = getProductsForCalculatePricing(this.product, this.usedSimpleProducts);
158
+ const payload = {
159
+ entities: entities.map(e => ({ ...e, brand: this.product.brand })),
160
+ postcode: this.suburb?.postcode,
161
+ country: this.country?._id,
162
+ currency: this.currency?._id
163
+ };
164
+ this.pricing = await api.calculateProductPrice(payload, this.shop._id);
165
+ this.lastUsedSimpleProductsSignature = this.buildSignature();
166
+ } catch (e) {
167
+ this.pricing = null;
168
+ } finally {
169
+ this.calculating = false;
170
+ }
171
+ }
67
172
  }
68
173
  };
69
174
  </script>
@@ -35,7 +35,7 @@
35
35
 
36
36
  <script>
37
37
  import { mapMutations, mapGetters } from 'vuex';
38
- import { inRange } from '@lancom/shared/assets/js/utils/filters';
38
+ import MultipackMixin from '@lancom/shared/mixins/multipack.mixin';
39
39
  import ProductMultipack from './product_multipack/product-multipack';
40
40
 
41
41
  export default {
@@ -43,6 +43,7 @@ export default {
43
43
  components: {
44
44
  ProductMultipack
45
45
  },
46
+ mixins: [MultipackMixin],
46
47
  props: {
47
48
  product: {
48
49
  type: Object,
@@ -92,61 +93,17 @@ export default {
92
93
  }
93
94
  },
94
95
  methods: {
95
- ...mapMutations('product', ['setSimpleProductAmount', 'clearSimpleProductsAmount', 'setMultipack']),
96
+ ...mapMutations('product', ['clearSimpleProductsAmount', 'setMultipack']),
96
97
  toggleMultipack(multipack) {
97
98
  this.selectedMultipack = this.selectedMultipack === multipack ? null : multipack;
98
99
  this.clearSimpleProductsAmount();
99
100
  if (this.selectedMultipack) {
100
- this.buyMultipack()
101
- }
102
- },
103
- buyMultipack() {
104
- const leftQty = this.addSimpleProducts([
105
- { size: 'S', percent: 0.15 },
106
- { size: 'M', percent: 0.2 },
107
- { size: 'XL', percent: 0.3 },
108
- { size: '2XL', percent: 0.05 },
109
- { size: 'L' }
110
- ]);
111
- if (leftQty > 0) {
112
- this.clearSimpleProductsAmount();
113
- const sizes = [
114
- { size: 'L' },
115
- { size: 'XL' },
116
- { size: 'M' },
117
- ...this.simpleProducts
118
- .filter(sp => sp.color?._id === this.color._id)
119
- .filter(simpleProduct => !['L','XL','M'].includes(simpleProduct.size?.shortName))
120
- .map(simpleProduct => ({ size: simpleProduct.size?.shortName }))
121
- ];
122
- const repeatLeftQty = this.addSimpleProducts(sizes);
101
+ const repeatLeftQty = this.buyMultipack(this.color, this.selectedMultipack.qty);
123
102
  if (repeatLeftQty > 0) {
124
103
  this.selectedMultipack = null;
125
- this.clearSimpleProductsAmount();
126
- this.$toastr.e('Stock unavailable');
127
104
  }
128
105
  }
129
106
  },
130
- addSimpleProducts(sizes) {
131
- let leftQty = this.selectedMultipack.qty;
132
- sizes.forEach(s => {
133
- const simpleProduct = this.simpleProducts
134
- .filter(sp => sp.color?._id === this.color._id)
135
- .find(simpleProduct => simpleProduct.size?.shortName === s.size);
136
- if (simpleProduct) {
137
- const qty = s.percent ? +(s.percent * this.selectedMultipack.qty).toFixed(0) : leftQty;
138
- const amount = inRange(qty, 0, simpleProduct.quantityStock || 0);
139
- leftQty -= amount;
140
- this.setSimpleProductAmount({
141
- colorId: simpleProduct.color._id,
142
- sizeId: simpleProduct.size._id,
143
- amount,
144
- currency: this.currency
145
- });
146
- }
147
- });
148
- return leftQty;
149
- },
150
107
  goToPrevPage() {
151
108
  this.thumbsPage = Math.max(0, this.thumbsPage - 1);
152
109
  },
@@ -9,6 +9,7 @@
9
9
  display: flex;
10
10
  gap: 6px;
11
11
  margin-top: 16px;
12
+ flex-wrap: wrap;
12
13
  }
13
14
  &__tier {
14
15
  padding: 4px;
@@ -17,6 +18,7 @@
17
18
  border: 1px solid #E5E5E5;
18
19
  background: #FFF;
19
20
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.10), 0 2px 4px -2px rgba(0, 0, 0, 0.10);
21
+ cursor: pointer;
20
22
  &-single-price {
21
23
  padding: 12px 0;
22
24
  border-radius: 8px;
@@ -5,14 +5,20 @@
5
5
  </h3>
6
6
  <div class="ProductPricingTiers__tiers">
7
7
  <div
8
- v-for="(tier, index) in product.pricing"
8
+ v-for="(tier, index) in defaultSimpleProduct.pricing"
9
9
  :key="index"
10
- class="ProductPricingTiers__tier">
10
+ class="ProductPricingTiers__tier"
11
+ @click="selectTier(tier)">
11
12
  <div class="ProductPricingTiers__tier-single-price">
12
- <span>{{ (tier.price / tier.min) | priceWithTax(pricingSettings, currency) }}</span> each
13
+ <price
14
+ :price="tier.price"
15
+ :with-gst="priceIncludeGST" /> each
13
16
  </div>
14
17
  <div class="ProductPricingTiers__tier-price">
15
- Buy {{ tier.min }} for <span>{{ tier.price | priceWithTax(pricingSettings, currency) }}</span>
18
+ Buy {{ tier.min }} for
19
+ <price
20
+ :price="tier.price * tier.min"
21
+ :with-gst="priceIncludeGST" />
16
22
  </div>
17
23
  </div>
18
24
  </div>
@@ -22,15 +28,28 @@
22
28
  <script>
23
29
  import { mapGetters } from 'vuex';
24
30
  import { priceWithTax } from '@lancom/shared/assets/js/utils/filters';
31
+ import MultipackMixin from '@lancom/shared/mixins/multipack.mixin';
32
+ import Price from '@lancom/shared/components/common/price';
25
33
 
26
34
  export default {
27
35
  name: 'ProductPricingTiers',
28
36
  filters: {
29
37
  priceWithTax
30
38
  },
39
+ components: {
40
+ Price
41
+ },
42
+ mixins: [MultipackMixin],
31
43
  computed: {
32
- ...mapGetters('product', ['product']),
33
- ...mapGetters(['pricingSettings'])
44
+ ...mapGetters('product', ['product', 'editableColor', 'priceIncludeGST', 'defaultSimpleProduct']),
45
+ ...mapGetters(['pricingSettings', 'currency'])
46
+ },
47
+ methods: {
48
+ selectTier(tier) {
49
+ if (this.editableColor) {
50
+ this.buyMultipack(this.editableColor, tier.min);
51
+ }
52
+ }
34
53
  }
35
54
  };
36
55
  </script>
@@ -40,6 +40,11 @@
40
40
  &__out-stock {
41
41
  color: $gray_main;
42
42
  }
43
+ &__price {
44
+ span {
45
+ border-bottom: 1px dashed grey;
46
+ }
47
+ }
43
48
  }
44
49
 
45
50
  ::v-deep .ProductSizeSelectorColorCell {
@@ -55,4 +60,4 @@
55
60
  background: $green;
56
61
  width: 26px;
57
62
  }
58
- }
63
+ }
@@ -120,7 +120,9 @@
120
120
  </span>
121
121
  </slot>
122
122
  <template slot="popover">
123
- <pricing-discounts-table :prices="layerPrintPricing" />
123
+ <pricing-discounts-table
124
+ :prices="layerPrintPricing"
125
+ :with-gst="priceIncludeGST" />
124
126
  </template>
125
127
  </v-popover>
126
128
  </td>
@@ -156,21 +158,22 @@ import WizardTextOrLogoForm from './../../wizard_print_text_or_logo/wizard_text_
156
158
 
157
159
  export default {
158
160
  name: 'WizardPrintLayer',
159
- mixins: [printLayerMixin],
161
+ filters: {
162
+ pricingRange
163
+ },
160
164
  components: {
161
165
  PricingDiscountsTable,
162
166
  WizardTextOrLogoForm
163
167
  },
164
- filters: {
165
- pricingRange
166
- },
168
+ mixins: [printLayerMixin],
167
169
  props: {
168
170
  editable: {
169
171
  type: Boolean
170
172
  }
171
173
  },
172
174
  computed: {
173
- ...mapGetters(['currency'])
175
+ ...mapGetters(['currency']),
176
+ ...mapGetters('product', ['priceIncludeGST'])
174
177
  }
175
178
  };
176
179
  </script>
@@ -7,27 +7,35 @@
7
7
  <a
8
8
  :href="generateProductsLink($route, { category }, true)"
9
9
  class="CategoryCard__link">
10
- <div class="CategoryCard__image-wrapper">
10
+ <span
11
+ v-if="visibleImages"
12
+ class="CategoryCard__image-wrapper">
11
13
  <img
12
14
  v-if="category.image"
13
15
  :src="category.image.medium"
14
16
  :alt="category.name"
15
17
  class="CategoryCard__image" />
16
- </div>
17
- <div class="CategoryCard__name">
18
+ </span>
19
+ <span class="CategoryCard__name">
18
20
  {{ category.name }}
19
- </div>
21
+ </span>
20
22
  </a>
21
23
  </div>
22
24
  </div>
23
25
  </template>
24
-
26
+
25
27
  <script>
26
28
  import { mapGetters } from 'vuex';
27
29
  import { generateProductsLink } from '@lancom/shared/assets/js/utils/product';
28
-
30
+
29
31
  export default {
30
32
  name: 'ChildrenCategories',
33
+ props: {
34
+ visibleImages: {
35
+ type: Boolean,
36
+ default: true
37
+ }
38
+ },
31
39
  computed: {
32
40
  ...mapGetters('products', ['childrenCategories'])
33
41
  },
@@ -40,4 +48,3 @@ export default {
40
48
  <style lang="scss" scoped>
41
49
  @import 'children-categories';
42
50
  </style>
43
-
@@ -23,12 +23,16 @@
23
23
  :has-selected-icon="hasSelectedIcon"
24
24
  :selected-icon-circle="selectedIconCircle" />
25
25
  </div>
26
- <div class="ProductsAside__item">
26
+ <div
27
+ v-if="hasProductionTime"
28
+ class="ProductsAside__item">
27
29
  <products-production-time
28
30
  :has-selected-icon="hasSelectedIcon"
29
31
  :selected-icon-circle="selectedIconCircle" />
30
32
  </div>
31
- <div class="ProductsAside__item">
33
+ <div
34
+ v-if="hasMinimumQty"
35
+ class="ProductsAside__item">
32
36
  <products-minimum-qty
33
37
  :has-selected-icon="hasSelectedIcon"
34
38
  :selected-icon-circle="selectedIconCircle" />
@@ -93,6 +97,14 @@ export default {
93
97
  hasProductTypes: {
94
98
  type: Boolean,
95
99
  default: false
100
+ },
101
+ hasProductionTime: {
102
+ type: Boolean,
103
+ default: true
104
+ },
105
+ hasMinimumQty: {
106
+ type: Boolean,
107
+ default: true
96
108
  }
97
109
  },
98
110
  data() {
@@ -8,4 +8,18 @@
8
8
  overflow: hidden;
9
9
  @import "@lancom/shared/assets/scss/normalize";
10
10
  }
11
- }
11
+ }
12
+
13
+ .post-full-image {
14
+ display: flex;
15
+ flex-direction: column;
16
+ align-items: center;
17
+ overflow: hidden;
18
+ margin: 25px 0 50px;
19
+ border-radius: 3px;
20
+ img {
21
+ max-width: 1040px;
22
+ width: 100%;
23
+ height: auto;
24
+ }
25
+ }
@@ -5,6 +5,13 @@
5
5
  class="StaticPage__title lc_h1">
6
6
  {{ item.title }}
7
7
  </h1>
8
+ <figure
9
+ v-if="item.image"
10
+ class="post-full-image">
11
+ <img
12
+ :src="item.image.origin"
13
+ :alt="item.title" />
14
+ </figure>
8
15
  <div
9
16
  class="StaticPage__content"
10
17
  v-html="item.text"></div>
@@ -11,6 +11,7 @@ export default {
11
11
  async fetch() {
12
12
  await this.loadProducts();
13
13
 
14
+ console.log('fetchChildrenCategories: ', this.page, this.currentCategory);
14
15
  if (this.page === 1) {
15
16
  await this.fetchChildrenCategories(this.currentCategory);
16
17
  }
@@ -277,9 +278,9 @@ export default {
277
278
  text = this.currentCategory ? text.replace(/{{categoryName}}/g, this.currentCategory.name) : text;
278
279
  return text;
279
280
  },
280
- async openAside() {
281
+ async openAside(props) {
281
282
  const ProductsAside = await import('@/components/products/products_aside/products-aside');
282
- this.$aside.show(ProductsAside.default);
283
+ this.$aside.show(ProductsAside.default, {}, { props });
283
284
  }
284
285
  }
285
286
  };
@@ -0,0 +1,61 @@
1
+ import { mapMutations, mapGetters } from 'vuex';
2
+ import { inRange } from '@lancom/shared/assets/js/utils/filters';
3
+
4
+ export default {
5
+ computed: {
6
+ ...mapGetters('product', ['simpleProducts']),
7
+ ...mapGetters(['currency'])
8
+ },
9
+ methods: {
10
+ ...mapMutations('product', ['setSimpleProductAmount', 'clearSimpleProductsAmount']),
11
+ buyMultipack(color, qty) {
12
+ const leftQty = this.addSimpleProducts([
13
+ { size: 'S', percent: 0.15 },
14
+ { size: 'M', percent: 0.2 },
15
+ { size: 'XL', percent: 0.3 },
16
+ { size: '2XL', percent: 0.05 },
17
+ { size: 'L' }
18
+ ], color, qty);
19
+ if (leftQty > 0) {
20
+ this.clearSimpleProductsAmount();
21
+ const sizes = [
22
+ { size: 'L' },
23
+ { size: 'XL' },
24
+ { size: 'M' },
25
+ ...this.simpleProducts
26
+ .filter(sp => sp.color?._id === color._id)
27
+ .filter(simpleProduct => !['L', 'XL', 'M'].includes(simpleProduct.size?.shortName))
28
+ .map(simpleProduct => ({ size: simpleProduct.size?.shortName }))
29
+ ];
30
+ const repeatLeftQty = this.addSimpleProducts(sizes, color, qty);
31
+ if (repeatLeftQty > 0) {
32
+ this.clearSimpleProductsAmount();
33
+ this.$toastr.e('Stock unavailable');
34
+ }
35
+ return repeatLeftQty;
36
+ }
37
+
38
+ return 0;
39
+ },
40
+ addSimpleProducts(sizes, color, qty) {
41
+ let leftQty = qty;
42
+ sizes.forEach(s => {
43
+ const simpleProduct = this.simpleProducts
44
+ .filter(sp => sp.color?._id === color._id)
45
+ .find(simpleProduct => simpleProduct.size?.shortName === s.size);
46
+ if (simpleProduct) {
47
+ const calculatedQty = s.percent ? +(s.percent * qty).toFixed(0) : leftQty;
48
+ const amount = inRange(calculatedQty, 0, simpleProduct.quantityStock || 0);
49
+ leftQty -= amount;
50
+ this.setSimpleProductAmount({
51
+ colorId: simpleProduct.color._id,
52
+ sizeId: simpleProduct.size._id,
53
+ amount,
54
+ currency: this.currency
55
+ });
56
+ }
57
+ });
58
+ return leftQty;
59
+ }
60
+ }
61
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lancom/shared",
3
- "version": "0.0.432",
3
+ "version": "0.0.434",
4
4
  "description": "lancom common scripts",
5
5
  "author": "e.tokovenko <e.tokovenko@gmail.com>",
6
6
  "repository": {
@@ -1,4 +1,5 @@
1
1
  module.exports = function (req, res, next) {
2
2
  res.removeHeader('Expect-CT');
3
+ res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
3
4
  next();
4
5
  };
@@ -22,9 +22,13 @@ export function saveStatePlugin(store) {
22
22
  });
23
23
  }
24
24
 
25
- export function loadState() {
25
+ export function loadState(query) {
26
26
  const savedState = localStorage.getItem(STATE_STORAGE_KEY);
27
- return savedState && JSON.parse(savedState);
27
+ const state = savedState && JSON.parse(savedState);
28
+ if (query?.price && state?.product) {
29
+ delete state.product.priceIncludeGST;
30
+ }
31
+ return state;
28
32
  }
29
33
 
30
34
  export function saveState(store) {
Binary file