UNPKG

trailpack-proxy-cart

Version:

eCommerce - Trailpack for Proxy Engine

259 lines (242 loc) 7.37 kB
/* eslint no-console: [0] */ 'use strict' const Service = require('trails/service') const csvParser = require('papaparse') const _ = require('lodash') const shortid = require('shortid') const fs = require('fs') const CUSTOMER_UPLOAD = require('../../lib').Enums.CUSTOMER_UPLOAD /** * @module CustomerCsvService * @description Customer Csv Service */ module.exports = class CustomerCsvService extends Service { /** * * @param file * @returns {Promise} */ customerCsv(file) { console.time('csv') const uploadID = shortid.generate() const ProxyEngineService = this.app.services.ProxyEngineService 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 ProxyEngineService.count('CustomerUpload', { where: { upload_id: uploadID }}) .then(count => { results.customers = count results.errors = errors results.errors_count = errorsCount // Publish the event ProxyEngineService.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') // Parse the CSV/TSV csvParser.parse(fileString, options) }) } /** * * @param row * @param uploadID */ csvCustomerRow(row, uploadID) { const CustomerUpload = this.app.orm.CustomerUpload const values = _.values(CUSTOMER_UPLOAD) const keys = _.keys(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() } /** * * @param uploadId * @returns {Promise} */ processCustomerUpload(uploadId, options) { options = options || {} const CustomerUpload = this.app.orm['CustomerUpload'] const errors = [] let customersTotal = 0 let errorsCount = 0 return CustomerUpload.batch({ where: { upload_id: uploadId } }, (customers) => { const Sequelize = this.app.orm['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 } // Convert to normal object customer = customer instanceof this.app.orm['CustomerUpload'] ? 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.ProxyEngineService.publish('customer_process.complete', results) return results }) }) } }