UNPKG

@fabrix/spool-cart

Version:

Spool - eCommerce Spool for Fabrix

264 lines (263 loc) 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const common_1 = require("@fabrix/fabrix/dist/common"); const csvParser = require("papaparse"); const _ = require("lodash"); const shortid = require("shortid"); const fs = require("fs"); const enums_1 = require("../../enums"); class CollectionCsvService extends common_1.FabrixService { publish(type, event, options = {}) { if (this.app.services.EventsService) { options.include = options.include || [{ model: this.app.models.EventItem.instance, as: 'objects' }]; return this.app.services.EventsService.publish(type, event, options); } this.app.log.debug('spool-events is not installed, please install it to use publish'); return Promise.resolve(); } collectionCsv(file) { console.time('csv'); const uploadID = shortid.generate(); const EventsService = this.app.services.EventsService; const errors = []; let errorsCount = 0, lineNumber = 1; return new Promise((resolve, reject) => { const options = { header: true, dynamicTyping: true, encoding: 'utf-8', step: (results, parser) => { parser.pause(); lineNumber++; return this.csvCollectionRow(results.data[0], uploadID) .then(row => { parser.resume(); }) .catch(err => { this.app.log.error('ROW ERROR', err); errorsCount++; errors.push(`Line ${lineNumber}: ${err.message}`); parser.resume(); }); }, complete: (results, _file) => { console.timeEnd('csv'); results.upload_id = uploadID; EventsService.count('CollectionUpload', { where: { upload_id: uploadID } }) .then(count => { results.collections = count; results.errors = errors; results.errors_count = errorsCount; EventsService.publish('collection_upload.complete', results); return resolve(results); }) .catch(err => { errorsCount++; errors.push(err.message); results.errors = errors; return resolve(results); }); }, error: (err, _file) => { return reject(err); } }; const fileString = fs.readFileSync(file, 'utf8'); csvParser.parse(fileString, options); }); } csvCollectionRow(row, uploadID) { return Promise.resolve() .then(() => { const CollectionUpload = this.app.models.CollectionUpload; const values = _.values(enums_1.COLLECTION_UPLOAD); const keys = _.keys(enums_1.COLLECTION_UPLOAD); const upload = { upload_id: uploadID, options: {}, images: [], collections: [], tags: [] }; _.each(row, (data, key) => { if (typeof (data) === 'undefined' || data === '') { row[key] = null; } }); row = _.omitBy(row, _.isNil); if (_.isEmpty(row)) { return Promise.resolve({}); } _.each(row, (data, key) => { if (typeof (data) !== 'undefined' && data !== null && data !== '') { const i = values.indexOf(key.replace(/^\s+|\s+$/g, '')); const k = keys[i]; if (i > -1 && k) { if (k === 'handle') { upload[k] = this.app.services.ProxyCartService.splitHandle(data.toString()); } else if (k === 'title') { upload[k] = this.app.services.ProxyCartService.title(data); } else if (k === 'description') { upload[k] = this.app.services.ProxyCartService.description(data); } else if (k === 'seo_title') { upload[k] = this.app.services.ProxyCartService.title(data); } else if (k === 'seo_description') { upload[k] = this.app.services.ProxyCartService.description(data); } else if (k === 'discount_product_include') { upload[k] = data.toString().split(',').map(discount => { return discount.trim(); }); } else if (k === 'discount_product_exclude') { upload[k] = data.toString().split(',').map(discount => { return discount.trim(); }); } else if (k === 'collections') { upload[k] = data.toString().split(',').map(collection => { return collection.trim(); }); } else if (k === 'images') { upload[k] = data.toString().split(',').map(images => { return images.trim(); }); } else if (k === 'images_alt') { upload[k] = data.toString().split('|').map(images => { return images.trim(); }); } else if (k === 'tags') { upload[k] = _.uniq(data.toString().split(',').map(tag => { return tag.toLowerCase().trim(); })); } else { upload[k] = data; } } } }); upload.images = upload.images.map((image, index) => { return { src: image, alt: upload.images_alt ? upload.images_alt[index] || null : '' }; }); upload.images = upload.images.filter(image => image); upload.collections = upload.collections.map(collection => { return { handle: this.app.services.ProxyCartService.splitHandle(collection), title: collection }; }); upload.collections = upload.collections.filter(collection => collection); upload.collections = _.uniqBy(upload.collections, 'handle'); upload.tags = upload.tags.map(tag => { if (tag !== '') { return { name: this.app.services.ProxyCartService.name(tag) }; } }); upload.tags = upload.tags.filter(tag => tag); upload.tags = _.uniqBy(upload.tags, 'name'); if (!upload.handle) { return Promise.resolve({}); } else { const newCollection = CollectionUpload.build(upload); return newCollection.save(); } }); } processCollectionUpload(uploadId, options) { options = options || {}; const CollectionUpload = this.app.models.CollectionUpload; let collectionsTotal = 0, errorsCount = 0; const errors = []; return CollectionUpload.batch({ where: { upload_id: uploadId }, transaction: options.transaction || null }, collections => { return this.app.models.Collection.sequelize.Promise.mapSeries(collections, collection => { let create = { handle: collection.handle, title: collection.title, description: collection.description, seo_title: collection.seo_title, seo_description: collection.seo_description, excerpt: collection.excerpt, body: collection.body, primary_purpose: collection.primary_purpose, position: collection.position, sort_order: collection.sort_order, published: collection.published, tax_rate: collection.tax_rate, tax_percentage: collection.tax_percentage, tax_type: collection.tax_type, tax_name: collection.tax_name, shipping_rate: collection.shipping_rate, shipping_percentage: collection.shipping_percentage, shipping_type: collection.shipping_type, shipping_name: collection.shipping_name, discount_scope: collection.discount_scope, discount_status: collection.discount_status, discount_type: collection.discount_type, discount_rate: collection.discount_rate, discount_percentage: collection.discount_percentage, discount_product_include: collection.discount_product_include, discount_product_exclude: collection.discount_product_exclude, collections: collection.collections, images: collection.images, tags: collection.tags }; create = _.omitBy(create, _.isNil); return this.app.services.CollectionService.add(create, { transaction: options.transaction || null }) .then((createdCollection) => { if (!createdCollection) { throw new Error(`${collection.handle} was not created`); } collectionsTotal++; return; }) .catch(err => { this.app.log.error(err); errorsCount++; errors.push(`${collection.handle}: ${err.message}`); return err; }); }); }) .then(() => { return CollectionUpload.destroy({ where: { upload_id: uploadId } }) .catch(err => { errorsCount++; errors.push(err.message); return err; }); }) .then(destroyed => { const results = { upload_id: uploadId, collections: collectionsTotal, errors_count: errorsCount, errors: errors }; this.app.services.EventsService.publish('collection_process.complete', results); return results; }); } } exports.CollectionCsvService = CollectionCsvService;