const express = require('express'); const Module = require('../../base/Module'); const RepositorySystem = require('../../systems/RepositorySystem'); const RoutingSystem = require('../../systems/RoutingSystem'); const request = require('request'); const config = require('./config'); const rp = require('request-promise'); const xml2js = require('xml2js'); const knex = require('../../database/db'); class XmlSyncModule extends Module { constructor(){ super(); this.repository = RepositorySystem.create('Products'); this.CatRepo = RepositorySystem.create('Category'); this.CompRepo = RepositorySystem.create('Company'); this.parser = new xml2js.Parser(); this.router = express.Router(); this.init(); } init() { let routes = [ { type: 'custom', method: 'get', endpoint: '/sync', customFn: (req,res) => { this.parseXml() .then((products) => this.SyncDB(products)) .then(() => res.status(200).send()) .catch((e) => res.status(400).send(e)) } }, { type: 'custom', method: 'get', endpoint: '/test', customFn: (req,res) => { this.test() .then(() => res.status(200).send()) .catch((e) => res.status(400)) } }, ]; RoutingSystem.loadRoutes(routes, this.router); } test() { return this.repository.insert({ id : 1, name: 'skata' }).catch(() => console.log("EROR")) } parseXml() { let options = { method:"GET", uri: config.xml.api } return new Promise((resolve,reject) => { console.log("Requesting xml..."); rp(options).then((data) => { console.log("Data received..."); this.parser.parseString(data,(err,result) => { console.log(err, result); if(err) reject(err); try{ let products = result.store.products[0].product; resolve(products); }catch(e){ reject(e); } }) }) .catch((err) => { console.log("Error Receiving:"); console.log(err); throw err; }) }) } SyncDB(products){ var DBprods,XmlProds; console.log("Syncing..."); return this.repository.getPage(1,10000) .then((prods) => { DBprods = prods.reduce((dict,item) => { let id = item.id; dict[id] = item; return dict; }, {}) XmlProds = products.reduce((dict,item) => { let id = item.productId[0]; dict[id] = item; return dict; }, {}) console.log("Length ---> ",products.length) let Promises = Object.keys(XmlProds).map((key,indx) => { //return new Promise((resolve,reject) => { //}) let data = {}; try { data.id = parseInt(XmlProds[key].productId[0]); //data.name = XmlProds[key].name[0]; data.price = parseFloat(XmlProds[key].price[0]); data.name = XmlProds[key].productname[0]; data.quantity = XmlProds[key].quantity[0]; data.description = XmlProds[key].description[0]; data.shortdescription = XmlProds[key]["description-short"][0]; data.weight = parseFloat(XmlProds[key].weight[0]); data.image = XmlProds[key].image.length ? XmlProds[key].image[0] : ''; data.reference = XmlProds[key].reference.length ? XmlProds[key].reference[0] : ''; //extracting company and category name --> Category_path structure --> [' home > Toners > Hp'] let extra_data = XmlProds[key].Category_Path[0].split('>'); var category = extra_data[1] && extra_data[1].replace(' ',''); var company = extra_data[2] && extra_data[2].replace(' ',''); } catch(e) { console.log("INIT FAILED : ", data); console.log("ERROR: ", e); return () => Promise.resolve(true); } let keys = key; return () => Promise.resolve() .then(() => {if(category) return this.getCategoryId(category).then((id) => data.Category_id = id)}) .then(() => {if(company) return this.getCompanyId(company).then((comp_id) => data.Company_id = comp_id)}) .then(() => { return DBprods[keys] ? this.updateProduct(keys,data) : this.insertProduct(data) }) }); let ptimeout = (d,t) => new Promise((r,e) => setTimeout(() => r(d),t)); return Promises.reduce((promiseChain, currentTask) => { return promiseChain.then(chainResults => { return currentTask() .then(currentResult => [ ...chainResults, currentResult ]) }); }, Promise.resolve([])); }) .then(() => this.removeExtra(DBprods, XmlProds)) .catch((e) => console.log(e)) } removeExtra(db, xml) { console.log("REMOVING EXTRA..."); for(var i in xml) { delete db[i]; } let dbids = Object.keys(db); dbids = dbids.map((i) => parseInt(i)); let Promises = []; for(let i=0; i < dbids.length -1 ; i+=1 ) { if(!dbids[i])continue; var k = i; let sub = dbids.slice(k, k+1); Promises.push( this.repository.raw() .whereIn('id', sub) .update({deleted : 1}) ); } return Promise.all(Promises); } getCompanyId(comp) { return this.CompRepo.get('name',comp) .then((company) => { if(company.length){ return company[0].id; }else{ let data = { name:comp } return this.CompRepo.insert(data).returning('id'); } }) } getCategoryId(cat){ return this.CatRepo.get('name',cat) .then((category) => { if(category.length){ return category[0].id; }else{ let data = { name:cat } return this.CatRepo.insert(data).returning('id'); } }) } disableProduct(id) { return this.repository.update(''+id, { deleted:1 }); } insertProduct(data) { data.updatedAt = knex.fn.now() return this.repository.insert(data) } updateProduct(id,data) { data.updatedAt = knex.fn.now() return this.repository.update(id,data); } } module.exports = XmlSyncModule;