@lancom/shared 0.0.397 → 0.0.398
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/assets/js/utils/coupon.js +13 -0
- package/assets/js/utils/gtm.js +11 -9
- package/assets/js/utils/order.js +9 -7
- package/components/checkout/cart/cart.mixin.js +3 -2
- package/components/checkout/cart/cart.vue +5 -5
- package/components/checkout/cart/cart_entity/cart-entity.mixin.js +9 -1
- package/components/checkout/cart/cart_entity/cart-entity.scss +3 -0
- package/components/checkout/cart/cart_entity/cart-entity.vue +10 -1
- package/components/checkout/cart/cart_entity/cart_coupon_free_products/cart-coupon-free-products.scss +11 -0
- package/components/checkout/cart/cart_entity/cart_coupon_free_products/cart-coupon-free-products.vue +38 -0
- package/components/checkout/cart/cart_entity/cart_coupon_free_products/cart_coupon_free_product/cart-coupon-free-product.scss +7 -0
- package/components/checkout/cart/cart_entity/cart_coupon_free_products/cart_coupon_free_product/cart-coupon-free-product.vue +30 -0
- package/components/common/phone_input/phone-input.vue +0 -1
- package/package.json +1 -1
- package/pages/checkout/order.vue +2 -2
- package/store/cart.js +23 -3
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function getCouponFreeProducts(coupon, product) {
|
|
2
|
+
const freeProducts = coupon?.qualifyingProducts?.reduce((products, qualifyingProduct) => {
|
|
3
|
+
if (qualifyingProduct.products.includes(product?._id || product)) {
|
|
4
|
+
return [
|
|
5
|
+
...products,
|
|
6
|
+
...qualifyingProduct.freeProducts
|
|
7
|
+
];
|
|
8
|
+
}
|
|
9
|
+
return products;
|
|
10
|
+
}, []);
|
|
11
|
+
|
|
12
|
+
return freeProducts || [];
|
|
13
|
+
}
|
package/assets/js/utils/gtm.js
CHANGED
|
@@ -156,14 +156,16 @@ const gtm = {
|
|
|
156
156
|
};
|
|
157
157
|
|
|
158
158
|
function getOrderItems(order) {
|
|
159
|
-
return order.products
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
159
|
+
return order.products
|
|
160
|
+
.filter(p => !p.isFree)
|
|
161
|
+
.reduce((products, { product, simpleProducts }) => {
|
|
162
|
+
return [
|
|
163
|
+
...products,
|
|
164
|
+
...simpleProducts
|
|
165
|
+
.filter(({ amount }) => amount > 0)
|
|
166
|
+
.map(sp => getOrderItem(product, sp))
|
|
167
|
+
];
|
|
168
|
+
}, [])
|
|
167
169
|
}
|
|
168
170
|
|
|
169
171
|
function getOrderItem(product, simpleProduct, currency) {
|
|
@@ -173,7 +175,7 @@ function getOrderItem(product, simpleProduct, currency) {
|
|
|
173
175
|
item_id: SKU,
|
|
174
176
|
item_variant: `${product.name} ${color?.name || ''}-${size?.shortName || ''}`.trim(),
|
|
175
177
|
item_name: product.name.trim(),
|
|
176
|
-
item_brand: product.brand
|
|
178
|
+
item_brand: product.brand?.name,
|
|
177
179
|
price: productCost,
|
|
178
180
|
currency: currency?.isoCode || 'AUD',
|
|
179
181
|
quantity: amount,
|
package/assets/js/utils/order.js
CHANGED
|
@@ -39,20 +39,21 @@ export function populateProductsFields(products, pricing) {
|
|
|
39
39
|
product.designId = designId;
|
|
40
40
|
|
|
41
41
|
product.colors = (product.simpleProducts || []).reduce((colors, sp) => {
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const _id = sp.color._id || sp.color;
|
|
43
|
+
if (!colors.includes(_id)) {
|
|
44
|
+
colors.push(_id);
|
|
44
45
|
}
|
|
45
46
|
return colors;
|
|
46
47
|
}, []);
|
|
47
48
|
|
|
48
49
|
if (pricing) {
|
|
49
50
|
const productPricing = pricing.products[product.guid] || pricing.products[product?.product._id];
|
|
50
|
-
product.totalPrice = productPricing
|
|
51
|
-
product.printsTotalPrice = productPricing
|
|
52
|
-
product.productsTotalPrice = productPricing
|
|
51
|
+
product.totalPrice = productPricing?.totalPriceWithoutTax;
|
|
52
|
+
product.printsTotalPrice = productPricing?.prints.totalPriceWithoutTax;
|
|
53
|
+
product.productsTotalPrice = productPricing?.products.totalPriceWithoutTax;
|
|
53
54
|
|
|
54
55
|
(product.simpleProducts || []).forEach(sp => {
|
|
55
|
-
const spPricing = productPricing
|
|
56
|
+
const spPricing = productPricing?.products[sp.guid] || productPricing?.products[sp._id];
|
|
56
57
|
if (spPricing) {
|
|
57
58
|
sp.totalPrice = spPricing.totalPriceWithoutTax;
|
|
58
59
|
sp.productCost = spPricing.priceWithoutTax;
|
|
@@ -60,7 +61,7 @@ export function populateProductsFields(products, pricing) {
|
|
|
60
61
|
});
|
|
61
62
|
|
|
62
63
|
(product.prints || []).forEach(p => {
|
|
63
|
-
const pPricing = productPricing
|
|
64
|
+
const pPricing = productPricing?.prints[p.printArea?._id];
|
|
64
65
|
if (pPricing) {
|
|
65
66
|
p.totalPrice = pPricing.totalPriceWithoutTax;
|
|
66
67
|
p.printCost = pPricing.priceWithoutTax;
|
|
@@ -92,6 +93,7 @@ export function populatePrints(products) {
|
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
export function generateOrderData(data, cartEntities, pricing) {
|
|
96
|
+
console.log('generateOrderData:cartEntities: ', cartEntities);
|
|
95
97
|
const order = {
|
|
96
98
|
...data,
|
|
97
99
|
products: populateProductsFields(cartEntities, pricing),
|
|
@@ -19,6 +19,7 @@ export default {
|
|
|
19
19
|
'needToPickup',
|
|
20
20
|
'needToPickupWithoutErrors',
|
|
21
21
|
'entities',
|
|
22
|
+
'entitiesWithoutFreeProducts',
|
|
22
23
|
'cartPricing',
|
|
23
24
|
'simpleProducts',
|
|
24
25
|
'simpleProductsQuantity',
|
|
@@ -35,7 +36,7 @@ export default {
|
|
|
35
36
|
return this.isNotValidProductsQuantity || this.isNotValidStockQuantity || this.isNotValidPrintsQuantity || this.isNotValidPrintsBigSizeQuantity;
|
|
36
37
|
},
|
|
37
38
|
isNotValidShipping() {
|
|
38
|
-
return this.needToPickup ? (this.notValidProductsPickup.length > 0 && !this.suburb) : !this.suburb;
|
|
39
|
+
return this.needToPickup ? (this.notValidProductsPickup.length > 0 && !this.suburb) : !this.suburb;
|
|
39
40
|
},
|
|
40
41
|
isNotValidProductsQuantity() {
|
|
41
42
|
return this.notValidProductsQuantities.length > 0;
|
|
@@ -51,7 +52,7 @@ export default {
|
|
|
51
52
|
}
|
|
52
53
|
},
|
|
53
54
|
watch: {
|
|
54
|
-
|
|
55
|
+
entitiesWithoutFreeProducts() {
|
|
55
56
|
this.calculateCartPriceWithDebounce({ shop: this.shop, country: this.country, currency: this.currency });
|
|
56
57
|
}
|
|
57
58
|
},
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
<cart-price-info @loaded="loadedPricing($event)" />
|
|
33
33
|
</div>
|
|
34
34
|
<div class="Cart__postcode-container">
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
</div>
|
|
37
37
|
<div class="Cart__coupon-container">
|
|
38
38
|
<coupon-select
|
|
@@ -99,12 +99,12 @@ export default {
|
|
|
99
99
|
mixins: [CartMixin],
|
|
100
100
|
computed: {
|
|
101
101
|
...mapGetters(['MESSAGES', 'SETTINGS', 'currency', 'country']),
|
|
102
|
-
...mapGetters('cart', ['isEmpty','cartPricingError', 'cartPricing', 'cartPricingCalculating', 'entities']),
|
|
102
|
+
...mapGetters('cart', ['isEmpty','cartPricingError', 'cartPricing', 'cartPricingCalculating', 'entities', 'entitiesWithoutFreeProducts']),
|
|
103
103
|
productsEntities() {
|
|
104
|
-
return this.
|
|
104
|
+
return this.entitiesWithoutFreeProducts.filter(e => !e.productsKit)
|
|
105
105
|
},
|
|
106
106
|
productsKitsEntities() {
|
|
107
|
-
const entities = this.
|
|
107
|
+
const entities = this.entitiesWithoutFreeProducts.filter(e => !!e.productsKit);
|
|
108
108
|
const groupedEntities = entities.reduce((acc, entity) => {
|
|
109
109
|
const { productsKitGuid, productsKit } = entity;
|
|
110
110
|
if (!acc[productsKitGuid]) {
|
|
@@ -132,7 +132,7 @@ export default {
|
|
|
132
132
|
},
|
|
133
133
|
methods: {
|
|
134
134
|
loadedPricing() {
|
|
135
|
-
gtm.viewCart(this.
|
|
135
|
+
gtm.viewCart(this.entitiesWithoutFreeProducts, this.cartPricing, this.currency);
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mapGetters } from 'vuex';
|
|
2
2
|
import { groupSimpleProducts } from '@lancom/shared/assets/js/utils/cart';
|
|
3
3
|
import { generateProductLink } from '@lancom/shared/assets/js/utils/product';
|
|
4
|
+
import { getCouponFreeProducts } from '@lancom/shared/assets/js/utils/coupon';
|
|
4
5
|
|
|
5
6
|
export default {
|
|
6
7
|
props: {
|
|
@@ -17,8 +18,15 @@ export default {
|
|
|
17
18
|
...mapGetters(['SETTINGS']),
|
|
18
19
|
...mapGetters('cart', [
|
|
19
20
|
'cartPricing',
|
|
20
|
-
'cartProductsPricing'
|
|
21
|
+
'cartProductsPricing',
|
|
22
|
+
'coupon'
|
|
21
23
|
]),
|
|
24
|
+
hasCouponFreeProducts() {
|
|
25
|
+
return this.couponFreeProducts.length > 0;
|
|
26
|
+
},
|
|
27
|
+
couponFreeProducts() {
|
|
28
|
+
return getCouponFreeProducts(this.coupon, this.product);
|
|
29
|
+
},
|
|
22
30
|
product() {
|
|
23
31
|
return this.entity.product;
|
|
24
32
|
},
|
|
@@ -73,6 +73,13 @@
|
|
|
73
73
|
class="CartEntity__decorations">
|
|
74
74
|
<cart-entity-prints :entity="entity" />
|
|
75
75
|
</div>
|
|
76
|
+
<div
|
|
77
|
+
v-if="hasCouponFreeProducts"
|
|
78
|
+
class="CartEntity__free-products">
|
|
79
|
+
<cart-coupon-free-products
|
|
80
|
+
:free-products="couponFreeProducts"
|
|
81
|
+
:entity="entity" />
|
|
82
|
+
</div>
|
|
76
83
|
<div class="CartEntity__subtotal lc_title">
|
|
77
84
|
Subtotal: {{ totalPrice | price(currency) }}
|
|
78
85
|
</div>
|
|
@@ -87,6 +94,7 @@
|
|
|
87
94
|
<script>
|
|
88
95
|
import { price } from '@lancom/shared/assets/js/utils/filters';
|
|
89
96
|
import CartEntityPrints from './cart_entity_prints/cart-entity-prints';
|
|
97
|
+
import CartCouponFreeProducts from './cart_coupon_free_products/cart-coupon-free-products';
|
|
90
98
|
import CartEntityColorSimpleProducts from './cart_entity_color_simple_products/cart-entity-color-simple-products';
|
|
91
99
|
import CartEntity from './cart-entity.mixin';
|
|
92
100
|
|
|
@@ -97,7 +105,8 @@ export default {
|
|
|
97
105
|
},
|
|
98
106
|
components: {
|
|
99
107
|
CartEntityPrints,
|
|
100
|
-
CartEntityColorSimpleProducts
|
|
108
|
+
CartEntityColorSimpleProducts,
|
|
109
|
+
CartCouponFreeProducts
|
|
101
110
|
},
|
|
102
111
|
mixins: [
|
|
103
112
|
CartEntity
|
package/components/checkout/cart/cart_entity/cart_coupon_free_products/cart-coupon-free-products.vue
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="CartCouponFreeProducts__wrapper">
|
|
3
|
+
<div class="CartCouponFreeProducts__label">
|
|
4
|
+
Free products
|
|
5
|
+
</div>
|
|
6
|
+
<cart-coupon-free-product
|
|
7
|
+
v-for="freeProduct in freeProducts"
|
|
8
|
+
:key="freeProduct._id"
|
|
9
|
+
:free-product="freeProduct"
|
|
10
|
+
:entity="entity"
|
|
11
|
+
class="CartCouponFreeProducts__product" />
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
import CartCouponFreeProduct from './cart_coupon_free_product/cart-coupon-free-product';
|
|
17
|
+
|
|
18
|
+
export default {
|
|
19
|
+
name: 'CartCouponFreeProducts',
|
|
20
|
+
components: {
|
|
21
|
+
CartCouponFreeProduct
|
|
22
|
+
},
|
|
23
|
+
props: {
|
|
24
|
+
freeProducts: {
|
|
25
|
+
type: Array,
|
|
26
|
+
required: true
|
|
27
|
+
},
|
|
28
|
+
entity: {
|
|
29
|
+
type: Object,
|
|
30
|
+
required: true
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<style lang="scss" scoped>
|
|
37
|
+
@import 'cart-coupon-free-products.scss';
|
|
38
|
+
</style>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="CartCouponFreeProduct__wrapper">
|
|
3
|
+
{{ freeProduct.name }} x {{ qty }}
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script>
|
|
8
|
+
export default {
|
|
9
|
+
name: 'CartCouponFreeProduct',
|
|
10
|
+
props: {
|
|
11
|
+
freeProduct: {
|
|
12
|
+
type: Object,
|
|
13
|
+
required: true
|
|
14
|
+
},
|
|
15
|
+
entity: {
|
|
16
|
+
type: Object,
|
|
17
|
+
required: true
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
computed: {
|
|
21
|
+
qty() {
|
|
22
|
+
return this.entity.simpleProducts?.reduce((qty, sp) => qty + (sp.amount || 0), 0) || 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<style lang="scss" scoped>
|
|
29
|
+
@import 'cart-coupon-free-product.scss';
|
|
30
|
+
</style>
|
package/package.json
CHANGED
package/pages/checkout/order.vue
CHANGED
|
@@ -43,7 +43,7 @@ export default {
|
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
computed: {
|
|
46
|
-
...mapGetters('cart', ['entities', 'coupon', 'cartPricing'])
|
|
46
|
+
...mapGetters('cart', ['entitiesWithoutFreeProducts', 'entities', 'coupon', 'cartPricing'])
|
|
47
47
|
},
|
|
48
48
|
methods: {
|
|
49
49
|
loadedPricing() {
|
|
@@ -52,7 +52,7 @@ export default {
|
|
|
52
52
|
value: this.cartPricing.totalPriceWithoutTax,
|
|
53
53
|
currency: 'AUD',
|
|
54
54
|
coupon: this.cartPricing.coupon?.code,
|
|
55
|
-
items: this.
|
|
55
|
+
items: this.entitiesWithoutFreeProducts.reduce((products, { guid: productGuid, product, simpleProducts }) => {
|
|
56
56
|
return [
|
|
57
57
|
...products,
|
|
58
58
|
...simpleProducts
|
package/store/cart.js
CHANGED
|
@@ -3,6 +3,7 @@ import api from '@lancom/shared/assets/js/api';
|
|
|
3
3
|
import gtm from '@lancom/shared/assets/js/utils/gtm';
|
|
4
4
|
import { getPrintTypeSizePricing } from '@lancom/shared/assets/js/utils/prints';
|
|
5
5
|
import { filterBigSize } from '@lancom/shared/assets/js/utils/product';
|
|
6
|
+
import { getCouponFreeProducts } from '@lancom/shared/assets/js/utils/coupon';
|
|
6
7
|
|
|
7
8
|
const SUPPLIERS_WITH_RATES_KEY = 'suppliers-with-rates';
|
|
8
9
|
|
|
@@ -73,7 +74,27 @@ const getPrintsQuantities = entities => {
|
|
|
73
74
|
};
|
|
74
75
|
|
|
75
76
|
export const getters = {
|
|
76
|
-
|
|
77
|
+
entitiesWithoutFreeProducts: ({ entities }) => entities,
|
|
78
|
+
entities: ({ entities, coupon }) => {
|
|
79
|
+
return entities.reduce((list, entity) => {
|
|
80
|
+
const amount = entity.simpleProducts?.reduce((count, sp) => count + +(sp.amount || 0), 0) || 0;
|
|
81
|
+
const freeProducts = getCouponFreeProducts(coupon, entity.product);
|
|
82
|
+
return [
|
|
83
|
+
...list,
|
|
84
|
+
entity,
|
|
85
|
+
...freeProducts
|
|
86
|
+
.filter(p => !!p.simpleProducts?.[0])
|
|
87
|
+
.map(product => ({
|
|
88
|
+
isFree: true,
|
|
89
|
+
designId: entity.designId,
|
|
90
|
+
product,
|
|
91
|
+
colors: [product.simpleProducts[0].color],
|
|
92
|
+
prints: [],
|
|
93
|
+
simpleProducts: [{ ...product.simpleProducts[0], amount }]
|
|
94
|
+
}))
|
|
95
|
+
];
|
|
96
|
+
}, []);
|
|
97
|
+
},
|
|
77
98
|
coupon: ({ coupon }) => coupon,
|
|
78
99
|
needToPickup: ({ needToPickup }) => needToPickup,
|
|
79
100
|
needToPickupWithoutErrors: (state, { notValidProductsPickup }) => state.needToPickup && notValidProductsPickup?.length === 0,
|
|
@@ -170,7 +191,7 @@ export const actions = {
|
|
|
170
191
|
})).filter(({ simpleProducts }) => simpleProducts.length > 0);
|
|
171
192
|
const payload = {
|
|
172
193
|
_id: state.id,
|
|
173
|
-
entities,
|
|
194
|
+
entities,
|
|
174
195
|
currency: currency?._id
|
|
175
196
|
};
|
|
176
197
|
await api.saveCart(payload, shop._id);
|
|
@@ -235,7 +256,6 @@ export const actions = {
|
|
|
235
256
|
localStorage.removeItem(SUPPLIERS_WITH_RATES_KEY);
|
|
236
257
|
commit('setSuburb', suburb);
|
|
237
258
|
commit('setCartPricing', null);
|
|
238
|
-
|
|
239
259
|
},
|
|
240
260
|
async selectRate({ state: { cartPricing, entities, suburb, coupon }, commit }, { supplier, rate, shop, country, currency }) {
|
|
241
261
|
const suppliersWithRates = cartPricing.shipping.suppliersWithRates
|