@fabrix/spool-cart
Version:
Spool - eCommerce Spool for Fabrix
233 lines (232 loc) • 9.3 kB
JavaScript
;
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;