diff --git a/.gitignore b/.gitignore index 6ff3883e..372eb0aa 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ src/config.json config/local.json config/certs/*.pem var/magento2-sample-data/ -var/* .migrate *.iml /docker/elasticsearch/data/ diff --git a/CHANGELOG.md b/CHANGELOG.md index e7630db6..18ddea98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.11.0-rc.1] - UNRELEASED +## [1.11.0-rc.2] - unreleased + +### Fixed + +- Fixed some smaller issues with graphql so that it is now working again with the fronted - #350 + + +## [1.11.0-rc.1] - 2019.10.03 ### Added - Experimental Elastic 7 support - @pkarw (#342) @@ -32,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Error responses for mailchimp - @andrzejewsky (#3337) - Replaced function arguments to object destructuring in `calculateProductTax` - @andrzejewsky (#3337) +- Refactor `taxcalc.js` similar to frontend - @gibkigonzo (#356) ## [1.10.0] - 2019.08.12 @@ -49,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Sharp dependency has been updated. *It might require reinstalling yarn dependencies* - @lukeromanowicz +- Replaced index property value `not_analyzed` with `true` for `options` field in attribute schema - @adityasharma7 (#334) ### Fixed - Missing `res` and `req` parameters are now passed to ProductProcessor - @jahvi (#218) diff --git a/README.md b/README.md index 7df81527..ed766d3c 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Besides a big improvement for the shopping experience, we also want to create a - Docker and Docker Compose Already included in `vue-storefront-api` Docker image (required locally, if you do not use containerization): -- Node.js 8.x or higher +- Node.js 10.x or higher - Yarn ## Installation @@ -144,7 +144,7 @@ This backend is using ElasticSearch data formats popularized by [ElasticSuite fo Please use data migration mechanism provided to manipulate Redis, ElasticSearch or kue. Details: https://github.com/DivanteLtd/vue-storefront-api/tree/master/doc ## Adding custom modules with own dependencies (Yarn only) -When adding custom [Extensions to the API](https://github.com/DivanteLtd/vue-storefront/blob/master/doc/Extending%20vue-storefront-api.md) you might want to define some dependencies inside them. Thanks to [Yarn workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) dependecies defined inside your custom module will be intaled when you execute `yarn` at project root level, so it's way esier and faster than installing all modules dependcies separetly. +When adding custom [Extensions to the API](https://github.com/DivanteLtd/vue-storefront/blob/master/doc/Extending%20vue-storefront-api.md) you might want to define some dependencies inside them. Thanks to [Yarn workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) dependencies defined inside your custom module will be installed when you execute `yarn` at project root level, so it's way easier and faster than installing all modules dependencies separately. To do this, define the `package.json` with your dependencies in your custom module: - `src/api/extensions/{your-custom-extension}/package.json` diff --git a/config/default.json b/config/default.json index a3ab42c8..9c856f21 100644 --- a/config/default.json +++ b/config/default.json @@ -63,6 +63,7 @@ "storeCode": "de", "disabled": false, "storeId": 3, + "websiteId": 1, "name": "German Store", "url": "/de", "elasticsearch": { @@ -97,6 +98,7 @@ "storeCode": "it", "disabled": false, "storeId": 4, + "websiteId": 1, "name": "Italian Store", "url": "/it", "elasticsearch": { diff --git a/config/elastic.schema.attribute.json b/config/elastic.schema.attribute.json index f9dd5232..8c976c90 100644 --- a/config/elastic.schema.attribute.json +++ b/config/elastic.schema.attribute.json @@ -14,4 +14,4 @@ } } } -} \ No newline at end of file +} diff --git a/config/elastic.schema.category.json b/config/elastic.schema.category.json index 9205fd66..5290d92c 100644 --- a/config/elastic.schema.category.json +++ b/config/elastic.schema.category.json @@ -6,13 +6,13 @@ "is_active": {"type": "boolean"}, "product_count": {"type": "integer"}, "parent_id": {"type": "integer"}, - "position": {"type": "long"}, - "created_at": { - "type": "date", + "position": {"type": "integer"}, + "created_at": { + "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" }, - "updated_at": { - "type": "date", + "updated_at": { + "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } diff --git a/scripts/db.js b/scripts/db.js index 95bc025b..cc26b7c2 100644 --- a/scripts/db.js +++ b/scripts/db.js @@ -24,6 +24,10 @@ program console.log(`** Putting the mappings on top of ${tempIndex}`) es.putMappings(common.db, tempIndex, (err) => { + if (err) { + console.error(err.meta ? err.meta : err) + } + console.log(`** We will reindex ${originalIndex} with the current schema`) es.reIndex(common.db, originalIndex, tempIndex, (err) => { if (err) { diff --git a/src/api/user.js b/src/api/user.js index 71292917..69210381 100755 --- a/src/api/user.js +++ b/src/api/user.js @@ -119,12 +119,14 @@ export default ({config, db}) => { */ userApi.post('/reset-password', (req, res) => { const userProxy = _getProxy(req) + const storeCode = req.query.storeCode + const websiteId = config.storeViews[storeCode].websiteId if (!req.body.email) { return apiStatus(res, 'Invalid e-mail provided!', 500) } - userProxy.resetPassword({ email: req.body.email, template: 'email_reset', websiteId: 1 }).then((result) => { + userProxy.resetPassword({ email: req.body.email, template: 'email_reset', websiteId }).then((result) => { apiStatus(res, result, 200); }).catch(err => { apiError(res, err); @@ -150,10 +152,10 @@ export default ({config, db}) => { userApi.get('/order-history', (req, res) => { const userProxy = _getProxy(req) userProxy.orderHistory( - req.query.token, - req.query.pageSize || 20, - req.query.currentPage || 1 - ).then((result) => { + req.query.token, + req.query.pageSize || 20, + req.query.currentPage || 1 + ).then((result) => { apiStatus(res, result, 200); }).catch(err => { apiError(res, err); diff --git a/src/db.js b/src/db.js index a8279bf5..b16dafa0 100755 --- a/src/db.js +++ b/src/db.js @@ -1,6 +1,6 @@ import config from 'config' -import * as redis from '../src/lib/redis' -import * as elastic from '../src/lib/elastic' +import * as redis from './lib/redis' +import * as elastic from './lib/elastic' export default callback => { // connect to a database if needed, then pass it to `callback`: diff --git a/src/graphql/elasticsearch/attribute/resolver.js b/src/graphql/elasticsearch/attribute/resolver.js index c498d1c9..1ff28a73 100644 --- a/src/graphql/elasticsearch/attribute/resolver.js +++ b/src/graphql/elasticsearch/attribute/resolver.js @@ -16,9 +16,6 @@ async function listAttributes (attributes, context, rootValue, _sourceIncludes) body: query, _sourceIncludes }; - if (parseInt(config.elasticsearch.apiVersion) < 6) { - esQuery.type = config.elasticsearch.indexTypes[3] - } const response = await client.search(adjustQuery(esQuery, 'attribute', config)); diff --git a/src/graphql/elasticsearch/catalog/schema.graphqls b/src/graphql/elasticsearch/catalog/schema.graphqls index 25a8c6b0..86fdcffe 100644 --- a/src/graphql/elasticsearch/catalog/schema.graphqls +++ b/src/graphql/elasticsearch/catalog/schema.graphqls @@ -41,7 +41,7 @@ input FilterTypeInput @doc(description: "FilterTypeInput specifies which action gte: String @doc(description: "Greater than or equal to") gteq: String @doc(description: "Greater than or equal to") in: [JSON] @doc(description: "In. The value can contain a set of comma-separated values") - like: String @doc(description: "Like. The specified value can contain % (percent signs) to allow matching of 0 or more characters") + like: [String] @doc(description: "Like. The specified value can contain % (percent signs) to allow matching of 0 or more characters") lt: String @doc(description: "Less than") lte: String @doc(description: "Less than or equal to") lteq: String @doc(description: "Less than or equal to") @@ -151,6 +151,7 @@ input ProductFilterInput @doc(description: "ProductFilterInput defines the filte stock: ProductFilterInput @doc(description: "The product stock. Customers use this stock to identify the product.") is_in_stock: FilterTypeInput @doc(description: "Is product in stock") keyword: FilterTypeInput @doc(description: "keyword filter input") + url_path: FilterTypeInput @doc(description: "The url path assigned to the product") } type LayerFilter { @@ -182,4 +183,4 @@ type SortFields @doc(description: "SortFields contains a default value for sort enum SortEnum { ASC DESC -} \ No newline at end of file +} diff --git a/src/graphql/elasticsearch/category/schema.graphqls b/src/graphql/elasticsearch/category/schema.graphqls index 2e7b2321..7873d74e 100644 --- a/src/graphql/elasticsearch/category/schema.graphqls +++ b/src/graphql/elasticsearch/category/schema.graphqls @@ -59,4 +59,5 @@ input CategorySortInput { display_mode: SortEnum @doc(description: "Category display mode") is_anchor: SortEnum @doc(description: "Is filter avalaible in category") page_layout: SortEnum @doc(description: "Category page layout") -} \ No newline at end of file + _score: SortEnum @doc(description: "Category page layout") +} diff --git a/src/graphql/elasticsearch/cms/schema.graphqls b/src/graphql/elasticsearch/cms/schema.graphqls index 85fb231a..6d91b273 100644 --- a/src/graphql/elasticsearch/cms/schema.graphqls +++ b/src/graphql/elasticsearch/cms/schema.graphqls @@ -17,6 +17,7 @@ input CmsInput @doc(description: "ProductFilterInput defines the filters to be u id: FilterTypeInput @doc(description: "Id of the CMS entity") identifier: FilterTypeInput @doc(description: "Identifiers of the CMS entity") store_id: FilterTypeInput @doc(description: "Store Id of the CMS entity") + url_path: FilterTypeInput @doc(description: "The url path assigned to the cms_page") } type CmsPage @doc(description: "CMS pages information") { @@ -32,6 +33,7 @@ type CmsPages @doc(description: "CMS page defines all CMS page information") { meta_description: String @doc(description: "CMS page meta description") meta_keywords: String @doc(description: "CMS page meta keywords") store_id: Int @doc(description: "Store Id of CMS page") + url_path: String @doc(description: "CMS page meta keywords") } type CmsBlocks @doc(description: "CMS blocks information") { @@ -40,6 +42,7 @@ type CmsBlocks @doc(description: "CMS blocks information") { type CmsBlock @doc(description: "CMS block defines all CMS block information") { identifier: String @doc(description: "CMS block identifier") + id: Int @doc(description: "CMS block identifier") title: String @doc(description: "CMS block title") content: String @doc(description: "CMS block content") creation_time: String @doc(description: "Timestamp indicating when the CMS block was created") @@ -60,4 +63,4 @@ type CmsHierarchy { request_url: String @doc(description: "Request URL of CMS hierarchy node") xpath: String @doc(description: "XPATH of CMS hierarchy node") store_id: Int @doc(description: "Store Id of CMS hierarchy node") -} \ No newline at end of file +} diff --git a/src/graphql/elasticsearch/queryBuilder.js b/src/graphql/elasticsearch/queryBuilder.js index d5e89942..8eb3927b 100644 --- a/src/graphql/elasticsearch/queryBuilder.js +++ b/src/graphql/elasticsearch/queryBuilder.js @@ -18,6 +18,16 @@ function processNestedFieldFilter (attribute, value) { return processedFilter; } +/** + * + * @param {Object} object + * @param {String} scope + * @returns {boolean} + */ +function checkIfObjectHasScope ({ object, scope }) { + return object.scope === scope || (Array.isArray(object.scope) && object.scope.find(scrope => scrope === scope)); +} + function applyFilters (filter, query, type) { if (filter.length === 0) { return query @@ -46,7 +56,7 @@ function applyFilters (filter, query, type) { // apply default filters appliedFilters.forEach((filter) => { - if (filter.scope === 'default' && Object.keys(filter.value).length) { + if (checkIfObjectHasScope({ object: filter, scope: 'default' }) && Object.keys(filter.value).length) { if (rangeOperators.every(rangeOperator => Object.prototype.hasOwnProperty.call(filter.value, rangeOperator))) { // process range filters query = query.filter('range', filter.attribute, filter.value); @@ -67,7 +77,7 @@ function applyFilters (filter, query, type) { let attrFilterBuilder = (filterQr, attrPostfix = '') => { appliedFilters.forEach((catalogfilter) => { const valueKeys = Object.keys(catalogfilter.value); - if (catalogfilter.scope === 'catalog' && valueKeys.length) { + if (checkIfObjectHasScope({ object: catalogfilter, scope: 'catalog' }) && valueKeys.length) { const isRange = valueKeys.filter(value => rangeOperators.indexOf(value) !== -1) if (isRange.length) { let rangeAttribute = catalogfilter.attribute diff --git a/src/lib/elastic.js b/src/lib/elastic.js index 130274d1..84b8ad22 100644 --- a/src/lib/elastic.js +++ b/src/lib/elastic.js @@ -138,7 +138,6 @@ function reIndex (db, fromIndexName, toIndexName, next) { }).then(res => { next() }).catch(err => { - console.error(err) next(err) }) } @@ -215,58 +214,40 @@ function putMappings (db, indexName, next) { let pageSchema = loadSchema('cms_page', '5.6'); let blockSchema = loadSchema('cms_block', '5.6'); - db.indices.putMapping({ - index: indexName, - type: 'product', - body: productSchema - }).then(res1 => { - console.dir(res1, { depth: null, colors: true }) - + Promise.all([ + db.indices.putMapping({ + index: indexName, + type: 'product', + body: productSchema + }), db.indices.putMapping({ index: indexName, type: 'taxrule', body: taxruleSchema - }).then(res2 => { - console.dir(res2, { depth: null, colors: true }) - - db.indices.putMapping({ - index: indexName, - type: 'attribute', - body: attributeSchema - }).then(res3 => { - console.dir(res3, { depth: null, colors: true }) - db.indices.putMapping({ - index: indexName, - type: 'cms_page', - body: pageSchema - }).then(res4 => { - console.dir(res4, { depth: null, colors: true }) - db.indices.putMapping({ - index: indexName, - type: 'cms_block', - body: blockSchema - }).then(res5 => { - console.dir(res5, { depth: null, colors: true }) - db.indices.putMapping({ - index: indexName, - type: 'category', - body: categorySchema - }).then(res6 => { - console.dir(res6, { depth: null, colors: true }) - next() - }) - }) - }) - }).catch(err3 => { - throw new Error(err3) - }) - }).catch(err2 => { - throw new Error(err2) + }), + db.indices.putMapping({ + index: indexName, + type: 'attribute', + body: attributeSchema + }), + db.indices.putMapping({ + index: indexName, + type: 'cms_page', + body: pageSchema + }), + db.indices.putMapping({ + index: indexName, + type: 'cms_block', + body: blockSchema + }), + db.indices.putMapping({ + index: indexName, + type: 'category', + body: categorySchema }) - }).catch(err1 => { - console.error(err1) - next(err1) - }) + ]).then(values => values.forEach(res => console.dir(res.body, { depth: null, colors: true }))) + .then(next) + .catch(next) } module.exports = { diff --git a/src/lib/taxcalc.js b/src/lib/taxcalc.js index 3f8c3916..5185a3eb 100644 --- a/src/lib/taxcalc.js +++ b/src/lib/taxcalc.js @@ -1,3 +1,5 @@ +import camelCase from 'lodash/camelCase' + function isSpecialPriceActive (fromDate, toDate) { if (!fromDate && !toDate) { return true @@ -20,84 +22,96 @@ function isSpecialPriceActive (fromDate, toDate) { } } +/** + * change object keys to camelCase + */ +function toCamelCase (obj = {}) { + return Object.keys(obj).reduce((accObj, currKey) => { + accObj[camelCase(currKey)] = obj[currKey] + return accObj + }, {}) +} + +/** + * Create price object with base price and tax + * @param price - product price which is used to extract tax value + * @param rateFactor - tax % in decimal + * @param isPriceInclTax - determines if price already include tax + */ +function createSinglePrice (price = 0, rateFactor = 0, isPriceInclTax) { + const _price = isPriceInclTax ? price / (1 + rateFactor) : price + const tax = _price * rateFactor + + return { price: _price, tax } +} + +/** + * assign price and tax to product with proper keys + * @param AssignPriceParams + */ +function assignPrice ({ product, target, price = 0, tax = 0, deprecatedPriceFieldsSupport = true }) { + let priceUpdate = { + [target]: price, + [`${target}_tax`]: tax, + [`${target}_incl_tax`]: price + tax + } + + if (deprecatedPriceFieldsSupport) { + /** BEGIN @deprecated - inconsitent naming kept just for the backward compatibility */ + priceUpdate = Object.assign(priceUpdate, toCamelCase(priceUpdate)) + /** END */ + } + + Object.assign(product, priceUpdate) +} + export function updateProductPrices ({ product, rate, sourcePriceInclTax = false, deprecatedPriceFieldsSupport = false, finalPriceInclTax = true }) { const rate_factor = parseFloat(rate.rate) / 100 - if (finalPriceInclTax) { - product.final_price_incl_tax = parseFloat(product.final_price) // final price does include tax - product.final_price = product.final_price_incl_tax / (1 + rate_factor) - product.final_price_tax = product.final_price_incl_tax - product.final_price - } else { - product.final_price = parseFloat(product.final_price) // final price does include tax - product.final_price_tax = product.final_price * rate_factor - product.final_price_incl_tax = product.final_price + product.final_price_tax + const hasOriginalPrices = ( + product.hasOwnProperty('original_price') && + product.hasOwnProperty('original_final_price') && + product.hasOwnProperty('original_special_price') + ) + // build objects with original price and tax + // for first calculation use `price`, for next one use `original_price` + const priceWithTax = createSinglePrice(parseFloat(product.original_price || product.price), rate_factor, sourcePriceInclTax && !hasOriginalPrices) + const finalPriceWithTax = createSinglePrice(parseFloat(product.original_final_price || product.final_price), rate_factor, finalPriceInclTax && !hasOriginalPrices) + const specialPriceWithTax = createSinglePrice(parseFloat(product.original_special_price || product.special_price), rate_factor, sourcePriceInclTax && !hasOriginalPrices) + + // save original prices + if (!hasOriginalPrices) { + assignPrice({product, target: 'original_price', ...priceWithTax, deprecatedPriceFieldsSupport}) + + product.original_final_price = finalPriceWithTax.price + product.original_special_price = specialPriceWithTax.price } - product.price = parseFloat(product.price) - product.special_price = parseFloat(product.special_price) + + // reset previous calculation + assignPrice({product, target: 'price', ...priceWithTax, deprecatedPriceFieldsSupport}) + assignPrice({product, target: 'final_price', ...finalPriceWithTax, deprecatedPriceFieldsSupport}) + assignPrice({product, target: 'special_price', ...specialPriceWithTax, deprecatedPriceFieldsSupport}) if (product.final_price) { if (product.final_price < product.price) { // compare the prices with the product final price if provided; final prices is used in case of active catalog promo rules for example if (product.final_price < product.special_price) { // for VS - special_price is any price lowered than regular price (`price`); in Magento there is a separate mechanism for setting the `special_prices` - product.price = product.special_price // if the `final_price` is lower than the original `special_price` - it means some catalog rules were applied over it + assignPrice({product, target: 'price', ...specialPriceWithTax, deprecatedPriceFieldsSupport}) // if the `final_price` is lower than the original `special_price` - it means some catalog rules were applied over it } - product.special_to_date = null - product.special_from_date = null - product.special_price = product.final_price + assignPrice({product, target: 'special_price', ...finalPriceWithTax, deprecatedPriceFieldsSupport}) } else { - product.price = product.final_price + assignPrice({product, target: 'price', ...finalPriceWithTax, deprecatedPriceFieldsSupport}) } } - let price_excl_tax = product.price - if (sourcePriceInclTax) { - price_excl_tax = product.price / (1 + rate_factor) - product.price = price_excl_tax - } - - product.price_tax = price_excl_tax * rate_factor - product.price_incl_tax = price_excl_tax + product.price_tax - - let special_price_excl_tax = product.special_price - if (sourcePriceInclTax) { - special_price_excl_tax = product.special_price / (1 + rate_factor) - product.special_price = special_price_excl_tax - } - - product.special_price_tax = special_price_excl_tax * rate_factor - product.special_price_incl_tax = special_price_excl_tax + product.special_price_tax - - if (deprecatedPriceFieldsSupport) { - /** BEGIN @deprecated - inconsitent naming kept just for the backward compatibility */ - product.priceTax = product.price_tax - product.priceInclTax = product.price_incl_tax - product.specialPriceTax = product.special_price_tax - product.specialPriceInclTax = product.special_price_incl_tax - /** END */ - } - - if (product.special_price && (product.special_price < product.price)) { + if (product.special_price && (product.special_price < product.original_price)) { if (!isSpecialPriceActive(product.special_from_date, product.special_to_date)) { - product.special_price = 0 // out of the dates period + // out of the dates period + assignPrice({product, target: 'special_price', price: 0, tax: 0, deprecatedPriceFieldsSupport}) } else { - product.original_price = price_excl_tax - product.original_price_incl_tax = product.price_incl_tax - product.original_price_tax = product.price_tax - - product.price = special_price_excl_tax - product.price_incl_tax = product.special_price_incl_tax - product.price_tax = product.special_price_tax - - if (deprecatedPriceFieldsSupport) { - /** BEGIN @deprecated - inconsitent naming kept just for the backward compatibility */ - product.priceInclTax = product.price_incl_tax - product.priceTax = product.price_tax - product.originalPrice = product.original_price - product.originalPriceInclTax = product.original_price_incl_tax - product.originalPriceTax = product.original_price_tax - /** END */ - } + assignPrice({product, target: 'price', ...specialPriceWithTax, deprecatedPriceFieldsSupport}) } } else { - product.special_price = 0 // the same price as original; it's not a promotion + // the same price as original; it's not a promotion + assignPrice({product, target: 'special_price', price: 0, tax: 0, deprecatedPriceFieldsSupport}) } if (product.configurable_children) { @@ -107,100 +121,25 @@ export function updateProductPrices ({ product, rate, sourcePriceInclTax = false configurableChild[opt.attribute_code] = opt.value } } - configurableChild.price = parseFloat(configurableChild.price) - configurableChild.special_price = parseFloat(configurableChild.special_price) - configurableChild.final_price_incl_tax = parseFloat(configurableChild.final_price) // final price does include tax - configurableChild.final_price = configurableChild.final_price_incl_tax / (1 + rate_factor) - - if (configurableChild.final_price) { - if (configurableChild.final_price < configurableChild.price) { // compare the prices with the product final price if provided; final prices is used in case of active catalog promo rules for example - if (configurableChild.final_price < configurableChild.special_price) { // for VS - special_price is any price lowered than regular price (`price`); in Magento there is a separate mechanism for setting the `special_prices` - configurableChild.price = configurableChild.special_price // if the `final_price` is lower than the original `special_price` - it means some catalog rules were applied over it - } - configurableChild.special_to_date = null - configurableChild.special_from_date = null - configurableChild.special_price = product.final_price - } else { - configurableChild.price = configurableChild.final_price - } - } - - let price_excl_tax = configurableChild.price - if (sourcePriceInclTax) { - price_excl_tax = configurableChild.price / (1 + rate_factor) - configurableChild.price = price_excl_tax - } - - configurableChild.price_tax = price_excl_tax * rate_factor - configurableChild.price_incl_tax = price_excl_tax + configurableChild.price_tax - - let special_price_excl_tax = parseFloat(configurableChild.special_price) - - if (sourcePriceInclTax) { - special_price_excl_tax = configurableChild.special_price / (1 + rate_factor) - configurableChild.special_price = special_price_excl_tax - } - configurableChild.special_price_tax = special_price_excl_tax * rate_factor - configurableChild.special_price_incl_tax = special_price_excl_tax + configurableChild.special_price_tax - - if (deprecatedPriceFieldsSupport) { - /** BEGIN @deprecated - inconsitent naming kept just for the backward compatibility */ - configurableChild.priceTax = configurableChild.price_tax - configurableChild.priceInclTax = configurableChild.price_incl_tax - configurableChild.specialPriceTax = configurableChild.special_price_tax - configurableChild.specialPriceInclTax = configurableChild.special_price_incl_tax - /** END */ - } - - if (configurableChild.special_price && (configurableChild.special_price < configurableChild.price)) { - if (!isSpecialPriceActive(configurableChild.special_from_date, configurableChild.special_to_date)) { - configurableChild.special_price = 0 // out of the dates period - } else { - configurableChild.original_price = price_excl_tax - configurableChild.original_price_incl_tax = configurableChild.price_incl_tax - configurableChild.original_price_tax = configurableChild.price_tax - - configurableChild.price = special_price_excl_tax - configurableChild.price_incl_tax = configurableChild.special_price_incl_tax - configurableChild.price_tax = configurableChild.special_price_tax - - if (deprecatedPriceFieldsSupport) { - /** BEGIN @deprecated - inconsitent naming kept just for the backward compatibility */ - configurableChild.originalPrice = configurableChild.original_price - configurableChild.originalPriceInclTax = configurableChild.original_price_incl_tax - configurableChild.originalPriceTax = configurableChild.original_price_tax - configurableChild.priceInclTax = configurableChild.price_incl_tax - configurableChild.priceTax = configurableChild.price_tax - /** END */ - } - } - } else { - configurableChild.special_price = 0 - } + // update children prices + updateProductPrices({ product: configurableChild, rate, sourcePriceInclTax, deprecatedPriceFieldsSupport, finalPriceInclTax }) if ((configurableChild.price_incl_tax <= product.price_incl_tax) || product.price === 0) { // always show the lowest price - product.price_incl_tax = configurableChild.price_incl_tax - product.price_tax = configurableChild.price_tax - product.price = configurableChild.price - product.special_price = configurableChild.special_price - product.special_price_incl_tax = configurableChild.special_price_incl_tax - product.special_price_tax = configurableChild.special_price_tax - product.original_price = configurableChild.original_price - product.original_price_incl_tax = configurableChild.original_price_incl_tax - product.original_price_tax = configurableChild.original_price_tax - - if (deprecatedPriceFieldsSupport) { - /** BEGIN @deprecated - inconsitent naming kept just for the backward compatibility */ - product.priceInclTax = product.price_incl_tax - product.priceTax = product.price_tax - product.specialPriceInclTax = product.special_price_incl_tax - product.specialPriceTax = product.special_price_tax - product.originalPrice = product.original_price - product.originalPriceInclTax = product.original_price_incl_tax - product.originalPriceTax = product.original_price_tax - /** END */ - } + assignPrice({ + product, + target: 'price', + price: configurableChild.price, + tax: configurableChild.price_tax, + deprecatedPriceFieldsSupport + }) + assignPrice({ + product, + target: 'special_price', + price: configurableChild.special_price, + tax: configurableChild.special_price_tax, + deprecatedPriceFieldsSupport + }) } } } @@ -230,7 +169,7 @@ export function calculateProductTax ({ product, taxClasses, taxCountry = 'PL', t } } if (!rateFound) { - updateProductPrices({ product, rate: {rate: 0} }) + updateProductPrices({ product, rate: {rate: 0}, sourcePriceInclTax, deprecatedPriceFieldsSupport }) product.price_incl_tax = product.price product.price_tax = 0 diff --git a/src/platform/magento2/user.js b/src/platform/magento2/user.js index b8eab151..c5b0fe7f 100644 --- a/src/platform/magento2/user.js +++ b/src/platform/magento2/user.js @@ -21,7 +21,7 @@ class UserProxy extends AbstractUserProxy { return this.api.customers.me(requestToken) } - orderHistory (requestToken, pageSize = 20, currentPage = 1) { + orderHistory (requestToken, pageSize = 20, currentPage = 1) { return this.api.customers.orderHistory(requestToken, pageSize, currentPage) } resetPassword (emailData) { diff --git a/var/catalog.json b/var/catalog.json new file mode 100644 index 00000000..197c37c4 --- /dev/null +++ b/var/catalog.json @@ -0,0 +1,2642 @@ +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"166","_score":1,"_source":{"id":166,"title":"it's really ugly,","detail":"Its fine I guess but it's really ugly, I picked out a really cute bag for college but my mom got me this one instead.","nickname":"Tracee","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"172","_score":1,"_source":{"id":172,"title":"Um, not actually waterproof","detail":"This bag is definitely not waterproof. I accidentally left it outside in a downpour, and my clothes got soaked. I'm disappointed!","nickname":"Aiko","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"183","_score":1,"_source":{"id":183,"title":"Keeps excellent time and is pretty tough","detail":"Keeps excellent time and is pretty tough! Still no scratches or scuffs after a year of wearing it.","nickname":"Denese","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"190","_score":1,"_source":{"id":190,"title":"Softest hoodie ever","detail":"This hoodie may be the softest thing I've ever touched! It's so perfect for curling up on a chilly day. I wore it hiking on a really cold day last November and it kept me really warm. My only issue is that it's kind of plain and unflattering. I would love to wear it all the time but it makes me look a little frumpy. Luma, I need this fabric with a more stylish design!","nickname":"Martina","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"204","_score":1,"_source":{"id":204,"title":"Pocket too small for mp3","detail":"The mp3 pocket barely fits my device. I was hoping for a slightly larger pocket.","nickname":"Rolande","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"206","_score":1,"_source":{"id":206,"title":"Shrinks a lot","detail":"Mine shrunk to! :( I gave it to my little sister.","nickname":"Alesha","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"208","_score":1,"_source":{"id":208,"title":"my new fave zip up","detail":"OMG, I've found my new fave zip up!! I live in this thing! I'm just mad their arent more colors.","nickname":"Lakeesha","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"222","_score":1,"_source":{"id":222,"title":"This is my go-to jacket","detail":"This is my go-to jacket when I'm running in the rain or cold! It's warm but lightweight, totally waterproof, and I love the colors!","nickname":"Kellye","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"227","_score":1,"_source":{"id":227,"title":"Everyone loves this jacket on me","detail":"I got this jacket for tennis practice since its in my schools color and everyone on the team loves it!!","nickname":"Kristyn","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"229","_score":1,"_source":{"id":229,"title":"Overheated","detail":"I agree with that other reviewer. I get very overheated while wearing this jacket while shoveling snow. ","nickname":"Venetta","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"240","_score":1,"_source":{"id":240,"title":"These pants move so well!","detail":"These pants move so well! They provide nice coverage so when I'm in Downward Dog, I don't have to worry. I don't know about this Cooltech technology though. I sweat in them, so they definitely don't keep me dry. They're pretty warm!","nickname":"Deloise","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"253","_score":1,"_source":{"id":253,"title":"I really dig this shirt for races","detail":"I really dig this shirt for races, it makes me feel like I'm flying.","nickname":"Lorena","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"254","_score":1,"_source":{"id":254,"title":"This shirt is decent for running","detail":"This shirt is pretty good! I'm a long distance runner and it keeps me pretty comfortable, although these companies always act like their shirts are magical and really it's just pretty basic stuff. Still it's a decent shirt and I would recommend it. Just don't expect it to change your life.","nickname":"Allyson","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"256","_score":1,"_source":{"id":256,"title":"Fits my large head TG","detail":"So I have a really large head and I love this shirt bc the neckline is so stretchy! Honestly I have gotten stuck in other running shirts with the really small collar hahahahaha so embarrassing!!! !!","nickname":"Hsiu","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"259","_score":1,"_source":{"id":259,"title":"Fabric is great for sport","detail":"I do think the fabric is great for sports but the cut and style are weeeird.","nickname":"Becki","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"260","_score":1,"_source":{"id":260,"title":"Doesn't help my figure one bit","detail":"The contored design is NOT really contored. I rarely wear this top out because it doesn't do anything for my figure.","nickname":"Hellen","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"264","_score":1,"_source":{"id":264,"title":"Looks and feels aweseom ","detail":"Really like the seams. Looks and feels awesome!","nickname":"Skye","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"265","_score":1,"_source":{"id":265,"title":"Really close-fitting. Do not love.","detail":"Really close-fitting. Do not love.","nickname":"Amberly","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"270","_score":1,"_source":{"id":270,"title":"Like the color .sleeves were too tight. ","detail":"Like the color .sleeves were too tight. felt constricted.","nickname":"Elmira","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"295","_score":1,"_source":{"id":295,"title":"I absolutely love these trainers. I can ","detail":"I absolutely love these trainers. I can get on the gym floor so quick becuz i don't have to tie any annoying ties.","nickname":"Rosy","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"300","_score":1,"_source":{"id":300,"title":"I can appreciate the concept, but I thin","detail":"I can appreciate the concept, but I think I'll be going back to regular laced sneakers from now on, they just didn't seem to fit my feet as well I guess because my feet are so narrow. People with narrow feet shouldn't buy these!","nickname":"Gertrud","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"302","_score":1,"_source":{"id":302,"title":"These are really well made and so lightw","detail":"These are really well made and so lightweight. I'll definitely be buying more of these.","nickname":"Nadene","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:46","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"314","_score":1,"_source":{"id":314,"title":"Meh, I'm not hating them, but I'm not in","detail":"Meh, I'm not hating them, but I'm not in love. The eyelet part looks way different online and the elastic band felt really tight. They are pretty comfy other than that.","nickname":"Eugena","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:47","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"313","_score":1,"_source":{"id":313,"title":"Pic is WAY different then the real thing","detail":"Pic is WAY different then the real thing! My mom wouldn't even wear these there so ugly! Can I give a 0 rating?","nickname":"Garnett","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:47","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"322","_score":1,"_source":{"id":322,"title":"So, so awesome. Great Support!","detail":"So, so awesome. Great Support! I just can't wait for the day that I'm comfortable enough with my midriff to wear this sans shirt, because the pattern is really cute!!","nickname":"Dorcas","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:47","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"332","_score":1,"_source":{"id":332,"title":"Sizes are off","detail":"I had to order 3 sizes before I found my fit. The sizes do NOT line up. I did like it in the end. Just took too long to get there.","nickname":"Krystina","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:47","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"335","_score":1,"_source":{"id":335,"title":"Not for non-petite","detail":"Watch out if you're shapely like me - this tiny thing makes it hard to breath! ","nickname":"Teofila","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:47","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"338","_score":1,"_source":{"id":338,"title":"Not for high impact","detail":"Definitely not good for anything high-impact, but it's very stylish for yoga or something else low impact.","nickname":"Merrie","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:47","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"340","_score":1,"_source":{"id":340,"title":"Great fit - love the v-neck design! ","detail":"Great fit - love the v-neck design! ","nickname":"Thalia","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:47","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"343","_score":1,"_source":{"id":343,"title":"Good choice for working out","detail":"Good choice for working out and stylin' enough to wear when I'm hanging with friends on hot days. Also washes really well! ","nickname":"Elfriede","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:47","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"349","_score":1,"_source":{"id":349,"title":"Test","detail":"This is a test review","nickname":"Test","customer_id":1793,"review_entity":"product","review_type":1,"review_status":2,"created_at":"2018-11-07 04:27:51","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"351","_score":1,"_source":{"id":351,"title":"Divante","detail":"wefwef","nickname":"piotr","review_entity":"product","review_type":3,"review_status":2,"created_at":"2018-11-14 11:53:14","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"356","_score":1,"_source":{"id":356,"title":"test","detail":"test","nickname":"test","customer_id":1,"review_entity":"product","review_type":1,"review_status":1,"created_at":"2018-11-21 11:29:10","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"365","_score":1,"_source":{"id":365,"title":"sdf","detail":"sdf","nickname":"sd","review_entity":"product","review_type":3,"review_status":2,"created_at":"2018-12-08 17:55:05","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"366","_score":1,"_source":{"id":366,"title":"sdf","detail":"sdf","nickname":"dr","review_entity":"product","review_type":3,"review_status":2,"created_at":"2018-12-08 17:55:37","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"372","_score":1,"_source":{"id":372,"title":"this is a demo review","detail":"this is a demo review","nickname":"First","customer_id":2383,"review_entity":"product","review_type":1,"review_status":2,"created_at":"2018-12-24 21:10:52","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"369","_score":1,"_source":{"id":369,"title":"proba","detail":"proba proba","nickname":"A","review_entity":"product","review_type":3,"review_status":2,"created_at":"2018-12-13 10:12:12","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"374","_score":1,"_source":{"id":374,"title":"TestSummary","detail":"TestRewiev","nickname":"TestFirst","customer_id":2400,"review_entity":"product","review_type":1,"review_status":2,"created_at":"2018-12-26 15:41:40","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"383","_score":1,"_source":{"id":383,"title":"123","detail":"123","nickname":"123","review_entity":"product","review_type":3,"review_status":2,"created_at":"2019-01-17 19:59:02","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"385","_score":1,"_source":{"id":385,"title":"312312312","detail":"312312312","nickname":"Alex","customer_id":2579,"review_entity":"product","review_type":1,"review_status":2,"created_at":"2019-01-17 21:55:23","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"386","_score":1,"_source":{"id":386,"title":"123","detail":"123","nickname":"123","review_entity":"product","review_type":3,"review_status":2,"created_at":"2019-01-18 00:56:12","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"387","_score":1,"_source":{"id":387,"title":"Test","detail":"Test Review","nickname":"Test","review_entity":"product","review_type":3,"review_status":2,"created_at":"2019-01-23 22:17:57","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"397","_score":1,"_source":{"id":397,"title":"Test","detail":"TEst","nickname":"Ace","customer_id":2828,"review_entity":"product","review_type":1,"review_status":2,"created_at":"2019-02-13 06:31:39","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"400","_score":1,"_source":{"id":400,"title":"asdasd","detail":"adasd","nickname":"Andrei","customer_id":2947,"review_entity":"product","review_type":1,"review_status":2,"created_at":"2019-02-17 01:31:35","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"407","_score":1,"_source":{"id":407,"title":"bhjb","detail":"vhjk","nickname":"sv","customer_id":3302,"review_entity":"product","review_type":1,"review_status":2,"created_at":"2019-02-26 14:24:48","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"408","_score":1,"_source":{"id":408,"title":"Demo","detail":"Demo","nickname":"Demo","review_entity":"product","review_type":3,"review_status":2,"created_at":"2019-02-27 06:52:42","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"415","_score":1,"_source":{"id":415,"title":"testr","detail":"test","nickname":"test","customer_id":8166,"review_entity":"product","review_type":1,"review_status":2,"created_at":"2019-03-21 17:06:40","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"423","_score":1,"_source":{"id":423,"title":"Test summary","detail":"Test review body, that should appear on poduct page^^","nickname":"Tester","review_entity":"product","review_type":3,"review_status":1,"created_at":"2019-03-27 08:43:06","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"449","_score":1,"_source":{"id":449,"title":"Quasi sit vel ipsam ","detail":"Non deserunt fugiat","nickname":"Quod ducimus cupida","customer_id":8451,"review_entity":"product","review_type":1,"review_status":2,"created_at":"2019-04-23 11:13:04","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"450","_score":1,"_source":{"id":450,"title":"fgh","detail":"cghjj","nickname":"Ce","customer_id":8670,"review_entity":"product","review_type":1,"review_status":2,"created_at":"2019-04-23 23:03:59","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"452","_score":1,"_source":{"id":452,"title":"Review Testing","detail":"Review1","nickname":"Nidha","customer_id":8689,"review_entity":"product","review_type":1,"review_status":2,"created_at":"2019-04-25 12:40:24","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"14","_score":1,"_source":{"id":14,"title":"This bag is really cool","detail":"This bag is really cool. I'm an art major, so I have tons of supplies that I have to lug back and forth every day for class. I didn't think this would be big enough, but surprisingly it can hold just about all my stuff. I really like the way it looks too.","nickname":"Jame","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"19","_score":1,"_source":{"id":19,"title":"Working flawlessly","detail":"I recently replace my 25 year old watch with this one, so it had high expectations to live up to. So far all the features are working flawlessly, I only hope it lasts as long as my old one.","nickname":"Billy","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"22","_score":1,"_source":{"id":22,"title":"It works ok but the ugliness is blinding","detail":"It works ok but the ugliness is blinding I am literally blinded","nickname":"Leon","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"24","_score":1,"_source":{"id":24,"title":"No ticktock","detail":"I got it because I thought it would still make a ticktick noise even though it's digital, but it doesn't!","nickname":"Chuck","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"26","_score":1,"_source":{"id":26,"title":"the only watch I wear","detail":"Hands down, it's the only watch I wear when I'm out on a run. The strap is soft and smooth, and the face even glows in the dark.","nickname":"Noe","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"25","_score":1,"_source":{"id":25,"title":"Not a bad watch for the price","detail":"Not a bad watch for the price. Wish it had actual numbers instead of marks, though.","nickname":"Robert","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"29","_score":1,"_source":{"id":29,"title":"I really like the modern look","detail":"I really like the modern look of this watch, but I could only get one time zone to work. I hope it has a warranty because I'm sending it back!","nickname":"Bobby","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"40","_score":1,"_source":{"id":40,"title":"Excellent quality. I actually love","detail":"Excellent quality. I actually love when it rains because I get a lot of compliments whenever I wear this jacket. ","nickname":"Randell","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"41","_score":1,"_source":{"id":41,"title":"I just live for this track jacket","detail":"I just live for this track jacket. Because it's solid, I can put it on over any t-shirt and look really athletic. I may not exercise all the time, but wearing this jacket makes other people think I do!","nickname":"Wyatt","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"44","_score":1,"_source":{"id":44,"title":"I didn't think it was that warm","detail":"I didn't think it was that warm at all and it needs a hood. I wouldn't wear it in the winter that's for sure. ","nickname":"Neal","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"48","_score":1,"_source":{"id":48,"title":"does everything it's suppose","detail":"This jacket does everything it's supposed to do. Keeps me warm and has lots of room for my stuff. Good buy!","nickname":"Burl","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"52","_score":1,"_source":{"id":52,"title":"Loop thing broke","detail":"I'd give it 4 or 5 stars if it wasn't for the fact that the effing loop thing broke. It wasn't stretchy enough and now im back to carrying my fone and sweating on it ughghg! ","nickname":"Jessie","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"60","_score":1,"_source":{"id":60,"title":"The mesh lining sometimes snags","detail":"The mesh lining sometimes snags when your taking them off but that's pretty common I think. Like them and would recommend.","nickname":"Armando","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"73","_score":1,"_source":{"id":73,"title":"Hate the fabric","detail":"Why is this kind of fabric all the rage? I know it's supposed to be the best thing since sliced bread with the moisture wicking crap but I feel like I sweat MORE than with just regular cotton. I'm over paying an arm and a leg for the \"technology.\" give me a 5 dollar tshirt from the dollar store!","nickname":"Hai","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"79","_score":1,"_source":{"id":79,"title":"Liked the way it fit mostly","detail":"Liked the way it fit mostly. But the collar was weird. I guess it kept me dry?","nickname":"Jonas","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"84","_score":1,"_source":{"id":84,"title":"Great training top. ","detail":"Great training top. I like that it also has UV protection because I'm outdoors all the time. Seems are a little weird tho.","nickname":"Donnell","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"89","_score":1,"_source":{"id":89,"title":"I've lost 50 pounds in 5 months","detail":"I've lost 50 pounds in 5 months and this shirt kept me comfortable since day one. I would recommend it to anyone serious about workout. Sizes run small tho so order a size up. ","nickname":"Darwin","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"92","_score":1,"_source":{"id":92,"title":"Luma got it right with this one.","detail":"Luma got it right with this one. I don't care about looking stylish, I just want a shirt that will still feel good after an hour at the gym, and that's what I got.","nickname":"Alfred","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"99","_score":1,"_source":{"id":99,"title":"Why can't you make this in my size?","detail":"Why can't you make this in my size? Thank you for the color at least. ","nickname":"Harold","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"98","_score":1,"_source":{"id":98,"title":"Yea. This pilled imeddiately","detail":"Yea. This pilled imeddiately after I washed it. Definatly returning.","nickname":"Wendell","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"105","_score":1,"_source":{"id":105,"title":"Great! I wear these almost every day-esp","detail":"Great! I wear these almost every day-especially love that I don't have to worry about the laces.","nickname":"Gerald","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"108","_score":1,"_source":{"id":108,"title":"Pretty average cts. Their comfrtable whe","detail":"Pretty average cts. Their comfrtable when I first start but don't try working out too hard in them. You're feet will definitely start to hurt!","nickname":"Judson","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"110","_score":1,"_source":{"id":110,"title":"Love, love, love - did I say love? It wa","detail":"Love, love, love - did I say love? It was totally worth it to wait for Luma to come out with a trail running shoe. Very comfortable.","nickname":"Jerold","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:44","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"116","_score":1,"_source":{"id":116,"title":"I wouldn't be a runner if it wasn't for ","detail":"I wouldn't be a runner if it wasn't for these shoes. I used to get really bad shin splints, blisters and pulled muscles no matter how much I stretched. Once I bought these it got so much eaiser. It is true that they are not that stylish but if you are serious about running, who cares?","nickname":"Irwin","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"119","_score":1,"_source":{"id":119,"title":"They ran too narrow for me and the mater","detail":"They ran too narrow for me and the material was almost too light - seemed pretty flimsy and I don't think they would last very long.","nickname":"Leslie","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"120","_score":1,"_source":{"id":120,"title":"These are really REALLY LIGHT! Not much ","detail":"These are really REALLY LIGHT! Not much shoe or cushioning. My calves were sore after running in them 5 miles the first time.","nickname":"Jody","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"123","_score":1,"_source":{"id":123,"title":"Unflattering","detail":"Honestly, could this be any more unflattering? The cut is really bad and I can't see anyone looking good in this unless they're really muscular.","nickname":"Dominic","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"126","_score":1,"_source":{"id":126,"title":"Average tank","detail":"It's just an average tank. Nothing really to say about it. I rarely work out so I can't speak to the moisture-wicking part.","nickname":"Edmund","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"129","_score":1,"_source":{"id":129,"title":"I feel awesome when I wear this","detail":"I feel awesome when I wear this to hit the gym!!! The cut makes my triceps look huge. It's so rewarding to look in the mirror after a really tough workout. My girlfriend says I look like a lunkhead but I know she loves it!!","nickname":"Eldon","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"130","_score":1,"_source":{"id":130,"title":"Comfortable","detail":"Not as lightweight as it seems but it was ok. Comfortable.","nickname":"Joey","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"132","_score":1,"_source":{"id":132,"title":"TINY neck hole??","detail":"Why is the neck opening so small??? Didn't fit right.","nickname":"Monroe","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"143","_score":1,"_source":{"id":143,"title":"Want more resistance","detail":"Its great to be able to work out at home and sometimes on my lunch break at work - I wish this provided more resistance, though.","nickname":"Randy","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"144","_score":1,"_source":{"id":144,"title":"Agreed. More resistance","detail":"Agreed. I can do plenty of exercises with it and its awesome for when I can't make it to the gym, but I'd like more resistance, too.","nickname":"Keren","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"145","_score":1,"_source":{"id":145,"title":"Too lazy to go to gym","detail":"I use these when I'm too lazy to go to the gym. Really helps me stay in shape. I have already adjusted several times to increase the tension because I'm getting stronger!","nickname":"Madeleine","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"review","_id":"149","_score":1,"_source":{"id":149,"title":"I BRING THIS TO ALL MY MEETS!","detail":"I BRING THIS TO ALL MY MEETS FOR WARMUP!!! BARELY TAKES UP ANY SPACE IN MY BAG","nickname":"Andy","review_entity":"product","review_type":3,"review_status":1,"created_at":"2017-11-06 12:17:45","store_id":1,"stores":[0,1],"product_id":1,"tsk":1556379376640}} +{"_index":"vue_storefront_catalog_1556379297","_type":"product","_id":"29","_score":1,"_source":{"id":29,"sku":"24-WG082-blue","name":"Sprite Stasis Ball 65 cm","attribute_set_id":12,"price":27,"status":1,"visibility":1,"type_id":"simple","created_at":"2017-11-06 12:16:28","updated_at":"2017-11-06 12:16:28","product_links":[],"tier_prices":[],"custom_attributes":null,"final_price":33.210001,"max_price":33.210001,"max_regular_price":33.210001,"minimal_regular_price":33.210001,"special_price":null,"minimal_price":33.210001,"regular_price":33.210001,"description":"

The Sprite Stasis Ball gives you the toned abs, sides, and back you want by amping up your core workout. With bright colors and a burst-resistant design, it's a must-have for every hard-core exercise addict. Use for abdominal conditioning, balance training, yoga, or even physical therapy.

\n","image":"/l/u/luma-stability-ball.jpg","small_image":"/l/u/luma-stability-ball.jpg","thumbnail":"/l/u/luma-stability-ball.jpg","color":"50","category_ids":[3,5],"options_container":"container2","required_options":"0","has_options":"0","url_key":"sprite-stasis-ball-65-cm-blue","tax_class_id":"2","activity":[8,11],"material":"44","gender":[80,81,82,83,84],"category_gear":"87","size":"92","slug":"sprite-stasis-ball-65-cm-29","links":{},"stock":{"item_id":29,"product_id":29,"stock_id":1,"qty":95,"is_in_stock":true,"is_qty_decimal":false,"show_default_notification_message":false,"use_config_min_qty":true,"min_qty":0,"use_config_min_sale_qty":1,"min_sale_qty":1,"use_config_max_sale_qty":true,"max_sale_qty":10000,"use_config_backorders":true,"backorders":0,"use_config_notify_stock_qty":true,"notify_stock_qty":1,"use_config_qty_increments":true,"qty_increments":0,"use_config_enable_qty_inc":true,"enable_qty_increments":false,"use_config_manage_stock":true,"manage_stock":true,"low_stock_date":null,"is_decimal_divided":false,"stock_status_changed_auto":0},"media_gallery":[{"vid":null,"image":"/l/u/luma-stability-ball.jpg","pos":1,"typ":"image","lab":"Image"}],"category":[{"path":"gear/gear-3","category_id":3,"name":"Gear","slug":"gear-3"},{"path":"gear/fitness-equipment/fitness-equipment-5","category_id":5,"name":"Fitness Equipment","slug":"fitness-equipment-5"}],"url_path":"gear/gear-3/sprite-stasis-ball-65-cm-29.html","tsk":1556379398182}} +{"_index":"vue_storefront_catalog_1556379297","_type":"product","_id":"19","_score":1,"_source":{"id":19,"sku":"24-UG05","name":"Go-Get'r Pushup Grips","attribute_set_id":11,"price":19,"status":1,"visibility":4,"type_id":"simple","created_at":"2017-11-06 12:16:27","updated_at":"2017-11-06 12:16:27","product_links":[],"tier_prices":[],"custom_attributes":null,"final_price":23.370001,"max_price":23.370001,"max_regular_price":23.370001,"minimal_regular_price":23.370001,"special_price":null,"minimal_price":23.370001,"regular_price":23.370001,"description":"

The Go-Get'r Pushup Grips safely provide the extra range of motion you need for a deep-dip routine targeting core, shoulder, chest and arm strength. Do fewer pushups using more energy, getting better results faster than the standard floor-level technique yield.

\n","image":"/u/g/ug05-gr-0.jpg","small_image":"/u/g/ug05-gr-0.jpg","thumbnail":"/u/g/ug05-gr-0.jpg","category_ids":[3,7,5,8],"options_container":"container2","required_options":"0","has_options":"0","url_key":"go-get-r-pushup-grips","tax_class_id":"2","activity":[16,11],"material":[44,45],"gender":[80,81,84],"category_gear":"87","erin_recommends":"1","new":"1","slug":"go-getr-pushup-grips-19","links":{},"stock":{"item_id":19,"product_id":19,"stock_id":1,"qty":80,"is_in_stock":true,"is_qty_decimal":false,"show_default_notification_message":false,"use_config_min_qty":true,"min_qty":0,"use_config_min_sale_qty":1,"min_sale_qty":1,"use_config_max_sale_qty":true,"max_sale_qty":10000,"use_config_backorders":true,"backorders":0,"use_config_notify_stock_qty":true,"notify_stock_qty":1,"use_config_qty_increments":true,"qty_increments":0,"use_config_enable_qty_inc":true,"enable_qty_increments":false,"use_config_manage_stock":true,"manage_stock":true,"low_stock_date":null,"is_decimal_divided":false,"stock_status_changed_auto":0},"media_gallery":[{"vid":null,"image":"/u/g/ug05-gr-0.jpg","pos":1,"typ":"image","lab":"Image"}],"category":[{"path":"gear/gear-3","category_id":3,"name":"Gear","slug":"gear-3"},{"path":"collections/collections-7","category_id":7,"name":"Collections","slug":"collections-7"},{"path":"gear/fitness-equipment/fitness-equipment-5","category_id":5,"name":"Fitness Equipment","slug":"fitness-equipment-5"},{"path":"collections/yoga-new/new-luma-yoga-collection-8","category_id":8,"name":"New Luma Yoga Collection","slug":"new-luma-yoga-collection-8"}],"url_path":"gear/gear-3/go-getr-pushup-grips-19.html","tsk":1556379398182}} +{"_index":"vue_storefront_catalog_1556379297","_type":"product","_id":"14","_score":1,"_source":{"id":14,"sku":"24-WB04","name":"Push It Messenger Bag - tier price","attribute_set_id":15,"price":45,"status":1,"visibility":4,"type_id":"simple","created_at":"2017-11-06 12:16:26","updated_at":"2018-08-22 09:27:59","product_links":[],"tier_prices":[{"qty":1,"extension_attributes":{"website_id":0},"customer_group_id":1,"value":35}],"custom_attributes":null,"final_price":55.350001,"max_price":55.350001,"max_regular_price":55.350001,"minimal_regular_price":55.350001,"special_price":null,"minimal_price":55.350001,"regular_price":55.350001,"description":"

The name says so, but the Push It Messenger Bag is much more than a busy commuter's tote. It's a closet away from home when you're pedaling from class or work to gym and back or home again. It's the perfect size and shape for laptop, folded clothes, even extra shoes.

\r\n","image":"/w/b/wb04-blue-0.jpg","small_image":"/w/b/wb04-blue-0.jpg","thumbnail":"/w/b/wb04-blue-0.jpg","color":"49","category_ids":[3,7,4],"options_container":"container2","required_options":"0","has_options":"0","url_key":"push-it-messenger-bag","msrp_display_actual_price_type":"0","gift_message_available":"0","tax_class_id":"2","activity":[20,23,8],"style_bags":[27,28],"material":[37,38],"strap_bags":[61,62,63,65,66,67],"features_bags":[74,75,78,79],"eco_collection":"0","performance_fabric":"1","erin_recommends":"0","new":"0","sale":"0","slug":"push-it-messenger-bag-tier-price-14","links":{},"stock":{"item_id":14,"product_id":14,"stock_id":1,"qty":40,"is_in_stock":true,"is_qty_decimal":false,"show_default_notification_message":false,"use_config_min_qty":true,"min_qty":0,"use_config_min_sale_qty":1,"min_sale_qty":1,"use_config_max_sale_qty":true,"max_sale_qty":10000,"use_config_backorders":true,"backorders":0,"use_config_notify_stock_qty":true,"notify_stock_qty":1,"use_config_qty_increments":true,"qty_increments":0,"use_config_enable_qty_inc":true,"enable_qty_increments":false,"use_config_manage_stock":true,"manage_stock":true,"low_stock_date":null,"is_decimal_divided":false,"stock_status_changed_auto":0},"media_gallery":[{"vid":null,"image":"/w/b/wb04-blue-0.jpg","pos":1,"typ":"image","lab":"Image"}],"category":[{"path":"gear/gear-3","category_id":3,"name":"Gear","slug":"gear-3"},{"path":"collections/collections-7","category_id":7,"name":"Collections","slug":"collections-7"},{"path":"gear/bags/bags-4","category_id":4,"name":"Bags","slug":"bags-4"}],"url_path":"gear/gear-3/push-it-messenger-bag-tier-price-14.html","tsk":1556379398182}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"73","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":true,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"1","is_visible_in_advanced_search":"1","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"1","is_visible":true,"scope":"store","attribute_id":73,"attribute_code":"name","frontend_input":"text","entity_type_id":"4","is_required":true,"options":[],"is_user_defined":false,"default_frontend_label":"Product Name","frontend_labels":null,"backend_type":"varchar","is_unique":"0","frontend_class":"validate-length maximum-length-255","validation_rules":[],"id":73,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"79","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":true,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":["simple","virtual","bundle","downloadable","configurable"],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"1","is_visible":true,"scope":"website","attribute_id":79,"attribute_code":"special_from_date","frontend_input":"date","entity_type_id":"4","is_required":false,"options":[],"is_user_defined":false,"default_frontend_label":"Special Price From Date","frontend_labels":null,"backend_type":"datetime","backend_model":"Magento\\Catalog\\Model\\Attribute\\Backend\\Startdate","is_unique":"0","validation_rules":[],"id":79,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"84","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":true,"is_visible_in_grid":false,"is_filterable_in_grid":true,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":true,"scope":"store","attribute_id":84,"attribute_code":"meta_title","frontend_input":"text","entity_type_id":"4","is_required":false,"options":[],"is_user_defined":false,"default_frontend_label":"Meta Title","frontend_labels":null,"backend_type":"varchar","is_unique":"0","validation_rules":[],"id":84,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"89","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"1","is_visible":true,"scope":"store","attribute_id":89,"attribute_code":"thumbnail","frontend_input":"media_image","entity_type_id":"4","is_required":false,"options":[],"is_user_defined":false,"default_frontend_label":"Thumbnail","frontend_labels":null,"backend_type":"varchar","is_unique":"0","validation_rules":[],"id":89,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"92","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":["simple","virtual","bundle","downloadable"],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":true,"scope":"website","attribute_id":92,"attribute_code":"tier_price","frontend_input":"text","entity_type_id":"4","is_required":false,"options":[],"is_user_defined":false,"default_frontend_label":"Tier Price","frontend_labels":null,"backend_type":"decimal","backend_model":"Magento\\Catalog\\Model\\Product\\Attribute\\Backend\\Tierprice","is_unique":"0","validation_rules":[],"id":92,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"98","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":["simple","virtual","bundle","downloadable","configurable"],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":false,"scope":"global","attribute_id":98,"attribute_code":"minimal_price","frontend_input":"price","entity_type_id":"4","is_required":false,"options":[],"is_user_defined":false,"default_frontend_label":"Minimal Price","frontend_labels":null,"backend_type":"decimal","backend_model":"Magento\\Catalog\\Model\\Product\\Attribute\\Backend\\Price","is_unique":"0","validation_rules":[],"id":98,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"99","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":true,"scope":"store","attribute_id":99,"attribute_code":"visibility","frontend_input":"select","entity_type_id":"4","is_required":false,"options":[{"label":"Not Visible Individually","value":"1"},{"label":"Catalog","value":"2"},{"label":"Search","value":"3"},{"label":"Catalog, Search","value":"4"}],"is_user_defined":false,"default_frontend_label":"Visibility","frontend_labels":null,"backend_type":"int","source_model":"Magento\\Catalog\\Model\\Product\\Visibility","default_value":"4","is_unique":"0","validation_rules":[],"id":99,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"105","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":true,"scope":"global","attribute_id":105,"attribute_code":"category_ids","frontend_input":"text","entity_type_id":"4","is_required":false,"options":[],"is_user_defined":false,"default_frontend_label":"Categories","frontend_labels":null,"backend_type":"static","backend_model":"Magento\\Catalog\\Model\\Product\\Attribute\\Backend\\Category","is_unique":"0","validation_rules":[],"id":105,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"108","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":false,"scope":"global","attribute_id":108,"attribute_code":"has_options","frontend_input":"text","entity_type_id":"4","is_required":false,"options":[],"is_user_defined":false,"frontend_labels":null,"backend_type":"static","is_unique":"0","validation_rules":[],"id":108,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"110","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"1","is_visible":false,"scope":"store","attribute_id":110,"attribute_code":"small_image_label","frontend_input":"text","entity_type_id":"4","is_required":false,"options":[],"is_user_defined":false,"default_frontend_label":"Small Image Label","frontend_labels":null,"backend_type":"varchar","is_unique":"0","validation_rules":[],"id":110,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"116","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":true,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":true,"scope":"store","attribute_id":116,"attribute_code":"custom_layout","frontend_input":"select","entity_type_id":"4","is_required":false,"options":[{"label":"No layout updates","value":""},{"label":"Empty","value":"empty"},{"label":"1 column","value":"1column"},{"label":"2 columns with left bar","value":"2columns-left"},{"label":"2 columns with right bar","value":"2columns-right"},{"label":"3 columns","value":"3columns"}],"is_user_defined":false,"default_frontend_label":"New Layout","frontend_labels":null,"backend_type":"varchar","source_model":"Magento\\Catalog\\Model\\Product\\Attribute\\Source\\Layout","is_unique":"0","validation_rules":[],"id":116,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"119","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":true,"is_visible_in_grid":false,"is_filterable_in_grid":true,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"1","is_visible":true,"scope":"store","attribute_id":119,"attribute_code":"url_key","frontend_input":"text","entity_type_id":"4","is_required":false,"options":[],"is_user_defined":false,"default_frontend_label":"URL Key","frontend_labels":null,"backend_type":"varchar","is_unique":"0","validation_rules":[],"id":119,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"123","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":["bundle"],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"1","is_visible":true,"scope":"global","attribute_id":123,"attribute_code":"price_type","frontend_input":"boolean","entity_type_id":"4","is_required":true,"options":[],"is_user_defined":false,"default_frontend_label":"Dynamic Price","frontend_labels":null,"backend_type":"int","default_value":"0","is_unique":"0","validation_rules":[],"id":123,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"126","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":["bundle"],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"1","is_visible":true,"scope":"global","attribute_id":126,"attribute_code":"price_view","frontend_input":"select","entity_type_id":"4","is_required":true,"options":[{"label":"Price Range","value":"0"},{"label":"As Low as","value":"1"}],"is_user_defined":false,"default_frontend_label":"Price View","frontend_labels":null,"backend_type":"int","source_model":"Magento\\Bundle\\Model\\Product\\Attribute\\Source\\Price\\View","is_unique":"0","validation_rules":[],"id":126,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"129","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":["downloadable"],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":false,"scope":"store","attribute_id":129,"attribute_code":"samples_title","frontend_input":null,"entity_type_id":"4","is_required":true,"options":[],"is_user_defined":false,"default_frontend_label":"Samples title","frontend_labels":null,"backend_type":"varchar","is_unique":"0","validation_rules":[],"id":129,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"130","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":["downloadable"],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":false,"scope":"store","attribute_id":130,"attribute_code":"links_title","frontend_input":null,"entity_type_id":"4","is_required":true,"options":[],"is_user_defined":false,"default_frontend_label":"Links title","frontend_labels":null,"backend_type":"varchar","is_unique":"0","validation_rules":[],"id":130,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"132","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":true,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":true,"scope":"global","attribute_id":132,"attribute_code":"gift_message_available","frontend_input":"select","entity_type_id":"4","is_required":false,"options":[{"label":"Yes","value":"1"},{"label":"No","value":"0"},{"label":"Use config","value":"2"}],"is_user_defined":false,"default_frontend_label":"Allow Gift Message","frontend_labels":null,"backend_type":"varchar","backend_model":"Magento\\Catalog\\Model\\Product\\Attribute\\Backend\\Boolean","source_model":"Magento\\Catalog\\Model\\Product\\Attribute\\Source\\Boolean","is_unique":"0","validation_rules":[],"id":132,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"143","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":true,"used_for_sort_by":false,"is_filterable":true,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"1","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":true,"scope":"global","attribute_id":143,"attribute_code":"eco_collection","frontend_input":"boolean","entity_type_id":"4","is_required":false,"options":[{"label":"Yes","value":"1"},{"label":"No","value":"0"}],"is_user_defined":true,"default_frontend_label":"Eco Collection","frontend_labels":null,"backend_type":"int","source_model":"Magento\\Eav\\Model\\Entity\\Attribute\\Source\\Boolean","default_value":"","is_unique":"0","validation_rules":[],"id":143,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"145","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":true,"used_for_sort_by":false,"is_filterable":true,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"1","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":true,"scope":"global","attribute_id":145,"attribute_code":"erin_recommends","frontend_input":"boolean","entity_type_id":"4","is_required":false,"options":[{"label":"Yes","value":"1"},{"label":"No","value":"0"}],"is_user_defined":true,"default_frontend_label":"Erin Recommends","frontend_labels":null,"backend_type":"int","source_model":"Magento\\Eav\\Model\\Entity\\Attribute\\Source\\Boolean","default_value":"","is_unique":"0","validation_rules":[],"id":145,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"144","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":true,"used_for_sort_by":false,"is_filterable":true,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"1","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":true,"scope":"global","attribute_id":144,"attribute_code":"performance_fabric","frontend_input":"boolean","entity_type_id":"4","is_required":false,"options":[{"label":"Yes","value":"1"},{"label":"No","value":"0"}],"is_user_defined":true,"default_frontend_label":"Performance Fabric","frontend_labels":null,"backend_type":"int","source_model":"Magento\\Eav\\Model\\Entity\\Attribute\\Source\\Boolean","default_value":"","is_unique":"0","validation_rules":[],"id":144,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"149","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":true,"used_for_sort_by":false,"is_filterable":true,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"1","is_visible_on_front":"1","used_in_product_listing":"0","is_visible":true,"scope":"global","attribute_id":149,"attribute_code":"style_bottom","frontend_input":"multiselect","entity_type_id":"4","is_required":false,"options":[{"label":" ","value":""},{"label":"Base Layer","value":"105"},{"label":"Basic","value":"106"},{"label":"Capri","value":"107"},{"label":"Compression","value":"108"},{"label":"Leggings","value":"109"},{"label":"Parachute","value":"110"},{"label":"Skort","value":"111"},{"label":"Snug","value":"112"},{"label":"Sweatpants","value":"113"},{"label":"Tights","value":"114"},{"label":"Track Pants","value":"115"},{"label":"Workout Pants","value":"116"}],"is_user_defined":true,"default_frontend_label":"Style Bottom","frontend_labels":null,"backend_type":"varchar","backend_model":"Magento\\Eav\\Model\\Entity\\Attribute\\Backend\\ArrayBackend","source_model":"Magento\\Eav\\Model\\Entity\\Attribute\\Source\\Table","default_value":"","is_unique":"0","validation_rules":[],"id":149,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"category","_id":"40","_score":1,"_source":{"id":40,"parent_id":7,"name":"Eco Collection New","is_active":true,"position":6,"level":3,"product_count":0,"children_data":[],"children":"","created_at":"2017-11-06 12:17:48","updated_at":"2017-11-06 12:17:48","path":"1/2/7/40","available_sort_by":[],"include_in_menu":false,"display_mode":"PAGE","is_anchor":"0","page_layout":"1column","children_count":"0","url_key":"eco-collection-new-40","url_path":"collections/eco-new/eco-collection-new-40","slug":"eco-collection-new-40","tsk":1556379380757}} +{"_index":"vue_storefront_catalog_1556379297","_type":"category","_id":"22","_score":1,"_source":{"id":22,"parent_id":20,"name":"Bottoms","is_active":true,"position":2,"level":3,"product_count":0,"children_data":[{"is_anchor":"1","is_active":true,"level":4,"product_count":91,"children_count":"0","created_at":"2017-11-06 12:16:41","url_key":"pants-27","path":"1/2/20/22/27","updated_at":"2017-11-06 12:16:41","children":"","parent_id":22,"available_sort_by":[],"name":"Pants","id":27,"position":1,"include_in_menu":true,"slug":"pants-27","children_data":[],"url_path":"women/bottoms-women/pants-women/pants-27"},{"is_anchor":"1","is_active":true,"level":4,"product_count":137,"children_count":"0","created_at":"2017-11-06 12:16:41","url_key":"shorts-28","path":"1/2/20/22/28","updated_at":"2017-11-06 12:16:41","children":"","parent_id":22,"available_sort_by":[],"name":"Shorts","id":28,"position":2,"include_in_menu":true,"slug":"shorts-28","children_data":[],"url_path":"women/bottoms-women/shorts-women/shorts-28"}],"children":"27,28","created_at":"2017-11-06 12:16:41","updated_at":"2017-11-06 12:16:41","path":"1/2/20/22","available_sort_by":[],"include_in_menu":true,"is_anchor":"1","children_count":"2","url_key":"bottoms-22","url_path":"women/bottoms-women/bottoms-22","slug":"bottoms-22","tsk":1556379380757}} +{"_index":"vue_storefront_catalog_1556379297","_type":"category","_id":"14","_score":1,"_source":{"id":14,"parent_id":12,"name":"Jackets","is_active":true,"position":1,"level":4,"product_count":176,"children_data":[],"children":"","created_at":"2017-11-06 12:16:40","updated_at":"2019-04-17 11:10:23","path":"1/2/11/12/14","available_sort_by":[],"include_in_menu":true,"description":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum dui sapien, bibendum ac luctus sed, lobortis id lacus. Nulla nisi augue, accumsan id sapien maximus, hendrerit vehicula elit.

","display_mode":"PRODUCTS","is_anchor":"1","children_count":"0","custom_use_parent_settings":"0","custom_apply_to_products":"0","url_key":"jackets-14","url_path":"men/tops-men/jackets-men/jackets-14","slug":"jackets-14","tsk":1556379380757}} +{"_index":"vue_storefront_catalog_1556379297","_type":"category","_id":"19","_score":1,"_source":{"id":19,"parent_id":13,"name":"Shorts","is_active":true,"position":2,"level":4,"product_count":148,"children_data":[],"children":"","created_at":"2017-11-06 12:16:40","updated_at":"2017-11-06 12:16:40","path":"1/2/11/13/19","available_sort_by":[],"include_in_menu":true,"is_anchor":"1","children_count":"0","url_key":"shorts-19","url_path":"men/bottoms-men/shorts-men/shorts-19","slug":"shorts-19","tsk":1556379380757}} +{"_index":"vue_storefront_catalog_1556379297","_type":"category","_id":"29","_score":1,"_source":{"id":29,"parent_id":2,"name":"Promotions","is_active":false,"position":6,"level":2,"product_count":0,"children_data":[{"is_anchor":"1","is_active":true,"level":3,"product_count":224,"children_count":"0","created_at":"2017-11-06 12:16:41","url_key":"women-sale-30","path":"1/2/29/30","updated_at":"2017-11-06 12:16:41","children":"","parent_id":29,"available_sort_by":[],"name":"Women Sale","id":30,"position":1,"include_in_menu":false,"slug":"women-sale-30","children_data":[],"url_path":"promotions/women-sale/women-sale-30"},{"is_anchor":"1","is_active":true,"level":3,"product_count":39,"children_count":"0","created_at":"2017-11-06 12:16:41","url_key":"men-sale-31","path":"1/2/29/31","updated_at":"2017-11-06 12:16:41","children":"","parent_id":29,"available_sort_by":[],"name":"Men Sale","id":31,"position":2,"include_in_menu":false,"slug":"men-sale-31","children_data":[],"url_path":"promotions/men-sale/men-sale-31"},{"is_anchor":"1","is_active":true,"level":3,"product_count":247,"children_count":"0","created_at":"2017-11-06 12:16:42","url_key":"pants-32","path":"1/2/29/32","updated_at":"2017-11-06 12:16:42","children":"","parent_id":29,"available_sort_by":[],"name":"Pants","id":32,"position":3,"include_in_menu":false,"slug":"pants-32","children_data":[],"url_path":"promotions/pants-all/pants-32"},{"is_anchor":"1","is_active":true,"level":3,"product_count":192,"children_count":"0","created_at":"2017-11-06 12:16:42","url_key":"tees-33","path":"1/2/29/33","updated_at":"2017-11-06 12:16:42","children":"","parent_id":29,"available_sort_by":[],"name":"Tees","id":33,"position":4,"include_in_menu":false,"slug":"tees-33","children_data":[],"url_path":"promotions/tees-all/tees-33"}],"children":"30,31,32,33","created_at":"2017-11-06 12:16:41","updated_at":"2017-11-06 12:16:42","path":"1/2/29","available_sort_by":[],"include_in_menu":false,"display_mode":"PAGE","is_anchor":"0","children_count":"4","url_key":"promotions-29","url_path":"promotions/promotions-29","slug":"promotions-29","tsk":1556379380757}} +{"_index":"vue_storefront_catalog_1556379297","_type":"attribute","_id":"120","_score":1,"_source":{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":false,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":false,"is_visible_in_grid":false,"is_filterable_in_grid":false,"position":0,"apply_to":[],"is_searchable":"0","is_visible_in_advanced_search":"0","is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0","used_in_product_listing":"0","is_visible":false,"scope":"store","attribute_id":120,"attribute_code":"url_path","frontend_input":"text","entity_type_id":"4","is_required":false,"options":[],"is_user_defined":false,"frontend_labels":null,"backend_type":"varchar","is_unique":"0","validation_rules":[],"id":120,"tsk":1556379391784}} +{"_index":"vue_storefront_catalog_1556379297","_type":"cms_block","_id":"14","_score":1,"_source":{"store_id":[0],"id":14,"identifier":"home-page-block","title":"Home Page Block","content":"
\n \n \"\"\n \n New Luma Yoga Collection\n Get fit and look fab in new seasonal styles\n Shop New Yoga\n \n \n
\n \n \"\"\n \n 20% OFF\n Luma pants when you shop today*\n Shop Pants\n \n \n \n \"\"\n \n Even more ways to mix and match\n Buy 3 Luma tees get a 4th free\n Shop Tees\n \n \n \n \"\"\n \n Take it from Erin\n Luma founder Erin Renny shares her favorites!\n Shop Erin Recommends\n \n \n \n \"\"\n \n Science meets performance\n Wicking to raingear, Luma covers you\n Shop Performance\n \n \n \n \"\"\n \n Twice around, twice as nice\n Find conscientious, comfy clothing in our eco-friendly collection\n Shop Eco-Friendly\n \n \n
\n
\n
\n

Hot Sellers

\n

Here is what`s trending on Luma right now

\n
\n","creation_time":"2017-11-06 12:17:49","update_time":"2017-11-06 12:17:49","active":true,"type":"cms_block","tsk":1556379356906}} +{"_index":"vue_storefront_catalog_1556379297","_type":"category","_id":"25","_score":1,"_source":{"id":25,"parent_id":21,"name":"Tees","is_active":true,"position":3,"level":4,"product_count":192,"children_data":[],"children":"","created_at":"2017-11-06 12:16:41","updated_at":"2017-11-06 12:16:41","path":"1/2/20/21/25","available_sort_by":[],"include_in_menu":true,"is_anchor":"1","children_count":"0","url_key":"tees-25","url_path":"women/tops-women/tees-women/tees-25","slug":"tees-25","tsk":1556379380757}} +{"_index":"vue_storefront_catalog_1556379297","_type":"category","_id":"24","_score":1,"_source":{"id":24,"parent_id":21,"name":"Hoodies & Sweatshirts","is_active":true,"position":2,"level":4,"product_count":182,"children_data":[],"children":"","created_at":"2017-11-06 12:16:41","updated_at":"2017-11-06 12:16:41","path":"1/2/20/21/24","available_sort_by":[],"include_in_menu":true,"is_anchor":"1","children_count":"0","url_key":"hoodies-and-sweatshirts-24","url_path":"women/tops-women/hoodies-and-sweatshirts-women/hoodies-and-sweatshirts-24","slug":"hoodies-and-sweatshirts-24","tsk":1556379380757}} +{"_index":"vue_storefront_catalog_1556379297","_type":"category","_id":"26","_score":1,"_source":{"id":26,"parent_id":21,"name":"Bras & Tanks","is_active":true,"position":4,"level":4,"product_count":224,"children_data":[],"children":"","created_at":"2017-11-06 12:16:41","updated_at":"2017-11-06 12:16:41","path":"1/2/20/21/26","available_sort_by":[],"include_in_menu":true,"is_anchor":"1","children_count":"0","url_key":"bras-and-tanks-26","url_path":"women/tops-women/tanks-women/bras-and-tanks-26","slug":"bras-and-tanks-26","tsk":1556379380757}} +{"_index":"vue_storefront_catalog_1556379297","_type":"product","_id":"22","_score":1,"_source":{"id":22,"sku":"24-WG088","name":"Sprite Foam Roller","attribute_set_id":11,"price":19,"status":1,"visibility":4,"type_id":"simple","created_at":"2017-11-06 12:16:28","updated_at":"2018-07-23 08:05:45","product_links":[],"tier_prices":[],"custom_attributes":null,"description":"

It hurts so good to use the Sprite Foam Roller on achy, tired muscles for myofascial massage therapy. Or you can add this fundamental piece to your Pilates and yoga accouterment, or apply towards core stability, strengthening and balance exercise.

\r\n","image":"/l/u/luma-foam-roller.jpg","small_image":"/l/u/luma-foam-roller.jpg","thumbnail":"/l/u/luma-foam-roller.jpg","color":"50","category_ids":[3,5],"options_container":"container2","required_options":"0","has_options":"0","url_key":"sprite-foam-roller","msrp_display_actual_price_type":"0","gift_message_available":"0","tax_class_id":"2","activity":[8,11],"material":"42","gender":[80,81,84],"category_gear":"87","eco_collection":"0","performance_fabric":"0","erin_recommends":"0","new":"0","sale":"0","slug":"sprite-foam-roller-22","links":{},"stock":{"item_id":22,"product_id":22,"stock_id":1,"qty":0,"is_in_stock":false,"is_qty_decimal":false,"show_default_notification_message":false,"use_config_min_qty":true,"min_qty":0,"use_config_min_sale_qty":1,"min_sale_qty":1,"use_config_max_sale_qty":true,"max_sale_qty":10000,"use_config_backorders":true,"backorders":0,"use_config_notify_stock_qty":true,"notify_stock_qty":1,"use_config_qty_increments":true,"qty_increments":0,"use_config_enable_qty_inc":true,"enable_qty_increments":false,"use_config_manage_stock":true,"manage_stock":true,"low_stock_date":"2019-04-16 10:43:08","is_decimal_divided":false,"stock_status_changed_auto":1},"media_gallery":[{"vid":null,"image":"/l/u/luma-foam-roller.jpg","pos":1,"typ":"image","lab":"Image"}],"category":[{"path":"gear/gear-3","category_id":3,"name":"Gear","slug":"gear-3"},{"path":"gear/fitness-equipment/fitness-equipment-5","category_id":5,"name":"Fitness Equipment","slug":"fitness-equipment-5"}],"url_path":"gear/gear-3/sprite-foam-roller-22.html","tsk":1556379398182}} +{"_index":"vue_storefront_catalog_1556379297","_type":"product","_id":"40","_score":1,"_source":{"id":40,"sku":"24-MG02","name":"Dash Digital Watch","attribute_set_id":11,"price":92,"status":1,"visibility":4,"type_id":"simple","created_at":"2017-11-06 12:16:30","updated_at":"2017-11-06 12:16:30","product_links":[],"tier_prices":[],"custom_attributes":null,"final_price":113.160001,"max_price":113.160001,"max_regular_price":113.160001,"minimal_regular_price":113.160001,"special_price":null,"minimal_price":113.160001,"regular_price":113.160001,"description":"

The Dash Digital Watch will challenge you to push harder and longer. Log workouts by date, average, and segment times, and recharge by setting hydration and nutrition alarms. This watch is styled with a sleek, square face and durable rubber strap for a long life.

\n