UNPKG

trailpack-proxy-cart

Version:

eCommerce - Trailpack for Proxy Engine

639 lines (612 loc) 21 kB
/* eslint no-console: [0] */ 'use strict' const Service = require('trails/service') const _ = require('lodash') const Errors = require('proxy-engine-errors') // const COLLECTION_DISCOUNT_TYPE = require('../../lib').Enums.COLLECTION_DISCOUNT_TYPE // const COLLECTION_DISCOUNT_SCOPE = require('../../lib').Enums.COLLECTION_DISCOUNT_SCOPE /** * @module CollectionService * @description Collection Service */ module.exports = class CollectionService extends Service { /** * Add a Collection * @param collection * @param options * @returns {Promise.<T>} */ add(collection, options) { options = options || {} const Collection = this.app.orm.Collection return Collection.resolve(collection, {transaction: options.transaction || null}) .then(resCollection => { if (!resCollection) { // Create a new Collection return this.create(collection, {transaction: options.transaction || null}) } else { // Update the existing collection resCollection = _.merge(resCollection, collection) return this.update(resCollection, {transaction: options.transaction || null}) } }) } /** * * @param collection * @param options */ create(collection, options) { options = options || {} const Collection = this.app.orm['Collection'] const Image = this.app.orm['Image'] const Discount = this.app.orm['Discount'] const Tag = this.app.orm['Tag'] let discounts = [] let resCollection let create = _.omit(collection, [ 'collections', 'images', 'discounts', 'discount_name', 'discount_status', 'discount_code', 'discount_scope', 'discount_type', 'discount_product_exclude', 'discount_product_include', 'discount_rate', 'discount_percentage', 'tags' ]) create = _.omitBy(create, _.isNil) if (collection.discount_type && collection.discount_type) { discounts.push({ name: collection.discount_name || collection.title, code: collection.discount_code || collection.title, status: collection.discount_status, discount_scope: collection.discount_scope, discount_type: collection.discount_type, discount_product_exclude: collection.discount_product_exclude, discount_product_include: collection.discount_product_include, discount_rate: collection.discount_rate, discount_percentage: collection.discount_percentage }) } if (collection.discounts && collection.discounts.length > 0) { discounts = [...discounts, ...collection.discounts] } return Collection.create(create, {transaction: options.transaction || null}) .then(createdCollection => { if (!createdCollection) { throw new Error('Collection was not created') } resCollection = createdCollection if (collection.collections && collection.collections.length > 0) { // Resolve the collections collection.collections = _.sortedUniq(collection.collections.filter(n => n)) return Collection.transformCollections(collection.collections, {transaction: options.transaction || null}) } return [] }) .then(collections => { if (collections && collections.length > 0) { return resCollection.setCollections(collections.map( c => c.id), {transaction: options.transaction || null}) } return }) .then(collections => { if (collection.images && collection.images.length > 0) { // Resolve the images collection.images = _.sortedUniq(collection.images.filter(n => n)) return Image.transformImages(collection.images, {transaction: options.transaction || null}) } return [] }) .then(images => { if (images && images.length > 0) { return Collection.sequelize.Promise.mapSeries(images, (image, index) => { return resCollection.addImage(image.id, {through: {position: index + 1 }, transaction: options.transaction || null}) }) } return }) .then(() => { if (discounts.length > 0) { return Discount.transformDiscounts(discounts, {transaction: options.transaction || null}) } return }) .then(discounts => { if (discounts && discounts.length > 0) { return resCollection.setDiscounts(discounts.map(d => d.id), {transaction: options.transaction || null}) } return }) .then(discounts => { if (collection.tags && collection.tags.length > 0) { collection.tags = _.sortedUniq(collection.tags.filter(n => n)) return Tag.transformTags(collection.tags, {transaction: options.transaction || null}) } return }) .then(tags => { if (tags && tags.length > 0) { // Add Tags return resCollection.setTags(tags.map(tag => tag.id), {transaction: options.transaction || null}) } return }) .then(tags => { return Collection.findByIdDefault(resCollection.id, {transaction: options.transaction || null}) }) } /** * * @param collection * @param options */ update(collection, options) { options = options || {} const Collection = this.app.orm['Collection'] const Image = this.app.orm['Image'] const Tag = this.app.orm['Tag'] if (!collection.id) { const err = new Errors.FoundError(Error('Collection is missing id')) return Promise.reject(err) } const update = _.omit(collection,['id','created_at','updated_at','collections','images','tags']) let resCollection return Collection.resolve(collection, {transaction: options.transaction || null}) .then(_collection => { if (!_collection) { throw new Error('Collection could not be resolved') } resCollection = _collection return resCollection.update(update, {transaction: options.transaction || null}) }) .then(updatedCollection => { resCollection = updatedCollection if (collection.collections && collection.collections.length > 0) { // Resolve the collections collection.collections = _.sortedUniq(collection.collections.filter(n => n)) return Collection.transformCollections(collection.collections, {transaction: options.transaction || null}) } return }) .then(collections => { if (collections && collections.length > 0) { return resCollection.setCollections(collections.map(c => c.id), {transaction: options.transaction || null}) } return [] }) .then(collections => { if (collection.images && collection.images.length > 0) { // Resolve the images collection.images = _.sortedUniq(collection.images.filter(n => n)) return Image.transformImages(collection.images, {transaction: options.transaction || null}) } else { return [] } }) .then(images => { if (images && images.length > 0) { return Collection.sequelize.Promise.mapSeries(images, (image, index) => { return resCollection.addImage(image.id, { through: {position: index + 1}, transaction: options.transaction || null }) }) } return }) .then(images => { if (collection.tags && collection.tags.length > 0) { collection.tags = _.sortedUniq(collection.tags.filter(n => n)) return Tag.transformTags(collection.tags, {transaction: options.transaction || null}) } return }) .then(tags => { if (tags && tags.length > 0) { // Add Tags return resCollection.setTags(tags.map(tag => tag.id), {transaction: options.transaction || null}) } return }) .then(() => { return Collection.findByIdDefault(resCollection.id, {transaction: options.transaction || null}) }) } /** * Add Multiple Collections * @param collection * @param collections * @param options * @returns {Promise.<*>} */ addCollections(collection, collections, options) { options = options || {} if (!Array.isArray(collections)) { collections = [collections] } const Sequelize = this.app.orm['Collection'].sequelize // const addedProducts = [] // Setup Transaction return Sequelize.transaction(t => { return Sequelize.Promise.mapSeries(collections, subCollection => { return this.addCollection(collection, subCollection, { transaction: t }) }) }) } /** * * @param collection * @param subCollection * @param options * @returns {Promise.<T>} */ addCollection(collection, subCollection, options){ options = options || {} const Collection = this.app.orm['Collection'] // const ItemCollection = this.app.orm['ItemCollection'] let resCollection, resSubCollection return Collection.resolve(collection, {transaction: options.transaction || null}) .then(collection => { if (!collection) { throw new Errors.FoundError(Error('Collection not found')) } resCollection = collection return Collection.resolve(subCollection, {transaction: options.transaction || null}) }) .then(_subCollection => { if (!_subCollection) { throw new Errors.FoundError(Error('Sub Collection not found')) } resSubCollection = _subCollection // return resCollection.hasCollection(resSubCollection.id, {transaction: options.transaction || null}) // }) // .then(hasCollection => { // if (!hasCollection) { // return ItemCollection.create({ // collection_id: resCollection.id, // model_id: resSubCollection.id, // model: 'collection' // }, {transaction: options.transaction || null}) const through = subCollection.collection_position ? { position: subCollection.collection_position } : {} return resCollection.addCollection(resSubCollection.id, { through: through, hooks: false, individualHooks: false, returning: false, transaction: options.transaction || null }) // } // return }) .then(() => { return resSubCollection // return Collection.findByIdDefault(resCollection.id, {transaction: options.transaction || null}) }) } /** * * @param collection * @param subCollection * @param options * @returns {Promise.<T>} */ removeCollection(collection, subCollection, options){ options = options || {} const Collection = this.app.orm['Collection'] let resCollection, resSubCollection return Collection.resolve(collection, {transaction: options.transaction || null}) .then(collection => { if (!collection) { throw new Errors.FoundError(Error('Collection not found')) } resCollection = collection return Collection.resolve(subCollection, {transaction: options.transaction || null}) }) .then(subCollection => { if (!subCollection) { throw new Errors.FoundError(Error('Sub Collection not found')) } resSubCollection = subCollection return resCollection.hasCollection(resSubCollection.id, {transaction: options.transaction || null}) }) .then(hasCollection => { if (hasCollection) { return resCollection.removeCollection(resSubCollection.id, {transaction: options.transaction || null}) } return resCollection }) .then(collection => { return resSubCollection // return Collection.findByIdDefault(resCollection.id, {transaction: options.transaction || null}) }) } /** * Add Multiple Products * @param collection * @param products * @param options * @returns {Promise.<*>} */ addProducts(collection, products, options) { options = options || {} if (!Array.isArray(products)) { products = [products] } const Sequelize = this.app.orm['Collection'].sequelize // const addedProducts = [] // Setup Transaction return Sequelize.transaction(t => { return Sequelize.Promise.mapSeries(products, product => { return this.addProduct(collection, product, { transaction: t }) }) }) } /** * * @param collection * @param product * @param options * @returns {Promise.<T>} */ addProduct(collection, product, options){ options = options || {} const Collection = this.app.orm['Collection'] const Product = this.app.orm['Product'] let resCollection, resProduct return Collection.resolve(collection, {transaction: options.transaction || null}) .then(collection => { if (!collection) { throw new Errors.FoundError(Error('Collection not found')) } resCollection = collection return Product.resolve(product, {transaction: options.transaction || null}) }) .then(product => { if (!product) { throw new Errors.FoundError(Error('Product not found')) } resProduct = product return resCollection.hasProduct(resProduct.id, {transaction: options.transaction || null}) }) .then(hasCollection => { const through = product.product_position ? {position: product.product_position} : {} // if (!hasCollection) { return resCollection.addProduct(resProduct.id, { through: through, transaction: options.transaction || null }) // } // else if (product.product_position) { // return resCollection.updateProduct(resProduct.id, { // through: through, // transaction: options.transaction || null // }) // } // return resCollection }) .then(collection => { return resProduct }) } /** * * @param collection * @param product * @param options * @returns {Promise.<T>} */ removeProduct(collection, product, options){ options = options || {} const Collection = this.app.orm['Collection'] const Product = this.app.orm['Product'] let resCollection, resProduct return Collection.resolve(collection, {transaction: options.transaction || null}) .then(collection => { if (!collection) { throw new Errors.FoundError(Error('Collection not found')) } resCollection = collection return Product.resolve(product, {transaction: options.transaction || null}) }) .then(product => { if (!product) { throw new Errors.FoundError(Error('Product not found')) } resProduct = product return resCollection.hasProduct(resProduct.id, {transaction: options.transaction || null}) }) .then(hasCollection => { if (hasCollection) { return resCollection.removeProduct(resProduct.id, {transaction: options.transaction || null}) } return resCollection }) .then(collection => { return resProduct // return Collection.findByIdDefault(resCollection.id, {transaction: options.transaction || null}) }) } /** * * @param collection * @param tag * @param options * @returns {Promise.<T>} */ addTag(collection, tag, options){ options = options || {} const Collection = this.app.orm['Collection'] const Tag = this.app.orm['Tag'] let resCollection, resTag return Collection.resolve(collection, {transaction: options.transaction || null}) .then(collection => { if (!collection) { throw new Errors.FoundError(Error('Collection not found')) } resCollection = collection return Tag.resolve(tag, {transaction: options.transaction || null}) }) .then(tag => { if (!tag) { throw new Errors.FoundError(Error('Tag not found')) } resTag = tag return resCollection.hasTag(resTag.id, {transaction: options.transaction || null}) }) .then(hasCollection => { if (!hasCollection) { return resCollection.addTag(resTag.id, {transaction: options.transaction || null}) } return resCollection }) .then(collection => { return Collection.findByIdDefault(resCollection.id, {transaction: options.transaction || null}) }) } /** * * @param collection * @param tag * @param options * @returns {Promise.<T>} */ removeTag(collection, tag, options){ options = options || {} const Collection = this.app.orm['Collection'] const Tag = this.app.orm['Tag'] let resCollection, resTag return Collection.resolve(collection, {transaction: options.transaction || null}) .then(collection => { if (!collection) { throw new Errors.FoundError(Error('Collection not found')) } resCollection = collection return Tag.resolve(tag, {transaction: options.transaction || null}) }) .then(tag => { if (!tag) { throw new Errors.FoundError(Error('Tag not found')) } resTag = tag return resCollection.hasTag(resTag.id, {transaction: options.transaction || null}) }) .then(hasCollection => { if (hasCollection) { return resCollection.removeTag(resTag.id, {transaction: options.transaction || null}) } return resCollection }) .then(collection => { return Collection.findByIdDefault(resCollection.id, {transaction: options.transaction || null}) }) } /** * Add Multiple Customers * @param collection * @param customers * @param options * @returns {Promise.<*>} */ addCustomers(collection, customers, options) { options = options || {} if (!Array.isArray(customers)) { customers = [customers] } const Sequelize = this.app.orm['Collection'].sequelize // const addedProducts = [] // Setup Transaction return Sequelize.transaction(t => { return Sequelize.Promise.mapSeries(customers, customer => { return this.addCustomer(collection, customer, { transaction: t }) }) }) } /** * * @param collection * @param customer * @param options * @returns {Promise.<T>} */ addCustomer(collection, customer, options){ options = options || {} const Collection = this.app.orm['Collection'] const Customer = this.app.orm['Customer'] let resCollection, resCustomer return Collection.resolve(collection, {transaction: options.transaction || null}) .then(collection => { if (!collection) { throw new Errors.FoundError(Error('Collection not found')) } resCollection = collection return Customer.resolve(customer, {transaction: options.transaction || null, create: false}) }) .then(customer => { if (!customer) { throw new Errors.FoundError(Error('Customer not found')) } resCustomer = customer return resCollection.hasCustomer(resCustomer.id, {transaction: options.transaction || null}) }) .then(hasCollection => { if (!hasCollection) { return resCollection.addCustomer(resCustomer.id, {transaction: options.transaction || null}) } return resCollection }) .then(collection => { return resCustomer // return Collection.findByIdDefault(resCollection.id, {transaction: options.transaction || null}) }) } /** * * @param collection * @param customer * @returns {Promise.<TResult>} */ removeCustomer(collection, customer){ const Collection = this.app.orm['Collection'] const Customer = this.app.orm['Customer'] let resCollection, resCustomer return Collection.resolve(collection) .then(collection => { if (!collection) { throw new Errors.FoundError(Error('Collection not found')) } resCollection = collection return Customer.resolve(customer, {create: false}) }) .then(customer => { if (!customer) { throw new Errors.FoundError(Error('Customer not found')) } resCustomer = customer return resCollection.hasCustomer(resCustomer.id) }) .then(hasCollection => { if (hasCollection) { return resCollection.removeCustomer(resCustomer.id) } return resCollection }) .then(collection => { return resCustomer // return Collection.findByIdDefault(resCollection.id) }) } }