diff --git a/config/default.json b/config/default.json index 8a48722e..3ebc31c4 100644 --- a/config/default.json +++ b/config/default.json @@ -162,6 +162,21 @@ "accessTokenSecret": "7qunl3p505rubmr7u1ijt7odyialnih9" } }, + "magento1": { + "url": "http://magento-demo.local", + "imgUrl": "http://magento-demo.local/media/catalog/product", + "magentoUserName": "", + "magentoUserPassword": "", + "httpUserName": "", + "httpUserPassword": "", + "api": { + "url": "http://magento-demo.local/vsbridge", + "consumerKey": "", + "consumerSecret": "", + "accessToken": "", + "accessTokenSecret": "" + } + }, "imageable": { "namespace": "", "maxListeners": 512, diff --git a/src/platform/abstract/address.js b/src/platform/abstract/address.js new file mode 100644 index 00000000..d51eb653 --- /dev/null +++ b/src/platform/abstract/address.js @@ -0,0 +1,21 @@ +class AbstractAddressProxy { + constructor(config, req) { + this._config = config + this._request = req + } + + list (customerToken) { + throw new Error('AbstractAddressProxy::list must be implemented for specific platform') + } + update (customerToken, addressData) { + throw new Error('AbstractAddressProxy::update must be implemented for specific platform') + } + get (customerToken, addressId) { + throw new Error('AbstractAddressProxy::get must be implemented for specific platform') + } + delete (customerToken, addressData) { + throw new Error('AbstractAddressProxy::delete must be implemented for specific platform') + } +} + +export default AbstractAddressProxy diff --git a/src/platform/abstract/contact.js b/src/platform/abstract/contact.js new file mode 100644 index 00000000..6ff3ef92 --- /dev/null +++ b/src/platform/abstract/contact.js @@ -0,0 +1,7 @@ +class AbstractContactProxy { + submit (formData) { + throw new Error('AbstractContactProxy::check must be implemented for specific platform') + } +} + +module.exports = AbstractContactProxy diff --git a/src/platform/abstract/newsletter.js b/src/platform/abstract/newsletter.js new file mode 100644 index 00000000..90c0605a --- /dev/null +++ b/src/platform/abstract/newsletter.js @@ -0,0 +1,9 @@ +class AbstractNewsletterProxy { + subscribe (emailAddress) { + } + + unsubscribe (customerToken) { + } +} + +module.exports = AbstractNewsletterProxy diff --git a/src/platform/abstract/stock_alert.js b/src/platform/abstract/stock_alert.js new file mode 100644 index 00000000..5823eb61 --- /dev/null +++ b/src/platform/abstract/stock_alert.js @@ -0,0 +1,11 @@ +class AbstractStockAlertProxy { + constructor(config, req) { + this._config = config + this._request = req + } + subscribe (customerToken, productId, emailAddress) { + throw new Error('AbstractContactProxy::subscribe must be implemented for specific platform') + } +} + +export default AbstractStockAlertProxy diff --git a/src/platform/abstract/wishlist.js b/src/platform/abstract/wishlist.js new file mode 100644 index 00000000..4e86e997 --- /dev/null +++ b/src/platform/abstract/wishlist.js @@ -0,0 +1,13 @@ +class AbstractWishlistProxy { + pull (customerToken) { + throw new Error('AbstractWishlistProxy::pull must be implemented for specific platform') + } + update (customerToken, wishListItem) { + throw new Error('AbstractWishlistProxy::update must be implemented for specific platform') + } + delete (customerToken, wishListItem) { + throw new Error('AbstractWishlistProxy::delete must be implemented for specific platform') + } +} + +module.exports = AbstractWishlistProxy diff --git a/src/platform/magento1/address.js b/src/platform/magento1/address.js new file mode 100644 index 00000000..a76de1f2 --- /dev/null +++ b/src/platform/magento1/address.js @@ -0,0 +1,24 @@ +import AbstractAddressProxy from '../abstract/address' +import {multiStoreConfig} from "./util"; +import {Magento1Client} from "./module"; + +class AddressProxy extends AbstractAddressProxy { + constructor (config, req){ + super(config, req) + this.api = Magento1Client(multiStoreConfig(config.magento1.api, req)); + } + list (customerToken) { + return this.api.address.list(customerToken) + } + update (customerToken, addressData) { + return this.api.address.update(customerToken, addressData); + } + get (customerToken, addressId) { + return this.api.address.get(customerToken, addressId) + } + delete (customerToken, addressData) { + return this.api.address.delete(customerToken, addressData) + } +} + +module.exports = AddressProxy diff --git a/src/platform/magento1/cart.js b/src/platform/magento1/cart.js new file mode 100644 index 00000000..f674ae00 --- /dev/null +++ b/src/platform/magento1/cart.js @@ -0,0 +1,48 @@ +import AbstractCartProxy from '../abstract/cart'; +import { multiStoreConfig } from './util'; +import { Magento1Client } from './module/index'; + +class CartProxy extends AbstractCartProxy { + constructor (config, req){ + super(config, req) + this.api = Magento1Client(multiStoreConfig(config.magento1.api, req)); + } + create (customerToken) { + return this.api.cart.create(customerToken); + } + update (customerToken, cartId, cartItem) { + return this.api.cart.update(customerToken, cartId, cartItem); + } + delete (customerToken, cartId, cartItem) { + return this.api.cart.delete(customerToken, cartId, cartItem); + } + pull (customerToken, cartId, params) { + return this.api.cart.pull(customerToken, cartId, params); + } + totals (customerToken, cartId, params) { + return this.api.cart.totals(customerToken, cartId, params); + } + getShippingMethods (customerToken, cartId, address) { + return this.api.cart.shippingMethods(customerToken, cartId, address); + } + getPaymentMethods (customerToken, cartId) { + return this.api.cart.paymentMethods(customerToken, cartId); + } + setShippingInformation (customerToken, cartId, address) { + return this.api.cart.shippingInformation(customerToken, cartId, address); + } + collectTotals (customerToken, cartId, shippingMethod) { + return this.api.cart.collectTotals(customerToken, cartId, shippingMethod); + } + applyCoupon (customerToken, cartId, coupon) { + return this.api.cart.applyCoupon(customerToken, cartId, coupon); + } + deleteCoupon (customerToken, cartId) { + return this.api.cart.deleteCoupon(customerToken, cartId); + } + getCoupon (customerToken, cartId) { + return this.api.cart.getCoupon(customerToken, cartId); + } +} + +module.exports = CartProxy; diff --git a/src/platform/magento1/contact.js b/src/platform/magento1/contact.js new file mode 100644 index 00000000..76db5708 --- /dev/null +++ b/src/platform/magento1/contact.js @@ -0,0 +1,15 @@ +import AbstractContactProxy from '../abstract/contact'; +import { multiStoreConfig } from './util'; +import { Magento1Client } from './module/index'; + +class ContactProxy extends AbstractContactProxy { + constructor (config, req){ + super(config, req) + this.api = Magento1Client(multiStoreConfig(config.magento1.api, req)); + } + submit (form) { + return this.api.contact.submit(form); + } +} + +module.exports = ContactProxy; diff --git a/src/platform/magento1/module/index.js b/src/platform/magento1/module/index.js new file mode 100644 index 00000000..5fe77d2a --- /dev/null +++ b/src/platform/magento1/module/index.js @@ -0,0 +1,40 @@ +const RestClient = require('./lib/rest_client').RestClient; +const user = require('./lib/user'); +const cart = require('./lib/cart'); +const stock = require('./lib/stock'); +const contact = require('./lib/contact'); +const wishlist = require('./lib/wishlist'); +const stockAlert = require('./lib/stock_alert'); +const newsletter = require('./lib/newsletter'); +const address = require('./lib/address'); + +const MAGENTO_API_VERSION = 'V1'; + +module.exports.Magento1Client = function (options) { + let instance = { + addMethods (key, module) { + let client = RestClient(options); + if (module) { + if (this[key]) + this[key] = Object.assign(this[key], module(client)); + else + this[key] = module(client); + } + } + }; + + options.version = MAGENTO_API_VERSION; + + let client = RestClient(options); + + instance.user = user(client); + instance.cart = cart(client); + instance.stock = stock(client); + instance.contact = contact(client); + instance.wishlist = wishlist(client); + instance.stockAlert = stockAlert(client); + instance.newsletter = newsletter(client); + instance.address = address(client); + + return instance; +}; diff --git a/src/platform/magento1/module/lib/address.js b/src/platform/magento1/module/lib/address.js new file mode 100644 index 00000000..ef22d353 --- /dev/null +++ b/src/platform/magento1/module/lib/address.js @@ -0,0 +1,36 @@ +module.exports = function (restClient) { + let module = {}; + let url = 'address/'; + function getResponse(data){ + if (data.code === 200){ + return data.result; + } + + return false; + } + module.list = function (customerToken) { + url += `list?token=${customerToken}` + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + }, + module.update = function (customerToken, addressData) { + url += `update?token=${customerToken}` + return restClient.post(url, {address: addressData}).then((data)=> { + return getResponse(data); + }); + } + module.get = function (customerToken, addressId) { + url += `get?token=${customerToken}&addressId=${addressId}` + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + module.delete = function (customerToken, addressData) { + url += `delete?token=${customerToken}` + return restClient.post(url, {address: addressData}).then((data)=> { + return getResponse(data); + }); + } + return module; +} diff --git a/src/platform/magento1/module/lib/cart.js b/src/platform/magento1/module/lib/cart.js new file mode 100644 index 00000000..69d80bdb --- /dev/null +++ b/src/platform/magento1/module/lib/cart.js @@ -0,0 +1,82 @@ +function isNumeric(val) { + return Number(parseFloat(val)).toString() === val; +} + +module.exports = function (restClient) { + let module = {}; + const urlPrefix = 'cart/'; + let url = urlPrefix; + function getResponse(data){ + if(data.code === 200){ + return data.result; + } + return false; + } + module.create = (customerToken) => { + url += `create?token=${customerToken}`; + return restClient.post(url).then((data)=> { + return getResponse(data); + }); + } + module.update = (customerToken, cartId, cartItem) => { + url += `update?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url, { cartItem: cartItem }).then((data)=> { + return getResponse(data); + }); + } + module.applyCoupon = (customerToken, cartId, coupon) => { + url += `applyCoupon?token=${customerToken}&cartId=${cartId}&coupon=${coupon}`; + return restClient.post(url).then((data)=> { + return getResponse(data); + }); + } + module.deleteCoupon = (customerToken, cartId) => { + url += `deleteCoupon?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url).then((data)=> { + return getResponse(data); + }); + } + module.delete = (customerToken, cartId, cartItem) => { + url += `delete?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url, { cartItem: cartItem }).then((data)=> { + return getResponse(data); + }); + } + module.pull = (customerToken, cartId) => { + url += `pull?token=${customerToken}&cartId=${cartId}`; + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + module.totals = (customerToken, cartId) => { + url += `totals?token=${customerToken}&cartId=${cartId}`; + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + module.shippingInformation = (customerToken, cartId, body) => { + url += `totals?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url, body).then((data)=> { + return getResponse(data); + }); + } + module.shippingMethods = (customerToken, cartId, address) => { + url += `shippingMethods?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url, { address: address }).then((data)=> { + return getResponse(data); + }); + } + module.paymentMethods = (customerToken, cartId) => { + url += `paymentMethods?token=${customerToken}&cartId=${cartId}`; + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + module.getCoupon = (customerToken, cartId) => { + url += `coupon?token=${customerToken}&cartId=${cartId}`; + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + return module; +} diff --git a/src/platform/magento1/module/lib/contact.js b/src/platform/magento1/module/lib/contact.js new file mode 100644 index 00000000..996698e8 --- /dev/null +++ b/src/platform/magento1/module/lib/contact.js @@ -0,0 +1,18 @@ +module.exports = function (restClient) { + let module = {}; + const urlPrefix = 'contact/'; + let url = urlPrefix; + function getResponse(data){ + if(data.code === 200){ + return data.result; + } + return false; + } + module.submit = (form) => { + url += `submit`; + return restClient.post(url, {form}).then((data)=> { + return getResponse(data); + }); + }; + return module; +}; diff --git a/src/platform/magento1/module/lib/log.js b/src/platform/magento1/module/lib/log.js new file mode 100644 index 00000000..50c6520b --- /dev/null +++ b/src/platform/magento1/module/lib/log.js @@ -0,0 +1,19 @@ +var winston = require('winston'); + +winston.emitErrs = true; + +var logger = new winston.Logger({ + transports: [ + new winston.transports.Console({ + level: 'debug', + handleExceptions: true, + json: false, + colorize: true + }) + ], + exitOnError: false +}); + +logger.info('Winston logging library initialized.'); + +module.exports = logger; diff --git a/src/platform/magento1/module/lib/newsletter.js b/src/platform/magento1/module/lib/newsletter.js new file mode 100644 index 00000000..9c1396e1 --- /dev/null +++ b/src/platform/magento1/module/lib/newsletter.js @@ -0,0 +1,24 @@ +module.exports = function (restClient) { + let module = {}; + const urlPrefix = 'newsletter/'; + let url = urlPrefix; + function getResponse(data){ + if(data.code === 200){ + return data.result; + } + return false; + } + module.subscribe = (emailAddress) => { + url += `subscribe`; + return restClient.post(url, {emailAddress: emailAddress}).then((data)=> { + return getResponse(data); + }); + }; + module.unsubscribe = (customerToken) => { + url += `unsubscribe?token=${customerToken}`; + return restClient.post(url).then((data)=> { + return getResponse(data); + }); + }; + return module; +}; diff --git a/src/platform/magento1/module/lib/rest_client.js b/src/platform/magento1/module/lib/rest_client.js new file mode 100644 index 00000000..6db954c3 --- /dev/null +++ b/src/platform/magento1/module/lib/rest_client.js @@ -0,0 +1,138 @@ +'use strict'; + +const OAuth = require('oauth-1.0a'); +const request = require('request'); +const logger = require('./log'); + +module.exports.RestClient = function (options) { + let instance = {}; + + var servelrUrl = options.url; + var oauth = OAuth({ + consumer: { + public: options.consumerKey, + secret: options.consumerSecret + }, + signature_method: 'HMAC-SHA1' + }); + var token = { + public: options.accessToken, + secret: options.accessTokenSecret + }; + + function apiCall(request_data, request_token = '') { + logger.debug('Calling API endpoint: ' + request_data.method + ' ' + request_data.url + ' token: ' + request_token); + + logger.info({ + url: request_data.url, + method: request_data.method, + headers: request_token ? { 'Authorization': 'Bearer ' + request_token } : oauth.toHeader(oauth.authorize(request_data, token)), + json: true, + body: request_data.body, + }); + /* eslint no-undef: off*/ + return new Promise(function (resolve, reject) { + request({ + url: request_data.url, + method: request_data.method, + headers: request_token ? { 'Authorization': 'Bearer ' + request_token } : oauth.toHeader(oauth.authorize(request_data, token)), + json: true, + body: request_data.body, + }, function (error, response, body) { + logger.debug('Response received') + if (error) { + logger.error('Error occured: ' + error); + reject(error); + return; + } else if (!httpCallSucceeded(response)) { + let errorMessage = '' + + if (body) { + errorMessage = 'HTTP ERROR ' + body.code; + } else { + errorMessage = 'HTTP ERROR ' + response.code; + } + + if (body && body.hasOwnProperty('result')) + errorMessage = errorString(body.result, body.hasOwnProperty('parameters') ? body.parameters : {}); + + logger.error('API call failed: ' + errorMessage); + reject(errorMessage); + } + resolve(body); + }); + }); + } + + instance.consumerToken = function (login_data) { + return apiCall({ + url: createUrl('/integration/customer/token'), + method: 'POST', + body: login_data + }) + } + + function httpCallSucceeded(response) { + return response.statusCode >= 200 && response.statusCode < 300; + } + + function errorString(message, parameters) { + if (parameters === null) { + return message; + } + let parameterPlaceholder + if (parameters instanceof Array) { + for (let i = 0; i < parameters.length; i++) { + parameterPlaceholder = '%' + (i + 1).toString(); + message = message.replace(parameterPlaceholder, parameters[i]); + } + } else if (parameters instanceof Object) { + for (let key in parameters) { + parameterPlaceholder = '%' + key; + message = message.replace(parameterPlaceholder, parameters[key]); + } + } + + return message; + } + + instance.get = function (resourceUrl, request_token = '') { + const request_data = { + url: createUrl(resourceUrl), + method: 'GET' + }; + return apiCall(request_data, request_token); + } + + function createUrl(resourceUrl) { + return servelrUrl + '/' + resourceUrl; + } + + instance.post = function (resourceUrl, data, request_token = '') { + const request_data = { + url: createUrl(resourceUrl), + method: 'POST', + body: data + }; + return apiCall(request_data, request_token); + } + + instance.put = function (resourceUrl, data, request_token = '') { + const request_data = { + url: createUrl(resourceUrl), + method: 'PUT', + body: data + }; + return apiCall(request_data, request_token); + } + + instance.delete = function (resourceUrl, request_token = '') { + const request_data = { + url: createUrl(resourceUrl), + method: 'DELETE' + }; + return apiCall(request_data, request_token); + } + + return instance; +} diff --git a/src/platform/magento1/module/lib/stock.js b/src/platform/magento1/module/lib/stock.js new file mode 100644 index 00000000..8cd3e959 --- /dev/null +++ b/src/platform/magento1/module/lib/stock.js @@ -0,0 +1,18 @@ +module.exports = function (restClient) { + let module = {}; + const urlPrefix = 'stock/'; + let url = urlPrefix; + function getResponse(data){ + if(data.code === 200){ + return data.result; + } + return false; + } + module.check = (sku) => { + url += `check?sku=${sku}`; + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + }; + return module; +}; diff --git a/src/platform/magento1/module/lib/stock_alert.js b/src/platform/magento1/module/lib/stock_alert.js new file mode 100644 index 00000000..1168ac9c --- /dev/null +++ b/src/platform/magento1/module/lib/stock_alert.js @@ -0,0 +1,32 @@ +module.exports = function (restClient) { + let module = {}; + const urlPrefix = 'stockalert/'; + let url = urlPrefix; + function getResponse(data){ + if (data.code === 200){ + return data.result; + } + + return false; + } + module.subscribe = (customerToken, productId, emailAddress) => { + url += `add`; + + if (typeof customerToken !== 'undefined' && customerToken) { + url += `?token=${customerToken}` + } + + let alertData = { + productId: productId + } + + if (emailAddress) { + alertData.emailAddress = emailAddress + } + + return restClient.post(url, alertData).then((data)=> { + return getResponse(data); + }); + }; + return module; +}; diff --git a/src/platform/magento1/module/lib/user.js b/src/platform/magento1/module/lib/user.js new file mode 100644 index 00000000..2dc8e2c2 --- /dev/null +++ b/src/platform/magento1/module/lib/user.js @@ -0,0 +1,68 @@ +module.exports = function (restClient) { + let module = {}; + let url = 'user/'; + function getResponse(data){ + if (data.code === 200){ + return data.result; + } + + return false; + } + module.login = (userData) => { + url += 'login'; + return restClient.post(url, userData).then((data)=> { + return getResponse(data); + }); + } + module.resetPassword = function (emailData) { + url += `resetPassword`; + return restClient.post(url, {email: emailData.email}).then((data)=> { + return getResponse(data); + }); + } + module.changePassword = function (passwordData) { + url += `changePassword?token=${passwordData.token}`; + return restClient.post(url, passwordData.body).then((data)=> { + return getResponse(data); + }); + } + module.create = function (userData) { + url += `create`; + return restClient.post(url, userData).then((data)=> { + return getResponse(data); + }); + } + module.creditValue = function (customerToken) { + const getCreditUrl = `user_credit/get?token=${customerToken}` + + return restClient.get(getCreditUrl).then((data)=> { + return getResponse(data); + }); + } + module.refillCredit = function (customerToken, creditCode) { + const getCreditUrl = `user_credit/refill?token=${customerToken}` + + return restClient.post(getCreditUrl, {credit_code: creditCode}).then((data)=> { + return getResponse(data); + }); + } + module.orderHistory = function (customerToken, page, pageSize) { + url += `orderHistory?token=${customerToken}`; + return restClient.get(url, {page: page, pageSize: pageSize}).then((data)=> { + return getResponse(data); + }); + } + module.update = function (userData) { + url += `me?token=${userData.token}` + return restClient.post(url, userData.body).then((data)=> { + return getResponse(data); + }); + } + module.me = function (customerToken) { + const url = `user/me?token=${customerToken}` + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + } + return module; +} diff --git a/src/platform/magento1/module/lib/wishlist.js b/src/platform/magento1/module/lib/wishlist.js new file mode 100644 index 00000000..50992a07 --- /dev/null +++ b/src/platform/magento1/module/lib/wishlist.js @@ -0,0 +1,36 @@ +module.exports = function (restClient) { + let module = {}; + const urlPrefix = 'wishlist/'; + let url = urlPrefix; + function getResponse(data){ + if(data.code === 200){ + return data.result; + } + return false; + } + module.pull = (customerToken) => { + url += `pull?token=${customerToken}`; + return restClient.get(url).then((data)=> { + return getResponse(data); + }); + }; + module.update = (customerToken, wishListItem) => { + url += `update?token=${customerToken}`; + return restClient.post(url, {wishListItem: wishListItem}).then((data)=> { + return getResponse(data); + }); + }; + module.delete = (customerToken, wishListItem) => { + url += `delete?token=${customerToken}`; + return restClient.post(url, {wishListItem: wishListItem}).then((data)=> { + return getResponse(data); + }); + }; + module.moveToCart = (customerToken, cartId, wishListItem) => { + url += `moveToCart?token=${customerToken}&cartId=${cartId}`; + return restClient.post(url, {wishListItem: wishListItem}).then((data)=> { + return getResponse(data); + }); + }; + return module; +}; diff --git a/src/platform/magento1/newsletter.js b/src/platform/magento1/newsletter.js new file mode 100644 index 00000000..2edea6e0 --- /dev/null +++ b/src/platform/magento1/newsletter.js @@ -0,0 +1,18 @@ +import AbstractNewsletterProxy from '../abstract/newsletter'; +import { multiStoreConfig } from './util'; +import { Magento1Client } from './module/index'; + +class NewsletterProxy extends AbstractNewsletterProxy { + constructor (config, req){ + super(config, req) + this.api = Magento1Client(multiStoreConfig(config.magento1.api, req)); + } + subscribe (emailAddress) { + return this.api.newsletter.subscribe(emailAddress); + } + unsubscribe (customerToken) { + return this.api.newsletter.unsubscribe(customerToken); + } +} + +module.exports = NewsletterProxy; diff --git a/src/platform/magento1/stock.js b/src/platform/magento1/stock.js new file mode 100644 index 00000000..eddee69c --- /dev/null +++ b/src/platform/magento1/stock.js @@ -0,0 +1,15 @@ +import AbstractUserProxy from '../abstract/user'; +import { multiStoreConfig } from './util'; +import { Magento1Client } from './module/index'; + +class StockProxy extends AbstractUserProxy { + constructor (config, req){ + super(config, req) + this.api = Magento1Client(multiStoreConfig(config.magento1.api, req)); + } + check (sku) { + return this.api.stock.check(sku); + } +} + +module.exports = StockProxy; diff --git a/src/platform/magento1/stock_alert.js b/src/platform/magento1/stock_alert.js new file mode 100644 index 00000000..95d7195e --- /dev/null +++ b/src/platform/magento1/stock_alert.js @@ -0,0 +1,15 @@ +import AbstractStockAlertProxy from '../abstract/stock_alert'; +import { multiStoreConfig } from './util'; +import { Magento1Client } from './module/index'; + +class StockAlertProxy extends AbstractStockAlertProxy { + constructor (config, req){ + super(config, req) + this.api = Magento1Client(multiStoreConfig(config.magento1.api, req)); + } + subscribe (customerToken, productId, emailAddress) { + return this.api.stockAlert.subscribe(customerToken, productId, emailAddress); + } +} + +module.exports = StockAlertProxy; diff --git a/src/platform/magento1/tax.js b/src/platform/magento1/tax.js new file mode 100644 index 00000000..6b09c2a9 --- /dev/null +++ b/src/platform/magento1/tax.js @@ -0,0 +1,100 @@ +import AbstractTaxProxy from '../abstract/tax' +import { calculateProductTax } from '../../lib/taxcalc' +const es = require('elasticsearch') +const bodybuilder = require('bodybuilder') +import TierHelper from '../../helpers/priceTiers' + +class TaxProxy extends AbstractTaxProxy { + constructor (config, entityType, indexName, taxCountry, taxRegion = '', sourcePriceInclTax = null) { + super(config) + this._entityType = entityType + this._indexName = indexName + this._sourcePriceInclTax = sourcePriceInclTax + + if (this._config.storeViews && this._config.storeViews.multistore) { + for (let storeCode in this._config.storeViews){ + let store = this._config.storeViews[storeCode] + if (typeof store === 'object') { + if (store.elasticsearch && store.elasticsearch.index) { // workaround to map stores + if (store.elasticsearch.index === indexName) { + taxRegion = store.tax.defaultRegion + taxCountry = store.tax.defaultCountry + sourcePriceInclTax = store.tax.sourcePriceIncludesTax + break; + } + } + } + } + } else { + if (!taxRegion) { + taxRegion = this._config.tax.defaultRegion + } + if (!taxCountry) { + taxCountry = this._config.tax.defaultCountry + } + } + if (sourcePriceInclTax === null) { + sourcePriceInclTax = this._config.tax.sourcePriceIncludesTax + } + this._taxCountry = taxCountry + this._taxRegion = taxRegion + this._sourcePriceInclTax = sourcePriceInclTax + console.log('Taxes will be calculated for', taxCountry, taxRegion, sourcePriceInclTax) + this.taxFor = this.taxFor.bind(this) + } + + taxFor (product) { + return calculateProductTax(product, this._taxClasses, this._taxCountry, this._taxRegion, this._sourcePriceInclTax) + } + + applyTierPrices (productList, groupId) { + if (this._config.usePriceTiers) { + for (let item of productList) { + TierHelper(item._source, groupId) + } + } + } + + process (productList, groupId = null) { + let inst = this + return new Promise ((resolve, reject) => { + inst.applyTierPrices(productList, groupId) + + if (this._config.tax.calculateServerSide) { + const esConfig = { // as we're runing tax calculation and other data, we need a ES indexer + host: { + host: this._config.elasticsearch.host, + port: this._config.elasticsearch.port + }, + log: 'debug', + apiVersion: '5.5', + requestTimeout: 5000 + } + if (this._config.elasticsearch.user) { + esConfig.httpAuth = this._config.elasticsearch.user + ':' + this._config.elasticsearch.password + } + + let client = new es.Client(esConfig) + const esQuery = { + index: this._indexName, + type: 'taxrule', + body: bodybuilder() + } + client.search(esQuery).then(function (taxClasses) { // we're always trying to populate cache - when online + inst._taxClasses = taxClasses.hits.hits.map(el => { return el._source }) + for (let item of productList) { + inst.taxFor(item._source) + } + + resolve(productList) + }).catch(err => { + reject(err) + }) + } else { + resolve(productList) + } + }) + } +} + +module.exports = TaxProxy diff --git a/src/platform/magento1/user.js b/src/platform/magento1/user.js new file mode 100644 index 00000000..f3f9ce8f --- /dev/null +++ b/src/platform/magento1/user.js @@ -0,0 +1,39 @@ +import AbstractUserProxy from '../abstract/user' +import { multiStoreConfig } from './util' +import {Magento1Client} from "./module"; + +class UserProxy extends AbstractUserProxy { + constructor (config, req){ + super(config, req) + this.api = Magento1Client(multiStoreConfig(config.magento1.api, req)); + } + register (userData) { + return this.api.user.create(userData) + } + login (userData) { + return this.api.user.login(userData) + } + me (customerToken) { + return this.api.user.me(customerToken) + } + orderHistory (customerToken, page, pageSize) { + return this.api.user.orderHistory(customerToken, page, pageSize) + } + creditValue (customerToken) { + return this.api.user.creditValue(customerToken) + } + refillCredit (customerToken, creditCode) { + return this.api.user.refillCredit(customerToken, creditCode) + } + resetPassword (emailData) { + return this.api.user.resetPassword(emailData) + } + update (userData) { + return this.api.user.update(userData) + } + changePassword (passwordData) { + return this.api.user.changePassword(passwordData) + } +} + +module.exports = UserProxy diff --git a/src/platform/magento1/util.js b/src/platform/magento1/util.js new file mode 100644 index 00000000..38a25636 --- /dev/null +++ b/src/platform/magento1/util.js @@ -0,0 +1,30 @@ +import config from 'config' +/** + * Adjust the config provided to the current store selected via request params + * @param Object config configuration + * @param Express request req + */ +export function multiStoreConfig(apiConfig, req) { + let confCopy = Object.assign({}, apiConfig) + let storeCode = '' + + if (req.headers['x-vs-store-code']) { + storeCode = req.headers['x-vs-store'] + } + if (req.query.storeCode) { + storeCode = req.query.storeCode + } + + if (storeCode && config.availableStores.indexOf(storeCode) >= 0) + { + if (config.magento2['api_' + storeCode]) { + confCopy = Object.assign({}, config.magento2['api_' + storeCode]) // we're to use the specific api configuration - maybe even separate magento instance + } + confCopy.url = confCopy.url + '/' + storeCode + } else { + if (storeCode) { + console.error('Unavailable store code', storeCode) + } + } + return confCopy +} \ No newline at end of file diff --git a/src/platform/magento1/wishlist.js b/src/platform/magento1/wishlist.js new file mode 100644 index 00000000..6048e90c --- /dev/null +++ b/src/platform/magento1/wishlist.js @@ -0,0 +1,21 @@ +import AbstractWishlistProxy from '../abstract/wishlist'; +import { multiStoreConfig } from './util'; +import { Magento1Client } from './module/index'; + +class WishlistProxy extends AbstractWishlistProxy { + constructor (config, req){ + super(config, req) + this.api = Magento1Client(multiStoreConfig(config.magento1.api, req)); + } + pull (customerToken) { + return this.api.wishlist.pull(customerToken); + } + update (customerToken, wishListItem) { + return this.api.wishlist.update(customerToken, wishListItem); + } + delete (customerToken, wishListItem) { + return this.api.wishlist.delete(customerToken, wishListItem); + } +} + +module.exports = WishlistProxy;