UNPKG

@fabrix/spool-cart

Version:

Spool - eCommerce Spool for Fabrix

233 lines (232 loc) 9.3 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 CustomerCsvService 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(); } customerCsv(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.csvCustomerRow(results.data[0], uploadID) .then(row => { parser.resume(); }) .catch(err => { errorsCount++; errors.push(`Line ${lineNumber}: ${err.message}`); this.app.log.error('ROW ERROR', err); parser.resume(); }); }, complete: (results, _file) => { console.timeEnd('csv'); results.upload_id = uploadID; EventsService.count('CustomerUpload', { where: { upload_id: uploadID } }) .then(count => { results.customers = count; results.errors = errors; results.errors_count = errorsCount; EventsService.publish('customer_upload.complete', results); return resolve(results); }) .catch(err => { errorsCount++; errors.push(err.message); results.errors = errors; results.errors_count = errorsCount; return resolve(results); }); }, error: (err, _file) => { return reject(err); } }; const fileString = fs.readFileSync(file, 'utf8'); csvParser.parse(fileString, options); }); } csvCustomerRow(row, uploadID) { const CustomerUpload = this.app.models.CustomerUpload; const values = _.values(enums_1.CUSTOMER_UPLOAD); const keys = _.keys(enums_1.CUSTOMER_UPLOAD); const upload = { upload_id: uploadID, users: [], collections: [], accounts: [], options: {} }; _.each(row, (data, key) => { if (!data || data === '') { row[key] = null; } }); row = _.omitBy(row, _.isNil); if (_.isEmpty(row)) { return Promise.resolve({}); } _.each(row, (data, key) => { if (data && data !== '') { const i = values.indexOf(key.replace(/^\s+|\s+$/g, '')); const k = keys[i]; if (i > -1 && k) { if (k === 'tags') { upload[k] = _.uniq(data.toLowerCase().split(',').map(tag => { return tag.trim(); })); } else if (k === 'collections') { upload[k] = data.split(',').map(collection => { return collection.trim(); }); } else if (k === 'accounts') { upload[k] = data.split(',').map(account => { return account.trim(); }); } else if (k === 'users') { upload[k] = data.split(',').map(user => { return user.trim(); }); } else { upload[k] = data; } } } }); upload.collections = upload.collections.map((collection, index) => { return { handle: this.app.services.ProxyCartService.splitHandle(collection), title: collection }; }); upload.collections = upload.collections.filter(collection => collection); upload.accounts = upload.accounts.map((account, index) => { return { gateway: account.split(/:(.+)/)[0], foreign_id: account.split(/:(.+)/)[1] }; }); upload.accounts = upload.accounts.filter(account => account); upload.users = upload.users.map((user, index) => { return { email: user }; }); upload.users = upload.users.filter(user => user); const newCustomer = CustomerUpload.build(upload); return newCustomer.save(); } processCustomerUpload(uploadId, options) { options = options || {}; const CustomerUpload = this.app.models['CustomerUpload']; const errors = []; let customersTotal = 0; let errorsCount = 0; return CustomerUpload.batch({ where: { upload_id: uploadId } }, (customers) => { const Sequelize = this.app.models['Customer'].sequelize; return Sequelize.Promise.mapSeries(customers, customer => { const create = { account_balance: customer.account_balance, first_name: customer.first_name, last_name: customer.last_name, email: customer.email, company: customer.company, phone: customer.phone, shipping_address: {}, billing_address: {}, collections: customer.collections, tags: customer.tags, accounts: customer.accounts, users: customer.users }; customer = customer instanceof this.app.models['CustomerUpload'].instance ? customer.get({ plain: true }) : customer; _.each(customer, (value, key) => { if (key.indexOf('shipping_') > -1) { const newKey = key.replace('shipping_', ''); if (value && value !== '') { create.shipping_address[newKey] = value; } } if (key.indexOf('billing_') > -1) { const newKey = key.replace('billing_', ''); if (value && value !== '') { create.billing_address[newKey] = value; } } }); if (_.isEmpty(create.shipping_address)) { delete create.shipping_address; } if (_.isEmpty(create.billing_address)) { delete create.billing_address; } return this.app.services.CustomerService.create(create, { transaction: options.transaction || null }) .then(() => { customersTotal++; return; }) .catch(err => { errorsCount++; errors.push(err.message); return; }); }) .then(() => { return CustomerUpload.destroy({ where: { upload_id: uploadId }, transaction: options.transaction || null }) .catch(err => { errorsCount++; errors.push(err.message); return; }); }) .then(() => { const results = { upload_id: uploadId, customers: customersTotal, errors_count: errorsCount, errors: errors, }; this.app.services.EventsService.publish('customer_process.complete', results); return results; }); }); } } exports.CustomerCsvService = CustomerCsvService;