@lancom/shared 0.0.238 → 0.0.240

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.
@@ -263,8 +263,8 @@ export default {
263
263
  fetchInventoryHistory(params) {
264
264
  return _get('admin/inventory-history', params);
265
265
  },
266
- fetchInventoryCommitted(params) {
267
- return _get('admin/inventory/committed', params);
266
+ removeInventoryHistory(id) {
267
+ return _delete(`admin/inventory-history/${id}`);
268
268
  },
269
269
  fetchInventory(params) {
270
270
  return _get('admin/inventory');
@@ -0,0 +1,4 @@
1
+ export const COUNTRIES_CODES = {
2
+ Australia: 'AU',
3
+ 'United Kingdom': 'UK'
4
+ };
@@ -1,3 +1,6 @@
1
+ import dayjs from 'dayjs';
2
+ import { COUNTRIES_CODES } from '@lancom/shared/assets/js/constants/country';
3
+
1
4
  function surveyOptin(order, shop) {
2
5
  if (!window.renderOptIn) {
3
6
  const tag = document.createElement('script');
@@ -42,12 +45,12 @@ function surveyoptinRender(order, shop) {
42
45
  .filter(gtin => !!gtin)
43
46
  ];
44
47
  }, []);
45
- const estimated_delivery_date = "2023-11-28";
48
+ const estimated_delivery_date = dayjs(new Date()).add(15, 'day').format('YYYY-MM-DD');
46
49
  const data = {
47
50
  merchant_id: MERCHANT_ID,
48
51
  order_id: order.code,
49
52
  email: order.shippingAddress.email,
50
- delivery_country: order.shippingAddress.country,
53
+ delivery_country: COUNTRIES_CODES[order.shippingAddress.country] || order.shippingAddress.country,
51
54
  estimated_delivery_date,
52
55
  products,
53
56
  opt_in_style: "BOTTOM_RIGHT_DIALOG"
@@ -1,3 +1,5 @@
1
+ import { COUNTRIES_CODES } from '@lancom/shared/assets/js/constants/country';
2
+
1
3
  const gtm = {
2
4
  push(data, skipReset) {
3
5
  console.log('push:data: ', data);
@@ -9,6 +11,15 @@ const gtm = {
9
11
  }
10
12
  window.dataLayer.push(data);
11
13
  },
14
+ viewItem(product) {
15
+ this.push({
16
+ value: product.minPrice,
17
+ items: [{
18
+ id: product.SKU,
19
+ google_business_vertical: 'retail'
20
+ }]
21
+ });
22
+ },
12
23
  addToCart(entities, pricing) {
13
24
  this.push({
14
25
  event: 'add_to_cart',
@@ -30,7 +41,7 @@ const gtm = {
30
41
  viewCart(entities, pricing) {
31
42
  if (pricing) {
32
43
  this.push({
33
- event: 'view_cart',
44
+ event: 'view_item_list',
34
45
  value: pricing.totalPriceWithoutTax,
35
46
  currency: 'AUD',
36
47
  coupon: pricing.coupon?.code,
@@ -88,7 +99,7 @@ const gtm = {
88
99
  city,
89
100
  region: state,
90
101
  postal_code: +postcode,
91
- country
102
+ country: COUNTRIES_CODES[country] || country
92
103
  };
93
104
  }
94
105
  gtm.push(event);
@@ -135,13 +146,15 @@ function getOrderItems(order) {
135
146
  function getOrderItem(product, simpleProduct) {
136
147
  const { SKU, productCost, amount, color, size } = simpleProduct;
137
148
  return {
138
- item_id: product.SKU,
149
+ id: product.SKU,
150
+ item_id: SKU,
139
151
  item_variant: `${product.name} ${color?.name || ''}-${size?.shortName || ''}`.trim(),
140
152
  item_name: product.name.trim(),
141
153
  item_brand: product.brand.name,
142
154
  price: productCost,
143
155
  currency: 'AUD',
144
- quantity: amount
156
+ quantity: amount,
157
+ google_business_vertical: 'retail'
145
158
  };
146
159
  }
147
160
 
@@ -179,7 +179,7 @@ export default {
179
179
  this.$emit('next');
180
180
  } else {
181
181
  this.$nextTick(async () => {
182
- const message = `Unfortunately our payment gateway has reported the following error: '${this.errorMessage}'. Please check your card number and try again. Alternatively you can proceed with a 'pay later' order and receive and email confirmation now and pay via credit card or direct deposit`;
182
+ const message = `Unfortunately our payment gateway has reported the following error: '${this.errorMessage}'. Please check your card number and try again. Alternatively you can proceed with a 'pay later' order and receive an email confirmation now and pay via credit card or direct deposit`;
183
183
  const options = { submitLabel: 'PAY LATER', cancelLabel: 'TRY AGAIN', warning: true };
184
184
  const isSwitchToDeposit = await this.showConfirmationModal(message, options);
185
185
  if (isSwitchToDeposit) {
@@ -84,7 +84,7 @@ export default {
84
84
  data() {
85
85
  return {
86
86
  uniqueFieldId: `size-selector-${this.color._id}-${this.size._id}`,
87
- defaultValue: 0
87
+ defaultValue: null
88
88
  };
89
89
  },
90
90
  computed: {
@@ -122,7 +122,7 @@ export default {
122
122
  this.defaultValue = '';
123
123
  },
124
124
  onBlur() {
125
- this.defaultValue = 0;
125
+ this.defaultValue = null;
126
126
  }
127
127
  }
128
128
  };
@@ -366,7 +366,8 @@ export default {
366
366
  };
367
367
  },
368
368
  computed: {
369
- ...mapGetters(['shop'])
369
+ ...mapGetters(['shop']),
370
+ ...mapGetters('cart', ['entities']),
370
371
  },
371
372
  methods: {
372
373
  handleUploaded(file) {
@@ -403,7 +404,29 @@ export default {
403
404
  recaptchaToken,
404
405
  ...this.quote,
405
406
  quoteTypes: Object.keys(this.selectedQuoteTypes),
406
- shop: this.shop._id
407
+ shop: this.shop._id,
408
+ referer: window.location.href,
409
+ cartInfo: {
410
+ entities: (this.entities || [])
411
+ .map(({ product, simpleProducts, prints }) => {
412
+ return {
413
+ product: product ? { _id: product.name, name: product.name, SKU: product.SKU } : null,
414
+ prints: (prints || [])
415
+ .map(({ layers, printArea, printSize, printType }) => ({
416
+ layers,
417
+ printArea: printArea ? { _id: printArea._id, name: printArea.name } : null,
418
+ printSize: printSize ? { _id: printSize._id, name: printSize.name} : null,
419
+ printType: printType ? { _id: printType._id, name: printType.name} : null,
420
+ })),
421
+ simpleProducts: (simpleProducts || [])
422
+ .filter(({ amount }) => amount > 0)
423
+ .map(({ amount, SKU }) => ({
424
+ amount,
425
+ SKU,
426
+ }))
427
+ };
428
+ })
429
+ }
407
430
  };
408
431
  const quote = await api.saveQuoteRequest(body, this.shop._id);
409
432
 
@@ -35,8 +35,7 @@ export default {
35
35
  async convertToOrder(option) {
36
36
  try {
37
37
  this.processing = true;
38
- const recaptchaToken = await this.getRecaptcha('create_order');
39
- this.order = await this.createOrder({ ...option, recaptchaToken });
38
+ this.order = await this.createOrder({ ...option });
40
39
  this.setOrder(this.order);
41
40
  gtm.purchase(this.order);
42
41
  gapis.surveyOptin(this.order, this.shop);
@@ -51,11 +50,11 @@ export default {
51
50
  async createOrder(option) {
52
51
  const recaptchaToken = await this.getRecaptcha('create_order');
53
52
  const orderData = {
54
- recaptchaToken,
55
53
  shop: this.shop._id,
56
54
  country: this.country?._id,
57
55
  currency: this.currency?._id,
58
- ...convertQuoteToOrder(this.quote, option)
56
+ ...convertQuoteToOrder(this.quote, option),
57
+ recaptchaToken
59
58
  };
60
59
  return await api.createOrder(orderData, this.shop._id);
61
60
  }
@@ -0,0 +1,108 @@
1
+ async function googleShoppingFeed(axios, config, availableStores) {
2
+ const { data } = await axios.get(`${config.LOCAL_API_URL}/feed/products?host=${config.HOST_NAME}`);
3
+ const spliceFirstImage = images => (images || []).splice(0, 1)[0];
4
+ const getImages = images => (images || []).length > 0 ? images : null;
5
+ const channel = {
6
+ title: { _text: 'All products' },
7
+ link: { _text: `https://${config.HOST_NAME}` },
8
+ generator: { _text: config.HOST_NAME },
9
+ item: data
10
+ .reduce((items, product) => {
11
+ return [
12
+ ...items,
13
+ ...(product.simpleProducts || [])
14
+ .filter(sp => {
15
+ return !availableStores || availableStores.includes(sp.storeCode);
16
+ })
17
+ .map(sp => {
18
+ const feedImages = (product.images || []).filter(i => (i.types || []).includes('feed_primary') && sp.color._id === i.color).map(i => i.image);
19
+ const frontImages = (product.images || []).filter(i => (i.types || []).includes('front') && sp.color._id === i.color).map(i => i.image);
20
+ const backImages = (product.images || []).filter(i => (i.types || []).includes('back') && sp.color._id === i.color).map(i => i.image);
21
+ const catalogFrontImages = (product.images || []).filter(i => (i.types || []).includes('catalog_front')).map(i => i.image);
22
+ const image = spliceFirstImage(feedImages) || spliceFirstImage(frontImages) || spliceFirstImage(catalogFrontImages) || spliceFirstImage(backImages) || {};
23
+ const images = getImages(backImages) || getImages(frontImages) || [];
24
+ const feedTitle = (product.feedTitle || '')
25
+ .replace(/{colour}/g, sp.color.name)
26
+ .replace(/{size}/g, sp.size.name)
27
+ .replace(/{brand}/g, product.brand.name)
28
+ const title = feedTitle || `${product.name} ${sp.color.name}`;
29
+ const description = `${product.description || product.fabricInfoShort || product.name || ''}`
30
+ .replace(/ /g, ' ')
31
+ .replace(/·/, '·');
32
+ const link = `https://${config.HOST_NAME}/${product.brand.alias}/${product.productType.alias}/${product.alias}?color=${sp.color.alias}`;
33
+ const info = {
34
+ title: { _text: title },
35
+ description: { _text: description },
36
+ link: { _text: link },
37
+ 'g:id': { _text: sp.SKU },
38
+ 'g:item_group_id': { _text: product.SKU },
39
+ 'g:size': { _text: sp.size.name },
40
+ 'g:size_system': 'AU',
41
+ 'g:size_type': 'regular',
42
+ 'g:gender': { _text: product.gender },
43
+ 'g:material': { _text: product.fabricInfoShort },
44
+ 'g:brand': { _text: product.brand.name },
45
+ 'g:condition': { _text: 'new' },
46
+ 'g:mpn': { _text: sp.SKU },
47
+ 'g:color': { _text: sp.color.name },
48
+ 'g:image_link': { _text: image },
49
+ 'g:additional_image_link': images.map(i => ({ _text: i })),
50
+ 'g:price': { _text: `${(sp.price || 0)} AUD` },
51
+ 'g:availability': { _text: sp.quantityStock > 0 ? 'in_stock' : 'out_of_stock' },
52
+ 'g:google_product_category': { _text: 2047 },
53
+ 'g:product_type': { _text: `Home > Products > ${product.productType.name}`, },
54
+ 'g:is_bundle': { _text: product.prePrint ? 'yes' : 'no' },
55
+ 'g:identifier_exists': sp.gtin ? 'yes' : 'no',
56
+ 'g:product_weight': { _text: `${product.weight} kg` },
57
+ 'g:shipping_weight': { _text: `${((product.weight || 0) + (product.weight || 0) * 0.05).toFixed(3)} kg` },
58
+ 'g:quantity': { _text: sp.quantityStock },
59
+
60
+ };
61
+
62
+ if (sp.gtin) {
63
+ info['g:gtin'] = { _text: sp.gtin || '' };
64
+ }
65
+
66
+ if (sp.storeCode) {
67
+ info['g:store_code'] = { _text: sp.storeCode };
68
+ info['g:link_template'] = { _text: `${link}&store={store_code}` };
69
+ if (availableStores) {
70
+ info['g:pickup_method'] = { _text: 'buy' };
71
+ info['g:pickup_sla'] = { _text: product.prePrint ? 'next day' : 'same day' };
72
+ }
73
+ } else {
74
+ info['g:pickup_method'] = { _text: 'not_supported' };
75
+ }
76
+ if (product.volume) {
77
+ if (product.volume.length) {
78
+ info['g:shipping_length'] = { _text: `${product.volume.length} cm` };
79
+ }
80
+ if (product.volume.width) {
81
+ info['g:shipping_width'] = { _text: `${product.volume.width} cm` };
82
+ }
83
+ if (product.volume.height) {
84
+ info['g:shipping_height'] = { _text: `${product.volume.height} cm` };
85
+ }
86
+ }
87
+ return info;
88
+ })
89
+ ];
90
+ }, [])
91
+ };
92
+
93
+ return {
94
+ _declaration: { _attributes: { version: "1.0", encoding: "utf-8" } },
95
+ rss: {
96
+ _attributes: { version: "2.0", 'xmlns:g': "http://base.google.com/ns/1.0" },
97
+ channel: {
98
+ lastBuildDate: { _text: new Date().toUTCString() },
99
+ docs: { _text: "https://validator.w3.org/feed/docs/rss2.html" },
100
+ ...channel
101
+ },
102
+ },
103
+ }
104
+ }
105
+
106
+ module.exports = {
107
+ googleShoppingFeed
108
+ };
package/feeds/index.js ADDED
@@ -0,0 +1,7 @@
1
+ const { reviewsFeed } = require('./reviews');
2
+ const { googleShoppingFeed } = require('./google-shopping');
3
+
4
+ module.exports = {
5
+ reviewsFeed,
6
+ googleShoppingFeed
7
+ };
@@ -0,0 +1,112 @@
1
+ async function reviewsFeed(axios, config) {
2
+ const { data } = await axios.get(`${config.LOCAL_API_URL}/feed/reviews?host=${config.HOST_NAME}`);
3
+
4
+ return {
5
+ _declaration: { _attributes: { version: "1.0", encoding: "utf-8" } },
6
+ feed: {
7
+ _attributes: {
8
+ 'xmlns:vc': 'http://www.w3.org/2007/XMLSchema-versioning',
9
+ 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
10
+ 'xsi:noNamespaceSchemaLocation': 'http://www.google.com/shopping/reviews/schema/product/2.3/product_reviews.xsd'
11
+ },
12
+ version: { _text: '2.3' },
13
+ publisher: {
14
+ name: { _text: 'Workdepot Australia' },
15
+ favicon: { _text: 'https://www.workdepot.com.au/favicon.png' }
16
+ },
17
+ reviews: {
18
+ review: [
19
+ ...data
20
+ .filter(review => !!review.product)
21
+ .map(review => {
22
+ const { product } = review;
23
+ const productUrl = `https://${config.HOST_NAME}/${product.brand.alias}/${product.productType.alias}/${product.alias}`;
24
+ const item = {
25
+ review_id: { _text: review._id },
26
+ reviewer: {
27
+ name: {
28
+ _attributes: {
29
+ is_anonymous: 'false'
30
+ },
31
+ _text: review.name
32
+ }
33
+ },
34
+ review_timestamp: { _text: review.createdAt },
35
+ title: { _text: product.name },
36
+ content: { _text: review.text },
37
+ pros: {
38
+ pro: (review.pro || '').split(/\n/).map(pro => ({ _text: pro }))
39
+ },
40
+ cons: {
41
+ con: (review.cons || '').split(/\n/).map(cons => ({ _text: cons }))
42
+ },
43
+ review_url: {
44
+ _attributes: {
45
+ type: 'singleton'
46
+ },
47
+ _text: `${productUrl}#review-${review._id}`
48
+ },
49
+ reviewer_images: {
50
+ reviewer_image: [{
51
+ url: { _text: review.image?.large }
52
+ }]
53
+ },
54
+ ratings: {
55
+ overall: {
56
+ _attributes: {
57
+ min: 1,
58
+ max: 5
59
+ },
60
+ _text: review.mark
61
+ }
62
+ },
63
+ products: {
64
+ product: {
65
+ product_ids: {
66
+ gtins: {
67
+ gtin: { _text: product.simpleProduct?.gtin }
68
+ },
69
+ skus: {
70
+ sku: { _text: product.simpleProduct?.SKU }
71
+ },
72
+ brands: {
73
+ brand: { _text: product.brand.name }
74
+ },
75
+ },
76
+ product_name: { _text: product.name },
77
+ product_url: { _text: productUrl }
78
+ }
79
+ },
80
+ is_spam: { _text: 'false' }
81
+ };
82
+
83
+ if (!product.simpleProduct?.gtin) {
84
+ delete item.products.product.product_ids.gtins;
85
+ }
86
+
87
+ if (!product.simpleProduct?.SKU) {
88
+ delete item.products.product.product_ids.skus;
89
+ }
90
+
91
+ if (!review.pro) {
92
+ delete item.pros;
93
+ }
94
+
95
+ if (!review.cons) {
96
+ delete item.cons;
97
+ }
98
+
99
+ if (!review.image) {
100
+ delete item.reviewer_images;
101
+ }
102
+ return item;
103
+ })
104
+ ]
105
+ }
106
+ }
107
+ };
108
+ }
109
+
110
+ module.exports = {
111
+ reviewsFeed
112
+ };
package/nuxt.config.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const sharedRoutes = require('./routes');
2
+ const feeds = require('./feeds');
2
3
 
3
4
  module.exports = (config, axios, { raygunClient, publicPath } = {}) => ({
4
5
  globalName: 'appLancom',
@@ -122,211 +123,12 @@ module.exports = (config, axios, { raygunClient, publicPath } = {}) => ({
122
123
  feed: [{
123
124
  path: '/pr-rev-au.xml',
124
125
  async get() {
125
- const { data } = await axios.get(`${config.LOCAL_API_URL}/feed/reviews?host=${config.HOST_NAME}`);
126
-
127
- return {
128
- _declaration: { _attributes: { version: "1.0", encoding: "utf-8" } },
129
- feed: {
130
- _attributes: {
131
- 'xmlns:vc': 'http://www.w3.org/2007/XMLSchema-versioning',
132
- 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
133
- 'xsi:noNamespaceSchemaLocation': 'http://www.google.com/shopping/reviews/schema/product/2.3/product_reviews.xsd'
134
- },
135
- version: { _text: '2.3' },
136
- publisher: {
137
- name: { _text: 'Workdepot Australia' },
138
- favicon: { _text: 'https://www.workdepot.com.au/favicon.png' }
139
- },
140
- reviews: {
141
- review: [
142
- ...data
143
- .filter(review => !!review.product)
144
- .map(review => {
145
- const { product } = review;
146
- const productUrl = `https://${config.HOST_NAME}/${product.brand.alias}/${product.productType.alias}/${product.alias}`;
147
- const item = {
148
- review_id: { _text: review._id },
149
- reviewer: {
150
- name: {
151
- _attributes: {
152
- is_anonymous: 'false'
153
- },
154
- _text: review.name
155
- }
156
- },
157
- review_timestamp: { _text: review.createdAt },
158
- title: { _text: product.name },
159
- content: { _text: review.text },
160
- pros: {
161
- pro: (review.pro || '').split(/\n/).map(pro => ({ _text: pro }))
162
- },
163
- cons: {
164
- con: (review.cons || '').split(/\n/).map(cons => ({ _text: cons }))
165
- },
166
- review_url: {
167
- _attributes: {
168
- type: 'singleton'
169
- },
170
- _text: `${productUrl}#review-${review._id}`
171
- },
172
- reviewer_images: {
173
- reviewer_image: [{
174
- url: { _text: review.image?.large }
175
- }]
176
- },
177
- ratings: {
178
- overall: {
179
- _attributes: {
180
- min: 1,
181
- max: 5
182
- },
183
- _text: review.mark
184
- }
185
- },
186
- products: {
187
- product: {
188
- product_ids: {
189
- gtins: {
190
- gtin: { _text: product.simpleProduct?.gtin }
191
- },
192
- skus: {
193
- sku: { _text: product.simpleProduct?.SKU }
194
- },
195
- brands: {
196
- brand: { _text: product.brand.name }
197
- },
198
- },
199
- product_name: { _text: product.name },
200
- product_url: { _text: productUrl }
201
- }
202
- },
203
- is_spam: { _text: 'false' }
204
- };
205
-
206
- if (!product.simpleProduct?.gtin) {
207
- delete item.products.product.product_ids.gtins;
208
- }
209
-
210
- if (!product.simpleProduct?.SKU) {
211
- delete item.products.product.product_ids.skus;
212
- }
213
-
214
- if (!review.pro) {
215
- delete item.pros;
216
- }
217
-
218
- if (!review.cons) {
219
- delete item.cons;
220
- }
221
-
222
- if (!review.image) {
223
- delete item.reviewer_images;
224
- }
225
- return item;
226
- })
227
- ]
228
- }
229
- }
230
- };
126
+ return await feeds.reviewsFeed(axios, config);
231
127
  }
232
128
  }, {
233
129
  path: '/google-shopping.xml',
234
130
  async get() {
235
- const { data } = await axios.get(`${config.LOCAL_API_URL}/feed/products?host=${config.HOST_NAME}`);
236
- const spliceFirstImage = images => (images || []).splice(0, 1)[0];
237
- const getImages = images => (images || []).length > 0 ? images : null;
238
- const channel = {
239
- title: { _text: 'All products' },
240
- link: { _text: `https://${config.HOST_NAME}` },
241
- generator: { _text: config.HOST_NAME },
242
- item: data.reduce((items, product) => {
243
- return [
244
- ...items,
245
- ...(product.simpleProducts || []).map(sp => {
246
- const feedImages = (product.images || []).filter(i => (i.types || []).includes('feed_primary') && sp.color._id === i.color).map(i => i.image);
247
- const frontImages = (product.images || []).filter(i => (i.types || []).includes('front') && sp.color._id === i.color).map(i => i.image);
248
- const backImages = (product.images || []).filter(i => (i.types || []).includes('back') && sp.color._id === i.color).map(i => i.image);
249
- const catalogFrontImages = (product.images || []).filter(i => (i.types || []).includes('catalog_front')).map(i => i.image);
250
- const image = spliceFirstImage(feedImages) || spliceFirstImage(frontImages) || spliceFirstImage(catalogFrontImages) || spliceFirstImage(backImages) || {};
251
- const images = getImages(backImages) || getImages(frontImages) || [];
252
- const feedTitle = (product.feedTitle || '')
253
- .replace(/{colour}/g, sp.color.name)
254
- .replace(/{size}/g, sp.size.name)
255
- .replace(/{brand}/g, product.brand.name)
256
- const title = feedTitle || `${product.name} ${sp.color.name}`;
257
- const description = `${product.description || product.fabricInfoShort || product.name || ''}`
258
- .replace(/ /g, ' ')
259
- .replace(/·/, '·');
260
- const link = `https://${config.HOST_NAME}/${product.brand.alias}/${product.productType.alias}/${product.alias}?color=${sp.color.alias}`;
261
- const info = {
262
- title: { _text: title },
263
- description: { _text: description },
264
- link: { _text: link },
265
- 'g:id': { _text: sp.SKU },
266
- 'g:item_group_id': { _text: product.SKU },
267
- 'g:size': { _text: sp.size.name },
268
- 'g:size_system': 'AU',
269
- 'g:size_type': 'regular',
270
- 'g:gender': { _text: product.gender },
271
- 'g:material': { _text: product.fabricInfoShort },
272
- 'g:brand': { _text: product.brand.name },
273
- 'g:condition': { _text: 'new' },
274
- 'g:mpn': { _text: sp.SKU },
275
- 'g:color': { _text: sp.color.name },
276
- 'g:image_link': { _text: image },
277
- 'g:additional_image_link': images.map(i => ({ _text: i })),
278
- 'g:price': { _text: `${(sp.price || 0)} AUD` },
279
- 'g:availability': { _text: sp.quantityStock > 0 ? 'in_stock' : 'out_of_stock' },
280
- 'g:google_product_category': { _text: 2047 },
281
- 'g:product_type': { _text: `Home > Products > ${product.productType.name}`, },
282
- 'g:is_bundle': { _text: product.prePrint ? 'yes' : 'no' },
283
- 'g:identifier_exists': sp.gtin ? 'yes' : 'no',
284
- 'g:product_weight': { _text: `${product.weight} kg` },
285
- 'g:shipping_weight': { _text: `${((product.weight || 0) + (product.weight || 0) * 0.05).toFixed(3)} kg` },
286
- 'g:quantity': { _text: sp.quantityStock },
287
-
288
- };
289
-
290
- if (sp.gtin) {
291
- info['g:gtin'] = { _text: sp.gtin || '' };
292
- }
293
-
294
- if (sp.storeCode) {
295
- info['g:store_code'] = { _text: sp.storeCode };
296
- info['g:link_template'] = { _text: `${link}&store={store_code}` };
297
- info['g:pickup_method'] = { _text: 'buy' };
298
- info['g:pickup_sla'] = { _text: 'next day' };
299
- } else {
300
- info['g:pickup_method'] = { _text: 'not_supported' };
301
- }
302
- if (product.volume) {
303
- if (product.volume.length) {
304
- info['g:shipping_length'] = { _text: `${product.volume.length} cm` };
305
- }
306
- if (product.volume.width) {
307
- info['g:shipping_width'] = { _text: `${product.volume.width} cm` };
308
- }
309
- if (product.volume.height) {
310
- info['g:shipping_height'] = { _text: `${product.volume.height} cm` };
311
- }
312
- }
313
- return info;
314
- })
315
- ];
316
- }, [])
317
- };
318
-
319
- return {
320
- _declaration: { _attributes: { version: "1.0", encoding: "utf-8" } },
321
- rss: {
322
- _attributes: { version: "2.0", 'xmlns:g': "http://base.google.com/ns/1.0" },
323
- channel: {
324
- lastBuildDate: { _text: new Date().toUTCString() },
325
- docs: { _text: "https://validator.w3.org/feed/docs/rss2.html" },
326
- ...channel
327
- },
328
- },
329
- }
131
+ return await feeds.googleShoppingFeed(axios, config);
330
132
  }
331
133
  }],
332
134
  router: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lancom/shared",
3
- "version": "0.0.238",
3
+ "version": "0.0.240",
4
4
  "description": "lancom common scripts",
5
5
  "author": "e.tokovenko <e.tokovenko@gmail.com>",
6
6
  "repository": {
package/store/product.js CHANGED
@@ -196,6 +196,9 @@ export const actions = {
196
196
  const response = await api.fetchPrintTypes(shop);
197
197
  commit('setPrintTypes', response);
198
198
  },
199
+ async updatePriceIncludeGST({ commit }, value) {
200
+ commit('setPriceIncludeGST', value);
201
+ },
199
202
  async calculateProductPrice({ state: { template, product, isPrintPricing }, commit, getters }, shop) {
200
203
  commit('setCalculatingPrice', true);
201
204
  const entities = getProductsForCalculatePricing(product, getters.usedSimpleProducts, template.layers, isPrintPricing, true);