@fabrix/spool-cart
Version:
Spool - eCommerce Spool for Fabrix
1,154 lines (1,153 loc) • 39.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const common_1 = require("@fabrix/fabrix/dist/common");
const spool_sequelize_1 = require("@fabrix/spool-sequelize");
const errors_1 = require("@fabrix/spool-sequelize/dist/errors");
const lodash_1 = require("lodash");
const queryDefaults_1 = require("../utils/queryDefaults");
const enums_1 = require("../../enums");
const enums_2 = require("../../enums");
const enums_3 = require("../../enums");
class ProductResolver extends spool_sequelize_1.SequelizeResolver {
findByIdDefault(criteria, options = {}) {
options = this.app.services.SequelizeService.mergeOptionDefaults(queryDefaults_1.Product.default(this.app), options);
let resProduct;
return this.findById(criteria, options)
.then(product => {
resProduct = product;
if (resProduct && options.req && options.req.customer) {
return resProduct.getCustomerHistory(options.req.customer, { transaction: options.transaction || null });
}
else {
return;
}
})
.then(() => {
if (resProduct) {
return resProduct.calculate({
req: options.req || null,
transaction: options.transaction || null
});
}
else {
return resProduct;
}
});
}
findByHandleDefault(handle, options = {}) {
options = this.app.services.SequelizeService.mergeOptionDefaults(queryDefaults_1.Product.default(this.app), options, {
where: {
handle: handle
}
});
let resProduct;
return this.findOne(options)
.then(product => {
resProduct = product;
if (resProduct && options.req && options.req.customer) {
return resProduct.getCustomerHistory(options.req.customer, { transaction: options.transaction || null });
}
else {
return;
}
})
.then(() => {
if (resProduct) {
return resProduct.calculate({
req: options.req || null,
transaction: options.transaction || null
});
}
else {
return resProduct;
}
});
}
findOneDefault(options = {}) {
options = this.app.services.SequelizeService.mergeOptionDefaults(queryDefaults_1.Product.default(this.app), options);
let resProduct;
return this.findOne(options)
.then(product => {
if (!product) {
}
resProduct = product;
if (resProduct && options.req && options.req.customer) {
return resProduct.getCustomerHistory(options.req.customer, { transaction: options.transaction || null });
}
else {
return;
}
})
.then(() => {
if (resProduct) {
return resProduct.calculate({
req: options.req || null,
transaction: options.transaction || null
});
}
else {
return resProduct;
}
});
}
findAllDefault(options = {}) {
options = this.app.services.SequelizeService.mergeOptionDefaults(queryDefaults_1.Product.findAllDefault(this.app), options);
return this.findAll(options);
}
findAndCountDefault(options) {
options = this.app.services.SequelizeService.mergeOptionDefaults(queryDefaults_1.Product.findAllDefault(this.app), options);
return this.findAndCountAll(options);
}
resolveByInstance(product, options = {}) {
return Promise.resolve(product);
}
resolveById(product, options = {}) {
return this.findById(product.id, options)
.then(resUser => {
if (!resUser && options.reject !== false) {
throw new errors_1.ModelError('E_NOT_FOUND', `product ${product.id} not found`);
}
return resUser;
});
}
resolveByToken(product, options = {}) {
return this.findOne(this.app.services.SequelizeService.mergeOptionDefaults(options, {
where: {
token: product.token
}
}))
.then(resUser => {
if (!resUser && options.reject !== false) {
throw new errors_1.ModelError('E_NOT_FOUND', `product token ${product.token} not found`);
}
return resUser;
});
}
resolveByhandle(product, options = {}) {
return this.findOne(this.app.services.SequelizeService.mergeOptionDefaults(options, {
where: {
handle: product.handle
}
}))
.then(resUser => {
if (!resUser && options.reject !== false) {
throw new errors_1.ModelError('E_NOT_FOUND', `product handle ${product.handle} not found`);
}
return resUser;
});
}
resolveByNumber(product, options = {}) {
return this.findById(product, options)
.then(resUser => {
if (!resUser && options.reject !== false) {
throw new errors_1.ModelError('E_NOT_FOUND', `product ${product.token} not found`);
}
return resUser;
});
}
resolveByString(product, options = {}) {
return this.findOne(this.app.services.SequelizeService.mergeOptionDefaults(options, {
where: {
handle: product
}
}))
.then(resUser => {
if (!resUser && options.reject !== false) {
throw new errors_1.ModelError('E_NOT_FOUND', `product ${product} not found`);
}
return resUser;
});
}
resolve(product, options = {}) {
const resolvers = {
'instance': product instanceof this.instance,
'id': !!(product && lodash_1.isObject(product) && product.id),
'handle': !!(product && lodash_1.isObject(product) && product.token),
'number': !!(product && lodash_1.isNumber(product)),
'string': !!(product && lodash_1.isString(product))
};
const type = Object.keys(resolvers).find((key) => resolvers[key]);
switch (type) {
case 'instance': {
return this.resolveByInstance(product, options);
}
case 'id': {
return this.resolveById(product, options);
}
case 'handle': {
return this.resolveByToken(product, options);
}
case 'number': {
return this.resolveByNumber(product, options);
}
case 'string': {
return this.resolveByString(product, options);
}
default: {
const err = new Error(`Unable to resolve product ${product}`);
return Promise.reject(err);
}
}
}
}
exports.ProductResolver = ProductResolver;
class Product extends common_1.FabrixModel {
static get resolver() {
return ProductResolver;
}
static config(app, Sequelize) {
return {
options: {
enums: {
UNITS: enums_1.UNITS,
PRODUCT_DEFAULTS: enums_2.PRODUCT_DEFAULTS,
},
underscored: true,
scopes: {
live: {
where: {
live_mode: true
}
},
published: {
where: {
published: true
}
}
},
hooks: {
beforeValidate: [
(product, options) => {
if (!product.handle && product.title) {
product.handle = product.title;
}
if (!product.calculated_price && product.price) {
product.calculated_price = product.price;
}
if (!product.compare_at_price && product.price) {
product.compare_at_price = product.price;
}
}
],
beforeCreate: [
(product, options) => {
return app.services.ProductService.beforeCreate(product, options)
.catch(err => {
return Promise.reject(err);
});
}
],
beforeUpdate: [
(product, options) => {
return app.services.ProductService.beforeUpdate(product, options)
.catch(err => {
return Promise.reject(err);
});
}
]
}
}
};
}
static schema(app, Sequelize) {
return {
host: {
type: Sequelize.STRING,
defaultValue: enums_2.PRODUCT_DEFAULTS.HOST
},
handle: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
set: function (val) {
this.setDataValue('handle', app.services.ProxyCartService.handle(val));
}
},
title: {
type: Sequelize.STRING,
set: function (val) {
this.setDataValue('title', app.services.ProxyCartService.title(val));
}
},
body: {
type: Sequelize.TEXT
},
html: {
type: Sequelize.TEXT
},
seo_title: {
type: Sequelize.STRING,
set: function (val) {
this.setDataValue('seo_title', app.services.ProxyCartService.title(val));
}
},
seo_description: {
type: Sequelize.TEXT,
set: function (val) {
this.setDataValue('seo_description', app.services.ProxyCartService.description(val));
}
},
type: {
type: Sequelize.STRING,
allowNull: false,
set: function (val) {
this.setDataValue('type', app.services.ProxyCartService.title(val));
}
},
tax_code: {
type: Sequelize.STRING,
defaultValue: enums_2.PRODUCT_DEFAULTS.TAX_CODE
},
compare_at_price: {
type: Sequelize.INTEGER,
defaultValue: enums_2.PRODUCT_DEFAULTS.PRICE
},
price: {
type: Sequelize.INTEGER,
defaultValue: enums_2.PRODUCT_DEFAULTS.PRICE
},
calculated_price: {
type: Sequelize.VIRTUAL(Sequelize.INTEGER),
defaultValue: enums_2.PRODUCT_DEFAULTS.CALCULATED_PRICE
},
currency: {
type: Sequelize.STRING,
defaultValue: enums_2.PRODUCT_DEFAULTS.CURRENCY
},
total_orders: {
type: Sequelize.INTEGER,
defaultValue: 0
},
discounted_lines: {
type: Sequelize.JSONB,
defaultValue: enums_2.PRODUCT_DEFAULTS.DISCOUNTED_LINES
},
total_discounts: {
type: Sequelize.INTEGER,
defaultValue: enums_2.PRODUCT_DEFAULTS.TOTAL_DISCOUNTS
},
published_scope: {
type: Sequelize.STRING,
defaultValue: enums_2.PRODUCT_DEFAULTS.PUBLISHED_SCOPE
},
published: {
type: Sequelize.BOOLEAN,
defaultValue: enums_2.PRODUCT_DEFAULTS.PUBLISHED
},
published_at: {
type: Sequelize.DATE
},
unpublished_at: {
type: Sequelize.DATE
},
available: {
type: Sequelize.BOOLEAN,
defaultValue: enums_2.PRODUCT_DEFAULTS.AVAILABLE
},
options: {
type: Sequelize.JSONB,
defaultValue: enums_2.PRODUCT_DEFAULTS.OPTIONS
},
property_pricing: {
type: Sequelize.JSONB,
defaultValue: {}
},
weight: {
type: Sequelize.INTEGER,
defaultValue: enums_2.PRODUCT_DEFAULTS.WEIGHT
},
weight_unit: {
type: Sequelize.ENUM,
values: lodash_1.values(enums_1.UNITS),
defaultValue: enums_2.PRODUCT_DEFAULTS.WEIGHT_UNIT
},
review_score: {
type: Sequelize.INTEGER,
defaultValue: enums_2.PRODUCT_DEFAULTS.REVIEWS_SCORE
},
total_reviews: {
type: Sequelize.INTEGER,
defaultValue: enums_2.PRODUCT_DEFAULTS.TOTAL_REVIEWS
},
total_variants: {
type: Sequelize.INTEGER,
defaultValue: enums_2.PRODUCT_DEFAULTS.TOTAL_VARIANTS
},
average_shipping: {
type: Sequelize.INTEGER,
defaultValue: 0
},
exclude_payment_types: {
type: Sequelize.JSONB,
defaultValue: []
},
google: {
type: Sequelize.JSONB,
defaultValue: {}
},
amazon: {
type: Sequelize.JSONB,
defaultValue: {}
},
live_mode: {
type: Sequelize.BOOLEAN,
defaultValue: app.config.get('cart.live_mode')
}
};
}
static associate(models) {
models.Product.hasMany(models.ProductImage, {
as: 'images',
foreignKey: 'product_id',
through: null,
onDelete: 'CASCADE'
});
models.Product.hasMany(models.ProductVariant, {
as: 'variants',
foreignKey: 'product_id',
onDelete: 'CASCADE'
});
models.Product.hasMany(models.ProductReview, {
as: 'reviews',
foreignKey: 'product_id',
onDelete: 'CASCADE'
});
models.Product.belongsToMany(models.Collection, {
as: 'collections',
through: {
model: models.ItemCollection,
unique: false,
scope: {
model: 'product'
}
},
foreignKey: 'model_id',
constraints: false
});
models.Product.hasOne(models.Metadata, {
as: 'metadata',
foreignKey: 'product_id'
});
models.Product.belongsToMany(models.Vendor, {
as: 'vendors',
through: {
model: models.VendorProduct,
unique: false,
},
foreignKey: 'product_id',
});
models.Product.belongsToMany(models.Shop, {
as: 'shops',
through: {
model: models.ShopProduct,
unique: false,
},
foreignKey: 'product_id',
});
models.Product.belongsToMany(models.Tag, {
as: 'tags',
through: {
model: models.ItemTag,
unique: false,
scope: {
model: 'product'
}
},
foreignKey: 'model_id',
otherKey: 'tag_id',
constraints: false
});
models.Product.belongsToMany(models.Product, {
as: 'associations',
through: {
model: models.ProductAssociation,
unique: false
},
foreignKey: 'product_id',
otherKey: 'associated_product_id',
});
models.Product.belongsToMany(models.Product, {
as: 'relations',
through: {
model: models.ProductAssociation,
unique: false
},
foreignKey: 'associated_product_id',
otherKey: 'product_id',
});
models.Product.belongsToMany(models.Discount, {
as: 'discounts',
through: {
model: models.ItemDiscount,
unique: false,
scope: {
model: 'product'
}
},
foreignKey: 'model_id',
constraints: false
});
models.Product.belongsToMany(models.Event, {
as: 'event_items',
through: {
model: models.EventItem,
unique: false,
scope: {
object: 'product'
}
},
foreignKey: 'object_id',
constraints: false
});
}
}
exports.Product = Product;
Product.prototype.setItemDiscountedLines = function (discounts = [], criteria = [], options = {}) {
this.discounted_lines = [];
const factoredDiscountedLines = [];
let discountsArr = [];
if (options.req && options.req.cart) {
options.req.cart.line_items = options.req.cart.line_items || [];
options.req.cart.line_items.map(item => {
discounts.forEach(discount => {
item = discount.discountItem(item, criteria);
});
return item;
});
options.req.cart.line_items.forEach(item => {
item.discounted_lines = item.discounted_lines || [];
discountsArr = [...discountsArr, item.discounted_lines.map(line => line.id)];
});
}
discounts.forEach(discount => {
discount.discountItem(this, criteria);
});
this.discounted_lines.forEach(line => {
discountsArr = [...discountsArr, line.id];
});
this.discounted_lines = this.discounted_lines.map(discount => {
discount.rules = discount.rules || {};
if (discount.rules.applies_once && discountsArr.filter(d => d === discount.id).length > 1) {
const arrRemove = discountsArr.findIndex(d => d === discount.id);
discountsArr = discountsArr.splice(arrRemove, 1);
discount.applies = false;
}
else if (discount.rules.minimum_order_amount > 0
&& options.req
&& options.req.cart
&& (options.req.cart.total_price + this.price) < discount.minimum_order_amount) {
discount.applies = false;
}
else if (discount.rules.applies_compound === false && discountsArr.length > 1) {
discount.applies = false;
}
else {
discount.applies = true;
}
return discount;
});
this.discounted_lines.forEach(discountedLine => {
if (discountedLine.applies === true) {
const calculatedPrice = Math.max(0, this.calculated_price - discountedLine.price);
const totalDeducted = Math.min(this.calculated_price, (this.calculated_price - (this.calculated_price - discountedLine.price)));
this.calculated_price = calculatedPrice;
this.total_discounts = Math.min(this.price, this.total_discounts + totalDeducted);
const fI = factoredDiscountedLines.findIndex(d => d.id === discountedLine.id);
if (fI > -1) {
factoredDiscountedLines[fI].price = factoredDiscountedLines[fI].price + totalDeducted;
}
else {
discountedLine.price = totalDeducted;
factoredDiscountedLines.push(discountedLine);
}
}
});
return this.setDiscountedLines(factoredDiscountedLines);
};
Product.prototype.setDiscountedLines = function (lines) {
this.total_discounts = 0;
this.discounted_lines = lines || [];
this.discounted_lines.forEach(line => {
this.total_discounts = this.total_discounts + line.price;
});
return this.setTotals();
};
Product.prototype.setCalculatedPrice = function (calculatedPrice) {
this.calculated_price = calculatedPrice;
return this;
};
Product.prototype.setTotals = function () {
this.total_price = Math.max(0, this.total_tax
+ this.total_shipping
+ this.subtotal_price);
this.total_due = Math.max(0, this.total_price
- this.total_discounts
- this.total_coupons
- this.total_overrides);
return this;
};
Product.prototype.getCustomerHistory = function (customer, options = {}) {
let hasPurchaseHistory = false, isSubscribed = false;
return this.hasPurchaseHistory(customer.id, options)
.then(pHistory => {
hasPurchaseHistory = pHistory;
return this.isSubscribed(customer.id, options);
})
.then(pHistory => {
isSubscribed = pHistory;
this.setDataValue('has_purchase_history', hasPurchaseHistory);
this.setDataValue('is_subscribed', isSubscribed);
return this;
})
.catch(err => {
this.setDataValue('has_purchase_history', hasPurchaseHistory);
this.setDataValue('is_subscribed', isSubscribed);
return this;
});
};
Product.prototype.hasPurchaseHistory = function (customerId, options = {}) {
return this.app.models['OrderItem'].findOne({
where: {
customer_id: customerId,
product_id: this.id,
fulfillment_status: {
$not: ['cancelled', 'pending', 'none']
}
},
attributes: ['id'],
transaction: options.transaction || null
})
.then(pHistory => {
if (pHistory) {
return true;
}
else {
return false;
}
})
.catch(err => {
return false;
});
};
Product.prototype.isSubscribed = function (customerId, options = {}) {
return this.app.models['Subscription'].findOne({
where: {
customer_id: customerId,
active: true,
line_items: {
$contains: [{
product_id: this.id
}]
}
},
attributes: ['id'],
transaction: options.transaction || null
})
.then(pHistory => {
if (pHistory) {
return true;
}
else {
return false;
}
})
.catch(err => {
return false;
});
};
Product.prototype.getCollectionPairs = function (options = {}) {
const collectionPairs = [];
const criteria = [];
return Promise.resolve()
.then(() => {
if (options.req && options.req.customer && options.req.customer.id) {
criteria.push({
model: 'customer',
model_id: options.req.customer.id
});
}
if (this.id) {
criteria.push({
model: 'product',
model_id: this.id
});
}
if (criteria.length > 0) {
return this.app.models['ItemCollection'].findAll({
where: {
$or: criteria
},
attributes: ['id', 'collection_id', 'model', 'model_id'],
transaction: options.transaction || null
});
}
return [];
})
.then(_collections => {
_collections.forEach(collection => {
const i = collectionPairs.findIndex(c => c.id === collection.collection_id);
if (i > -1) {
if (!collectionPairs[i][collection.model]) {
collectionPairs[i][collection.model] = [];
}
collectionPairs[i][collection.model].push(collection.model_id);
}
else {
collectionPairs.push({
collection: collection.collection_id,
[collection.model]: [collection.model_id]
});
}
});
return collectionPairs;
})
.catch(err => {
this.app.log.error(err);
return [];
});
};
Product.prototype.calculateDiscounts = function (options = {}) {
const criteria = [];
let collectionPairs = [], discountCriteria = [], checkHistory = [];
let resDiscounts;
return Promise.resolve()
.then(() => {
return this.getCollectionPairs({
req: options.req || null,
transaction: options.transaction || null
});
})
.then(_collections => {
collectionPairs = _collections;
if (options.req && options.req.cart && options.req.cart.id) {
criteria.push({
model: 'cart',
model_id: options.req.cart.id
});
}
if (options.req && options.req.customer && options.req.customer.id) {
criteria.push({
model: 'customer',
model_id: options.req.customer.id
});
}
if (this.id) {
criteria.push({
model: 'product',
model_id: this.id
});
}
if (collectionPairs.length > 0) {
criteria.push({
model: 'collection',
model_id: collectionPairs.map(c => c.collection)
});
}
if (criteria.length > 0) {
return this.app.models['ItemDiscount'].findAll({
where: {
$or: criteria
},
attributes: ['discount_id', 'model', 'model_id'],
transaction: options.transaction || null
});
}
else {
return [];
}
})
.then(discounts => {
discounts.forEach(discount => {
const i = discountCriteria.findIndex(d => d.discount === discount.discount_id);
if (i > -1) {
if (!discountCriteria[i][discount.model]) {
discountCriteria[i][discount.model] = [];
}
discountCriteria[i][discount.model].push(discount.model_id);
}
else {
discountCriteria.push({
discount: discount.discount_id,
[discount.model]: [discount.model_id]
});
}
});
discountCriteria = discountCriteria.map(d => {
if (d.collection) {
d.collection.forEach(colId => {
const i = collectionPairs.findIndex(c => c.collection = colId);
if (i > -1) {
d = lodash_1.merge(d, collectionPairs[i]);
}
});
}
return d;
});
if (discounts.length > 0) {
return this.app.models['Discount'].findAll({
where: {
id: discounts.map(item => item.discount_id),
status: enums_3.DISCOUNT_STATUS.ENABLED
},
transaction: options.transaction || null
});
}
else {
return [];
}
})
.then(_discounts => {
_discounts = _discounts || [];
resDiscounts = _discounts;
resDiscounts.forEach(discount => {
if (discount.applies_once_per_customer
&& options.req
&& options.req.customer
&& options.req.customer.id) {
checkHistory.push(discount);
}
});
if (checkHistory.length > 0) {
return Promise.all(checkHistory.map(discount => {
return discount.eligibleCustomer(options.req.customer.id, {
transaction: options.transaction || null
});
}));
}
else {
return [];
}
})
.then(_eligible => {
_eligible = _eligible || [];
_eligible.forEach(discount => {
const i = resDiscounts.findIndex(ii => ii.id === discount.id);
if (i > -1) {
resDiscounts.splice(i, 1);
}
});
return this.setItemDiscountedLines(resDiscounts, discountCriteria, options);
})
.catch(err => {
this.app.log.error(err);
return this;
});
};
Product.prototype.calculate = function (options = {}) {
if (!this) {
return;
}
this.calculated_price = this.price;
return this.calculateDiscounts(options)
.then(() => {
return this;
});
};
Product.prototype.mergeIntoCollections = function (colsB = []) {
const collections = this.collections;
colsB.forEach(collection => {
if (!this.collections.some(colA => colA.id === collection.id)) {
collections.push(collection);
}
});
this.collections = collections;
this.setDataValue('collections', collections);
this.set('collections', collections);
return this;
};
Product.prototype.toJSON = function () {
const position = this.position;
const resp = this instanceof this.app.models['Product'].instance ? this.get({ plain: true }) : this;
resp.calculated_price = resp.price;
if (resp.tags) {
resp.tags = resp.tags.map(tag => {
if (tag && lodash_1.isString(tag)) {
return tag;
}
else if (tag && tag.name && tag.name !== '') {
return tag.name;
}
});
}
if (resp.variants) {
resp.variants.map((variant, idx) => {
if (variant.tags) {
resp.variants[idx].tags = variant.tags.map(tag => {
if (tag && lodash_1.isString(tag)) {
return tag;
}
else if (tag && tag.name) {
return tag.name;
}
});
}
if (variant.metadata) {
if (typeof variant.metadata.data !== 'undefined') {
resp.variants[idx].metadata = variant.metadata.data;
}
}
resp.variants[idx].calculated_price = variant.price;
});
}
if (resp.metadata) {
if (typeof resp.metadata.data !== 'undefined') {
resp.metadata = resp.metadata.data;
}
}
if (resp.vendors) {
resp.vendors = resp.vendors.map(vendor => {
if (vendor && lodash_1.isString(vendor)) {
return vendor;
}
else {
return vendor.name;
}
});
}
if (position) {
resp.position = position;
}
return resp;
};
Product.prototype.resolveVariants = function (options = {}) {
if (this.variants
&& this.variants.every(v => v instanceof this.app.models['ProductVariant'].instance)
&& options.reload !== true) {
return Promise.resolve(this);
}
else {
return this.getVariants({
limit: 500,
transaction: options.transaction || null,
order: [['position', 'ASC']]
})
.then(variants => {
variants = variants || [];
this.variants = variants;
this.setDataValue('variants', variants);
this.set('variants', variants);
return this;
});
}
};
Product.prototype.getDefaultVariant = function (options = {}) {
if (this.variants
&& this.variants.every(v => v instanceof this.app.models['ProductVariant'].instance)
&& this.variants.some(v => v.position === 1)
&& options.reload !== true) {
return Promise.resolve(this.variants.find(v => v.position === 1));
}
else {
return this.getVariants({
where: {
position: 1
},
limit: 1,
transaction: options.transaction || null
})
.then(variants => {
const variant = variants[0] || null;
return variant;
});
}
};
Product.prototype.resolveAssociations = function (options = {}) {
if (this.associations
&& this.associations.every(p => p instanceof this.app.models['Product'].instance)
&& options.reload !== true) {
return Promise.resolve(this);
}
else {
return this.getAssociations({
limit: 100,
transaction: options.transaction || null
})
.then(associations => {
associations = associations || [];
this.associations = associations;
this.setDataValue('associations', associations);
this.set('associations', associations);
return this;
});
}
};
Product.prototype.resolveImages = function (options = {}) {
if (this.images
&& this.images.every(i => i instanceof this.app.models['ProductImage'].instance)
&& options.reload !== true) {
return Promise.resolve(this);
}
else {
return this.getImages({
limit: 50,
transaction: options.transaction || null,
order: [['position', 'ASC']]
})
.then(images => {
images = images || [];
this.images = images;
this.setDataValue('images', images);
this.set('images', images);
return this;
});
}
};
Product.prototype.resolveVendors = function (options = {}) {
if (this.vendors
&& this.vendors.every(v => v instanceof this.app.models['Vendor'].instance)
&& options.reload !== true) {
return Promise.resolve(this);
}
else {
return this.getVendors({
limit: 50,
transaction: options.transaction || null
})
.then(vendors => {
vendors = vendors || [];
this.vendors = vendors;
this.setDataValue('vendors', vendors);
this.set('vendors', vendors);
return this;
});
}
};
Product.prototype.resolveVendors = function (options = {}) {
if (this.vendors
&& this.vendors.every(v => v instanceof this.app.models['Vendor'].instance)
&& options.reload !== true) {
return Promise.resolve(this);
}
else {
return this.getVendors({
limit: 50,
transaction: options.transaction || null
})
.then(vendors => {
vendors = vendors || [];
this.vendors = vendors;
this.setDataValue('vendors', vendors);
this.set('vendors', vendors);
return this;
});
}
};
Product.prototype.resolveMetadata = function (options = {}) {
if (this.metadata
&& this.metadata instanceof this.app.models['Metadata'].instance
&& options.reload !== true) {
return Promise.resolve(this);
}
else {
return this.getMetadata({ transaction: options.transaction || null })
.then(_metadata => {
_metadata = _metadata || { product_id: this.id };
this.metadata = _metadata;
this.setDataValue('metadata', _metadata);
this.set('metadata', _metadata);
return this;
});
}
};
Product.prototype.resolveShops = function (options = {}) {
if (this.shops
&& this.shops.length > 0
&& this.shops.every(d => d instanceof this.app.models['Shop'].instance)
&& options.reload !== true) {
return Promise.resolve(this);
}
else {
return this.getShops({
limit: 50,
transaction: options.transaction || null
})
.then(shops => {
shops = shops || [];
this.shops = shops;
this.setDataValue('shops', shops);
this.set('shops', shops);
return this;
});
}
};
Product.prototype.resolveTags = function (options = {}) {
if (this.tags
&& this.tags.length > 0
&& this.tags.every(t => t instanceof this.app.models['Tag'].instance)
&& options.reload !== true) {
return Promise.resolve(this);
}
else {
return this.getTags({
limit: 50,
transaction: options.transaction || null
})
.then(tags => {
tags = tags || [];
this.tags = tags;
this.setDataValue('tags', tags);
this.set('tags', tags);
return this;
});
}
};
Product.prototype.resolveCollections = function (options = {}) {
if (this.collections
&& this.collections.length > 0
&& this.collections.every(c => c instanceof this.app.models['Collection'].instance)
&& options.reload !== true) {
return Promise.resolve(this);
}
else {
return this.getCollections({
limit: 50,
transaction: options.transaction || null
})
.then(collections => {
collections = collections || [];
this.collections = collections;
this.setDataValue('collections', collections);
this.set('collections', collections);
return this;
});
}
};
Product.prototype.resolveCoupons = function (options = {}) {
if (this.coupons
&& this.coupons.length > 0
&& this.coupons.every(c => c instanceof this.app.models['Coupon'].instance)
&& options.reload !== true) {
return Promise.resolve(this);
}
else {
return this.getCoupons({ transaction: options.transaction || null })
.then(coupons => {
coupons = coupons || [];
this.coupons = coupons;
this.setDataValue('coupons', coupons);
this.set('coupons', coupons);
return this;
});
}
};
Product.prototype.resolveDiscounts = function (options = {}) {
if (this.discounts
&& this.discounts.length > 0
&& this.discounts.every(d => d instanceof this.app.models['Discount'].instance)
&& options.reload !== true) {
return Promise.resolve(this);
}
else {
return this.getDiscounts({
limit: 10,
transaction: options.transaction || null
})
.then(_discounts => {
_discounts = _discounts || [];
this.discounts = _discounts;
this.setDataValue('discounts', _discounts);
this.set('discounts', _discounts);
return this;
});
}
};