@lancom/shared 0.0.101 → 0.0.105
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/api/admin.js +20 -2
- package/assets/js/api/index.js +3 -0
- package/components/checkout/cart/cart.mixin.js +7 -1
- package/components/checkout/order/address-form/address-form.vue +1 -0
- package/components/checkout/order/order-billing-information/order-billing-information.vue +7 -5
- package/components/common/coupon_select/coupon-select.scss +0 -0
- package/components/common/coupon_select/coupon-select.vue +111 -0
- package/components/common/postcode_select/postcode-select.vue +80 -58
- package/components/quotes/quote_request/quote-request.scss +1 -1
- package/components/quotes/quote_request/quote-request.vue +21 -2
- package/components/subscribe/subscribe.vue +15 -6
- package/nuxt.config.js +13 -1
- package/package.json +1 -1
- package/plugins/save-state.js +3 -1
- package/store/cart.js +12 -6
- package/store/index.js +2 -0
- package/store/order.js +2 -0
package/assets/js/api/admin.js
CHANGED
|
@@ -151,14 +151,26 @@ export default {
|
|
|
151
151
|
removeProductType(id) {
|
|
152
152
|
return _delete(`admin/product-types/${id}`);
|
|
153
153
|
},
|
|
154
|
+
fetchCoupons() {
|
|
155
|
+
return _get('admin/coupons');
|
|
156
|
+
},
|
|
157
|
+
fetchCouponById(id) {
|
|
158
|
+
return _get(`admin/coupons/${id}`);
|
|
159
|
+
},
|
|
160
|
+
saveCoupon(coupon) {
|
|
161
|
+
return coupon._id ? _put(`admin/coupons/${coupon._id}`, coupon) : _post('admin/coupons', coupon);
|
|
162
|
+
},
|
|
163
|
+
removeCoupon(id) {
|
|
164
|
+
return _delete(`admin/coupons/${id}`);
|
|
165
|
+
},
|
|
154
166
|
fetchReviews() {
|
|
155
167
|
return _get('admin/reviews');
|
|
156
168
|
},
|
|
157
169
|
fetchReviewById(id) {
|
|
158
170
|
return _get(`admin/reviews/${id}`);
|
|
159
171
|
},
|
|
160
|
-
saveReview(
|
|
161
|
-
return
|
|
172
|
+
saveReview(review) {
|
|
173
|
+
return review._id ? _put(`admin/reviews/${review._id}`, review) : _post('admin/reviews', review);
|
|
162
174
|
},
|
|
163
175
|
removeReview(id) {
|
|
164
176
|
return _delete(`admin/reviews/${id}`);
|
|
@@ -194,6 +206,9 @@ export default {
|
|
|
194
206
|
async fetchSuppliers(params) {
|
|
195
207
|
return sortByName(await _get('admin/suppliers', params));
|
|
196
208
|
},
|
|
209
|
+
validateSuppliers() {
|
|
210
|
+
return _get('admin/suppliers/validate');
|
|
211
|
+
},
|
|
197
212
|
fetchSupplierById(id) {
|
|
198
213
|
return _get(`admin/suppliers/${id}`);
|
|
199
214
|
},
|
|
@@ -400,5 +415,8 @@ export default {
|
|
|
400
415
|
},
|
|
401
416
|
sendToPrinter(job) {
|
|
402
417
|
return _post('admin/printers/job', job);
|
|
418
|
+
},
|
|
419
|
+
findResources(query) {
|
|
420
|
+
return _get(`admin/order/resources?search=${query || ''}`);
|
|
403
421
|
}
|
|
404
422
|
};
|
package/assets/js/api/index.js
CHANGED
|
@@ -48,6 +48,9 @@ const api = {
|
|
|
48
48
|
fetchProduct(shop, alias, print) {
|
|
49
49
|
return _get(`shop/${shop}/products/${alias}?print=${print || ''}`);
|
|
50
50
|
},
|
|
51
|
+
fetchCouponByCode(shop, code) {
|
|
52
|
+
return _get(`shop/${shop}/coupons/${code}`);
|
|
53
|
+
},
|
|
51
54
|
fetchMenus(shop) {
|
|
52
55
|
return _get(`shop/${shop}/menus`);
|
|
53
56
|
},
|
|
@@ -11,6 +11,7 @@ export default {
|
|
|
11
11
|
...mapGetters('cart', [
|
|
12
12
|
'entities',
|
|
13
13
|
'simpleProducts',
|
|
14
|
+
'coupon',
|
|
14
15
|
'suburb',
|
|
15
16
|
'quantities',
|
|
16
17
|
'notValidProductsQuantities',
|
|
@@ -39,7 +40,8 @@ export default {
|
|
|
39
40
|
},
|
|
40
41
|
methods: {
|
|
41
42
|
...mapMutations('cart', [
|
|
42
|
-
'setSuburb'
|
|
43
|
+
'setSuburb',
|
|
44
|
+
'setCoupon'
|
|
43
45
|
]),
|
|
44
46
|
...mapActions('cart', [
|
|
45
47
|
'removeSimpleProductsFromCart',
|
|
@@ -49,6 +51,10 @@ export default {
|
|
|
49
51
|
this.setSuburb(suburb);
|
|
50
52
|
this.calculateCartPrice({ shop: this.shop });
|
|
51
53
|
},
|
|
54
|
+
handleCouponChange(coupon) {
|
|
55
|
+
this.setCoupon(coupon);
|
|
56
|
+
this.calculateCartPrice({ shop: this.shop });
|
|
57
|
+
},
|
|
52
58
|
async removeSimpleProducts(simpleProducts) {
|
|
53
59
|
const message = 'This will delete all items in this row, Press OK to continue or Cancel';
|
|
54
60
|
const confirmed = await this.showConfirmationModal(message);
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
</div>
|
|
6
6
|
<div class="OrderBillingInformation__form">
|
|
7
7
|
<validation-observer
|
|
8
|
+
v-slot="{ invalid }"
|
|
8
9
|
ref="form">
|
|
9
10
|
<div class="OrderBillingInformation__content">
|
|
10
11
|
<address-form
|
|
@@ -12,7 +13,7 @@
|
|
|
12
13
|
:without-additional-info="true" />
|
|
13
14
|
</div>
|
|
14
15
|
<progress-steps-controls
|
|
15
|
-
:disabled-next="
|
|
16
|
+
:disabled-next="isSubmit && invalid"
|
|
16
17
|
@prev="$emit('prev')"
|
|
17
18
|
@next="submit" />
|
|
18
19
|
</validation-observer>
|
|
@@ -23,7 +24,6 @@
|
|
|
23
24
|
<script>
|
|
24
25
|
import AddressForm from '@lancom/shared/components/checkout/order/address-form/address-form';
|
|
25
26
|
import ProgressStepsControls from '@lancom/shared/components/common/progress_steps/progress_steps_controls/progress-steps-controls';
|
|
26
|
-
import { ORDER_STEPS } from '@lancom/shared/assets/js/constants/order';
|
|
27
27
|
|
|
28
28
|
export default {
|
|
29
29
|
name: 'OrderBillingInformation',
|
|
@@ -40,13 +40,15 @@ export default {
|
|
|
40
40
|
data() {
|
|
41
41
|
return {
|
|
42
42
|
copyToShippingAddress: true,
|
|
43
|
-
|
|
43
|
+
isSubmit: false
|
|
44
44
|
};
|
|
45
45
|
},
|
|
46
46
|
methods: {
|
|
47
47
|
async submit() {
|
|
48
|
-
this.
|
|
49
|
-
|
|
48
|
+
this.isSubmit = true;
|
|
49
|
+
|
|
50
|
+
const isValid = await this.$refs.form.validate() && !!this.order.shippingAddress.postcode;
|
|
51
|
+
if (!isValid) {
|
|
50
52
|
return;
|
|
51
53
|
}
|
|
52
54
|
|
|
File without changes
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="CouponSelect__wrapper form-row">
|
|
3
|
+
<validation-provider
|
|
4
|
+
tag="div"
|
|
5
|
+
name="coupon"
|
|
6
|
+
class="form-col col-half">
|
|
7
|
+
<label
|
|
8
|
+
for="coupon"
|
|
9
|
+
class="form-label">
|
|
10
|
+
{{ labelText }}
|
|
11
|
+
</label>
|
|
12
|
+
<input
|
|
13
|
+
id="coupon"
|
|
14
|
+
ref="coupon"
|
|
15
|
+
v-model="code"
|
|
16
|
+
placeholder="Coupon"
|
|
17
|
+
name="coupon"
|
|
18
|
+
type="text"
|
|
19
|
+
class="form-field labelless"
|
|
20
|
+
:class="{
|
|
21
|
+
'is-danger': code && notValidCoupon,
|
|
22
|
+
filled: code
|
|
23
|
+
}"
|
|
24
|
+
@change="validateCoupon" />
|
|
25
|
+
<span
|
|
26
|
+
v-if="code && notValidCoupon"
|
|
27
|
+
class="form-help is-danger">
|
|
28
|
+
Not valid coupon
|
|
29
|
+
</span>
|
|
30
|
+
</validation-provider>
|
|
31
|
+
<div v-if="value">
|
|
32
|
+
<div class="mt-10 lc_h4">
|
|
33
|
+
{{ value.value | price }} OFF
|
|
34
|
+
</div>
|
|
35
|
+
<div
|
|
36
|
+
v-if="value.minOrderValue"
|
|
37
|
+
class="mt-10 lc_caption">
|
|
38
|
+
Min Order For Coupon: {{ value.minOrderValue | price }}
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<script>
|
|
45
|
+
import api from '@lancom/shared/assets/js/api';
|
|
46
|
+
import { price } from '@lancom/shared/assets/js/utils/filters';
|
|
47
|
+
import { mapGetters } from 'vuex';
|
|
48
|
+
|
|
49
|
+
export default {
|
|
50
|
+
name: 'CouponSelect',
|
|
51
|
+
filters: {
|
|
52
|
+
price
|
|
53
|
+
},
|
|
54
|
+
props: {
|
|
55
|
+
value: {
|
|
56
|
+
type: Object
|
|
57
|
+
},
|
|
58
|
+
labelText: {
|
|
59
|
+
type: String,
|
|
60
|
+
default: 'Coupon'
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
data() {
|
|
64
|
+
return {
|
|
65
|
+
isLoading: false,
|
|
66
|
+
notValidCoupon: false,
|
|
67
|
+
code: null
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
computed: {
|
|
71
|
+
...mapGetters(['shop']),
|
|
72
|
+
model: {
|
|
73
|
+
get() {
|
|
74
|
+
return this.value?.code;
|
|
75
|
+
},
|
|
76
|
+
set(coupon) {
|
|
77
|
+
this.$emit('input', coupon);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
created() {
|
|
82
|
+
if (this.model) {
|
|
83
|
+
this.code = this.model;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
methods: {
|
|
87
|
+
async validateCoupon() {
|
|
88
|
+
this.notValidCoupon = false;
|
|
89
|
+
if (this.code) {
|
|
90
|
+
this.isLoading = true;
|
|
91
|
+
try {
|
|
92
|
+
const coupon = await api.fetchCouponByCode(this.shop._id, this.code);
|
|
93
|
+
this.$emit('input', coupon);
|
|
94
|
+
this.code = coupon.code;
|
|
95
|
+
} catch (e) {
|
|
96
|
+
this.notValidCoupon = true;
|
|
97
|
+
this.$emit('input', null);
|
|
98
|
+
} finally {
|
|
99
|
+
this.isLoading = false;
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
this.$emit('input', null);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<style lang="scss">
|
|
110
|
+
@import 'coupon-select';
|
|
111
|
+
</style>
|
|
@@ -1,61 +1,75 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="PostcodeSelect form-row">
|
|
3
|
-
<
|
|
4
|
-
v-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
3
|
+
<validation-provider
|
|
4
|
+
v-slot="{ errors }"
|
|
5
|
+
tag="div"
|
|
6
|
+
:rules="required ? 'required' : ''"
|
|
7
|
+
name="Postcode"
|
|
8
|
+
class="form-group form-row">
|
|
9
|
+
<label
|
|
10
|
+
v-if="labelless"
|
|
11
|
+
class="form-label"
|
|
12
|
+
@click="$refs.suburb.$el.focus()">
|
|
13
|
+
{{ labelText }}
|
|
14
|
+
</label>
|
|
15
|
+
<multiselect
|
|
16
|
+
ref="suburb"
|
|
17
|
+
v-model="model"
|
|
18
|
+
class="limited-height"
|
|
19
|
+
:class="{ labelless }"
|
|
20
|
+
:options="options"
|
|
21
|
+
:placeholder="placeholder"
|
|
22
|
+
:searchable="true"
|
|
23
|
+
:disabled="disabled"
|
|
24
|
+
:required="required"
|
|
25
|
+
:internal-search="false"
|
|
26
|
+
:clear-on-select="false"
|
|
27
|
+
:allow-empty="false"
|
|
28
|
+
:option-height="35"
|
|
29
|
+
:loading="isLoading"
|
|
30
|
+
track-by="value"
|
|
31
|
+
@search-change="handleSearchWithDebounce">
|
|
32
|
+
<div
|
|
33
|
+
slot="singleLabel"
|
|
34
|
+
slot-scope="{ option }"
|
|
35
|
+
class="PostcodeSelect__option">
|
|
36
|
+
{{ option.label }}
|
|
37
|
+
</div>
|
|
38
|
+
<div
|
|
39
|
+
slot="option"
|
|
40
|
+
slot-scope="{ option, search }"
|
|
41
|
+
class="lc_caption PostcodeSelect__option"
|
|
42
|
+
v-html="$options.filters.highlight(option.label, search)">
|
|
43
|
+
</div>
|
|
44
|
+
<div
|
|
45
|
+
slot="noOptions"
|
|
46
|
+
class="ub_caption">
|
|
47
|
+
Start typing.
|
|
48
|
+
</div>
|
|
49
|
+
<div
|
|
50
|
+
slot="noResult"
|
|
51
|
+
class="ub_caption">
|
|
52
|
+
Not result.
|
|
53
|
+
</div>
|
|
54
|
+
</multiselect>
|
|
55
|
+
<input
|
|
56
|
+
type="text"
|
|
57
|
+
:value="value"
|
|
58
|
+
:class="{ 'filled': value || selected }"
|
|
59
|
+
class="form-hidden-validator form-field" />
|
|
60
|
+
<label
|
|
61
|
+
v-if="!labelless"
|
|
62
|
+
class="form-label label-inner"
|
|
63
|
+
@click="$refs.suburb.$el.focus()">
|
|
64
|
+
{{ labelText }}
|
|
65
|
+
</label>
|
|
66
|
+
<slot></slot>
|
|
67
|
+
<span
|
|
68
|
+
v-if="errors.length"
|
|
69
|
+
class="form-help is-danger">
|
|
70
|
+
{{ errors[0] }}
|
|
71
|
+
</span>
|
|
72
|
+
</validation-provider>
|
|
59
73
|
</div>
|
|
60
74
|
</template>
|
|
61
75
|
|
|
@@ -83,6 +97,14 @@ export default {
|
|
|
83
97
|
type: Boolean,
|
|
84
98
|
default: false
|
|
85
99
|
},
|
|
100
|
+
required: {
|
|
101
|
+
type: Boolean,
|
|
102
|
+
default: false
|
|
103
|
+
},
|
|
104
|
+
disabled: {
|
|
105
|
+
type: Boolean,
|
|
106
|
+
default: false
|
|
107
|
+
},
|
|
86
108
|
suburb: {
|
|
87
109
|
type: Object
|
|
88
110
|
}
|
|
@@ -126,9 +148,9 @@ export default {
|
|
|
126
148
|
this.options = [];
|
|
127
149
|
}
|
|
128
150
|
},
|
|
129
|
-
createOptionFromSuburb({ locality, state, postcode }) {
|
|
151
|
+
createOptionFromSuburb({ locality, state, postcode, city }) {
|
|
130
152
|
return {
|
|
131
|
-
label:
|
|
153
|
+
label: [locality || city, state, postcode].filter(i => !!i).join(', '),
|
|
132
154
|
value: postcode
|
|
133
155
|
};
|
|
134
156
|
}
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
v-slot="{ errors }"
|
|
40
40
|
tag="div"
|
|
41
41
|
name="Phone"
|
|
42
|
+
rules="required|phone"
|
|
42
43
|
class="form-row">
|
|
43
44
|
<label
|
|
44
45
|
for="quote-request-name"
|
|
@@ -203,6 +204,13 @@
|
|
|
203
204
|
{{ errors[0] }}
|
|
204
205
|
</span>
|
|
205
206
|
</validation-provider>
|
|
207
|
+
<postcode-select
|
|
208
|
+
:suburb="quote.address.suburb"
|
|
209
|
+
:labelless="true"
|
|
210
|
+
:required="true"
|
|
211
|
+
placeholder="Postcode"
|
|
212
|
+
label-text="Postcode"
|
|
213
|
+
@select="handleChangeSuburb" />
|
|
206
214
|
<validation-provider
|
|
207
215
|
v-slot="{ errors }"
|
|
208
216
|
tag="div"
|
|
@@ -292,12 +300,14 @@ import api from '@lancom/shared/assets/js/api';
|
|
|
292
300
|
import { mapGetters } from 'vuex';
|
|
293
301
|
import CheckedIcon from '@lancom/shared/components/common/checked-icon';
|
|
294
302
|
import FileUploader from '@lancom/shared/components/common/file_uploader';
|
|
303
|
+
import PostcodeSelect from '@lancom/shared/components/common/postcode_select/postcode-select';
|
|
295
304
|
|
|
296
305
|
export default {
|
|
297
306
|
name: 'QuoteRequest',
|
|
298
307
|
components: {
|
|
299
308
|
CheckedIcon,
|
|
300
|
-
FileUploader
|
|
309
|
+
FileUploader,
|
|
310
|
+
PostcodeSelect
|
|
301
311
|
},
|
|
302
312
|
data() {
|
|
303
313
|
return {
|
|
@@ -339,7 +349,8 @@ export default {
|
|
|
339
349
|
address: {
|
|
340
350
|
fullName: '',
|
|
341
351
|
email: '',
|
|
342
|
-
phone: ''
|
|
352
|
+
phone: '',
|
|
353
|
+
suburb: null
|
|
343
354
|
},
|
|
344
355
|
expectedItemsQuantity: null,
|
|
345
356
|
description: '',
|
|
@@ -372,6 +383,14 @@ export default {
|
|
|
372
383
|
this.uploadError = null;
|
|
373
384
|
this.quote.file = null;
|
|
374
385
|
},
|
|
386
|
+
handleChangeSuburb(suburb) {
|
|
387
|
+
this.quote.address = {
|
|
388
|
+
...this.quote.address,
|
|
389
|
+
...suburb,
|
|
390
|
+
city: suburb?.locality,
|
|
391
|
+
suburb
|
|
392
|
+
};
|
|
393
|
+
},
|
|
375
394
|
async submit() {
|
|
376
395
|
try {
|
|
377
396
|
this.processing = true;
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
</div>
|
|
14
14
|
</slot>
|
|
15
15
|
<div v-if="isSubscribed">
|
|
16
|
-
<div class="Subscribe__success
|
|
16
|
+
<div class="Subscribe__success lc_h5 mt-5">
|
|
17
17
|
Subscribed successfully
|
|
18
18
|
</div>
|
|
19
19
|
</div>
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
rules="required"
|
|
33
33
|
class="form-row">
|
|
34
34
|
<input
|
|
35
|
-
id="email"
|
|
35
|
+
:id="'email' + uniqueKey"
|
|
36
36
|
ref="email"
|
|
37
37
|
v-model="subscriber.email"
|
|
38
|
-
name="email"
|
|
38
|
+
:name="'email' + uniqueKey"
|
|
39
39
|
type="text"
|
|
40
40
|
class="form-field"
|
|
41
41
|
:class="{
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
filled: subscriber.email
|
|
44
44
|
}" />
|
|
45
45
|
<label
|
|
46
|
-
for="email"
|
|
46
|
+
:for="'email' + uniqueKey"
|
|
47
47
|
class="form-label label-inner">
|
|
48
48
|
Your email address
|
|
49
49
|
</label>
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
{{ errors[0] }}
|
|
54
54
|
</span>
|
|
55
55
|
</validation-provider>
|
|
56
|
+
<slot :subscriber="subscriber" name="fields"></slot>
|
|
56
57
|
</div>
|
|
57
58
|
<div class="form__footer">
|
|
58
59
|
<div class="form-actions">
|
|
@@ -87,10 +88,13 @@ export default {
|
|
|
87
88
|
data() {
|
|
88
89
|
return {
|
|
89
90
|
subscriber: {
|
|
90
|
-
email: null
|
|
91
|
+
email: null,
|
|
92
|
+
userType: null,
|
|
93
|
+
printType: null
|
|
91
94
|
},
|
|
92
95
|
isSubscribed: false,
|
|
93
|
-
processing: false
|
|
96
|
+
processing: false,
|
|
97
|
+
uniqueKey: Math.random()
|
|
94
98
|
};
|
|
95
99
|
},
|
|
96
100
|
computed: {
|
|
@@ -98,6 +102,11 @@ export default {
|
|
|
98
102
|
},
|
|
99
103
|
methods: {
|
|
100
104
|
async submit() {
|
|
105
|
+
const isValid = await this.$refs.form.validate();
|
|
106
|
+
if (!isValid) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
101
110
|
try {
|
|
102
111
|
this.processing = true;
|
|
103
112
|
const recaptchaToken = await this.getRecaptcha('subscribe');
|
package/nuxt.config.js
CHANGED
|
@@ -122,11 +122,23 @@ module.exports = (config, axios) => ({
|
|
|
122
122
|
'g:product_type': { _text: `Home > Products > ${product.productType.name}`, },
|
|
123
123
|
'g:is_bundle': { _text: product.prePrint ? 'yes' : 'no' },
|
|
124
124
|
'g:identifier_exists': sp.gtin ? 'yes' : 'no',
|
|
125
|
-
'g:product_weight': { _text: `${product.weight} kg` }
|
|
125
|
+
'g:product_weight': { _text: `${product.weight} kg` },
|
|
126
|
+
'g:shipping_weight': { _text: `${((product.weight || 0) + (product.weight || 0) * 0.05).toFixed(3)} kg` }
|
|
126
127
|
};
|
|
127
128
|
if (sp.gtin) {
|
|
128
129
|
info['g:gtin'] = { _text: sp.gtin || '' };
|
|
129
130
|
}
|
|
131
|
+
if (product.volume) {
|
|
132
|
+
if (product.volume.length) {
|
|
133
|
+
info['g:shipping_length'] = { _text: `${product.volume.length} cm` };
|
|
134
|
+
}
|
|
135
|
+
if (product.volume.width) {
|
|
136
|
+
info['g:shipping_width'] = { _text: `${product.volume.width} cm` };
|
|
137
|
+
}
|
|
138
|
+
if (product.volume.height) {
|
|
139
|
+
info['g:shipping_height'] = { _text: `${product.volume.height} cm` };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
130
142
|
return info;
|
|
131
143
|
})
|
|
132
144
|
];
|
package/package.json
CHANGED
package/plugins/save-state.js
CHANGED
|
@@ -3,7 +3,9 @@ import debounce from 'lodash.debounce';
|
|
|
3
3
|
const STATE_STORAGE_KEY = 'lancom-state-2.1';
|
|
4
4
|
const SAVE_STATE_MODULES = new Map([
|
|
5
5
|
['cart/setId', 'cart.id'],
|
|
6
|
-
['cart/clearCart', 'cart.id']
|
|
6
|
+
['cart/clearCart', 'cart.id'],
|
|
7
|
+
['cart/setCoupon', 'cart.coupon'],
|
|
8
|
+
['cart/clearCart', 'cart.coupon']
|
|
7
9
|
]);
|
|
8
10
|
|
|
9
11
|
export function saveStatePlugin(store) {
|
package/store/cart.js
CHANGED
|
@@ -6,6 +6,7 @@ export const state = () => ({
|
|
|
6
6
|
id: null,
|
|
7
7
|
entities: [],
|
|
8
8
|
suburb: null,
|
|
9
|
+
coupon: null,
|
|
9
10
|
cartPricing: null,
|
|
10
11
|
cartPricingError: null
|
|
11
12
|
});
|
|
@@ -40,6 +41,7 @@ const getPrintsQuantities = entities => {
|
|
|
40
41
|
|
|
41
42
|
export const getters = {
|
|
42
43
|
entities: ({ entities }) => entities,
|
|
44
|
+
coupon: ({ coupon }) => coupon,
|
|
43
45
|
simpleProducts: ({ entities }) => entities.reduce((simpleProducts, entity) => [...simpleProducts, ...(entity.simpleProducts || [])], []),
|
|
44
46
|
notEmptySimpleProducts: (state, { simpleProducts }) => simpleProducts.filter(e => e.amount > 0),
|
|
45
47
|
simpleProductsQuantity: (state, { notEmptySimpleProducts }) => notEmptySimpleProducts.reduce((quantity, sp) => quantity + sp.amount, 0),
|
|
@@ -105,8 +107,8 @@ export const actions = {
|
|
|
105
107
|
await api.saveCart(payload, shop._id);
|
|
106
108
|
commit('setEntities', entities);
|
|
107
109
|
},
|
|
108
|
-
async calculateCartPrice({ state: { suburb, entities }, commit }, { shop }) {
|
|
109
|
-
const payload = generateCalculatePriceData(entities, suburb);
|
|
110
|
+
async calculateCartPrice({ state: { suburb, entities, coupon }, commit }, { shop }) {
|
|
111
|
+
const payload = generateCalculatePriceData(entities, suburb, null, coupon);
|
|
110
112
|
try {
|
|
111
113
|
const response = await api.calculateProductPrice(payload, shop._id);
|
|
112
114
|
commit('setCartPricing', response);
|
|
@@ -132,7 +134,7 @@ export const actions = {
|
|
|
132
134
|
clearCart({ commit }) {
|
|
133
135
|
commit('clearCart');
|
|
134
136
|
},
|
|
135
|
-
async selectRate({ state: { cartPricing, entities, suburb }, commit }, { supplier, rate, shop }) {
|
|
137
|
+
async selectRate({ state: { cartPricing, entities, suburb, coupon }, commit }, { supplier, rate, shop }) {
|
|
136
138
|
const suppliersWithRates = cartPricing.shipping.suppliersWithRates
|
|
137
139
|
.map(supplierWithRates => ({
|
|
138
140
|
...(
|
|
@@ -143,7 +145,7 @@ export const actions = {
|
|
|
143
145
|
})
|
|
144
146
|
: supplierWithRates)
|
|
145
147
|
}));
|
|
146
|
-
const payload = generateCalculatePriceData(entities, suburb, suppliersWithRates);
|
|
148
|
+
const payload = generateCalculatePriceData(entities, suburb, suppliersWithRates, coupon);
|
|
147
149
|
try {
|
|
148
150
|
const response = await api.calculateProductPrice(payload, shop._id);
|
|
149
151
|
commit('setCartPricing', response);
|
|
@@ -170,6 +172,9 @@ export const mutations = {
|
|
|
170
172
|
setSuburb(state, suburb) {
|
|
171
173
|
state.suburb = suburb;
|
|
172
174
|
},
|
|
175
|
+
setCoupon(state, coupon) {
|
|
176
|
+
state.coupon = coupon;
|
|
177
|
+
},
|
|
173
178
|
setCartPricing(state, price) {
|
|
174
179
|
state.cartPricing = price;
|
|
175
180
|
},
|
|
@@ -184,12 +189,12 @@ export const mutations = {
|
|
|
184
189
|
state.entities = [];
|
|
185
190
|
state.cartPricing = null;
|
|
186
191
|
state.suburb = null;
|
|
192
|
+
state.coupon = null;
|
|
187
193
|
state.cartPricingError = null;
|
|
188
194
|
}
|
|
189
195
|
};
|
|
190
196
|
|
|
191
|
-
function generateCalculatePriceData(entities, suburb, suppliersWithRates) {
|
|
192
|
-
console.log('suburb: ', suburb);
|
|
197
|
+
function generateCalculatePriceData(entities, suburb, suppliersWithRates, coupon) {
|
|
193
198
|
const getSimpleObj = i => i && ({ _id: i._id, name: i.name });
|
|
194
199
|
return {
|
|
195
200
|
entities: entities.map(({ _id, guid, prints, simpleProducts, product }) => ({
|
|
@@ -220,6 +225,7 @@ function generateCalculatePriceData(entities, suburb, suppliersWithRates) {
|
|
|
220
225
|
})),
|
|
221
226
|
postcode: suburb && suburb.postcode,
|
|
222
227
|
address: suburb ? [suburb.locality, suburb.state, suburb.postcode].filter(i => !!i).join(', ') : null,
|
|
228
|
+
coupon,
|
|
223
229
|
suppliersWithRates
|
|
224
230
|
};
|
|
225
231
|
}
|
package/store/index.js
CHANGED
package/store/order.js
CHANGED
|
@@ -19,6 +19,8 @@ export const actions = {
|
|
|
19
19
|
if (pricing) {
|
|
20
20
|
order.totalGST = pricing.totalPrice;
|
|
21
21
|
order.total = pricing.totalPriceWithoutTax;
|
|
22
|
+
order.couponTotal = pricing.coupon?.totalPrice || 0;
|
|
23
|
+
order.couponCode = pricing.coupon?.code || 0;
|
|
22
24
|
order.productsTotal = pricing.products?.products?.totalPriceWithoutTax || 0;
|
|
23
25
|
order.printsTotal = pricing.products?.prints?.totalPriceWithoutTax || 0;
|
|
24
26
|
order.shippingTotal = pricing.shipping?.totalPriceWithoutTax || 0;
|