@apihawk/billia-sdk
Version:
The ApiHawk Billia SDK
463 lines (462 loc) • 17.6 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const qs = require("qs");
const billia_sdk_service_base_1 = require("../lib/billia-sdk-service-base");
const billia_sdk_catalog_1 = require("./billia-sdk-catalog");
const to_rest_resource_1 = require("./common/to-rest-resource");
class BilliaSDKCart extends billia_sdk_service_base_1.BilliaSDKServiceBase {
constructor(api) {
super(api);
this.billiaSDKCatalog = new billia_sdk_catalog_1.BilliaSDKCatalog(api);
}
/**
* Adding item to cart
* @param {ICartItemToAdd} cartItem
* @param {IApihawkSession} session
* @param tempCart
* @returns {Promise<boolean>}
*/
addToCart(cartItem, session, tempCart = []) {
return __awaiter(this, void 0, void 0, function* () {
tempCart.push(cartItem);
return this._addCartItems(tempCart, session);
});
}
/**
* Bulk add to cart
* @param {ICartItemToAdd[]} items
* @param {IApihawkSession} session
* @returns {Promise<boolean>}
*/
bulkAddToCart(items = [], session) {
return __awaiter(this, void 0, void 0, function* () {
return yield this._addCartItems(items, session);
});
}
/**
* Get dummy cart items.
* @param {IApihawkSession} session
* @param {ICartItemToAdd[]} tempCart
* @returns {Promise<any>}
*/
getDummyCart(session, tempCart) {
return __awaiter(this, void 0, void 0, function* () {
if (tempCart && tempCart.length) {
return yield this._getDummyCart(tempCart);
}
else {
return yield Promise.resolve([]);
}
});
}
/**
* Get dummy cart
* @param {ICartItemToAdd[]} cart
* @returns {Promise<ICartItemToAdd[]>}
* @private
*/
_getDummyCart(cart = []) {
return __awaiter(this, void 0, void 0, function* () {
const productIDs = new Set();
cart.forEach((item) => {
productIDs.add(item.product_id);
});
if (productIDs.size === 0) {
return cart;
}
const catalogProduts = yield this.billiaSDKCatalog.getCatalogProducts([...productIDs], { page_size: -1 }, { advanced: true });
const productsByID = {};
catalogProduts.items.forEach((product) => {
productsByID[product.product_id] = product;
});
cart.forEach((item) => {
item.product = productsByID[item.product_id];
});
return cart;
});
}
/**
* Get cart items.
* @param {IApihawkSession} session
* @param {ICartItem[]} tempCart
* @param {string} promocode
* @param {number} customerProfileId
* @returns {Promise<IRestPaginatedResource<ICartItem>>}
*/
getCart(session, tempCart, promocode, customerProfileId) {
return __awaiter(this, void 0, void 0, function* () {
if (tempCart && tempCart.length) {
const addCartItemsResponse = yield this._addCartItems(tempCart, session);
return yield this._getCart(session, promocode, customerProfileId);
}
return yield this._getCart(session, promocode, customerProfileId);
});
}
/**
* Get cart summary.
* @param {IApihawkSession} session
* @returns {Promise<ICartSummary>}
*/
getCartSummary(session) {
return __awaiter(this, void 0, void 0, function* () {
const cart = yield this.api.call({
url: '/billing/cart?page_size=-1',
method: 'GET',
session,
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json',
'Accept-Response': 'Advanced'
}
});
const count = cart._embedded.cart.length;
const lines = cart._embedded.cart.map((l) => ({
item_id: l.item_id,
customer_product_id: l.customer_product_id,
product_id: l.product_id,
type: l.type
}));
const cartSummary = {
items: count,
total: cart.total,
lines
};
return cartSummary;
});
}
/**
* Remove cart item.
* @param {number} id
* @param {IApihawkSession} session
* @returns {Promise<boolean>}
*/
removeCartItem(id, session) {
return __awaiter(this, void 0, void 0, function* () {
return this.api
.call({
url: `/billing/cart/${id}`,
method: 'DELETE',
session,
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json'
}
})
.then(() => true);
});
}
/**
* Patch cart item.
* @param {number} id
* @param {ICartItemToAdd} body
* @param {IApihawkSession} session
* @returns {Promise<boolean>}
*/
patchCartItem(id, body, session) {
return __awaiter(this, void 0, void 0, function* () {
return this.api
.call({
url: `/billing/cart/${id}`,
method: 'PATCH',
session,
body,
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json'
}
})
.then(() => true);
});
}
/**
* Checkout cart
* @param {IApihawkSession} session
* @param {number} paymentMethodId
* @param {number} customerProfileId
* @param {number} affiliateID
* @returns {Promise<ICheckoutResponse>}
*/
checkout(session, paymentMethodId, customerProfileId, affiliateID) {
return __awaiter(this, void 0, void 0, function* () {
let query = `?payment_method_id=${paymentMethodId}`;
if (customerProfileId) {
query += `&customer_profile_id=${customerProfileId}`;
}
if (affiliateID) {
query += `&affiliate=${affiliateID}`;
}
const checkout = this.api.call({
url: `/billing/cart-checkout${query}`,
method: 'POST',
body: [],
session,
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json'
}
});
return checkout;
});
}
/**
* Renew
* @param session
* @param {number} customerProductId
* @returns {Promise<any>}
*/
renewCustomerProduct(session, customerProductId) {
return __awaiter(this, void 0, void 0, function* () {
return this.api.call({
url: `/customer/product-redact/${customerProductId}`,
method: 'POST',
body: { renew: {} },
session,
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json'
}
});
});
}
/**
* Get a promo code.
*
* @author Anton Katsarov
* @param {string} code - The promo code
* @param {Object} session
*/
getPromoCode(code = '', session) {
return __awaiter(this, void 0, void 0, function* () {
return this.api.call({
url: `/discount/promocode/${code}`,
method: 'GET',
session,
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json'
}
});
});
}
/**
* Get cart
* @param session
* @param {string} promocode
* @param {number} customerProfileId
* @returns {Promise<IRestPaginatedResource<ICartItem>>}
* @private
*/
_getCart(session, promocode, customerProfileId) {
return __awaiter(this, void 0, void 0, function* () {
let query = '?page_size=-1';
if (promocode === 'promo-code--remove') {
query += '&discount_code=false';
}
else if (promocode) {
query += `&discount_code=${promocode}`;
}
if (customerProfileId) {
query += `&customer_profile_id=${customerProfileId}`;
}
const cart = yield this.api.call({
url: `/billing/cart${query}`,
method: 'GET',
session,
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json',
'Accept-Response': 'Advanced'
}
});
const productIds = new Set();
cart._embedded.cart.forEach((item) => {
productIds.add(item.product_id);
if (item.type === 'upgrade' && item.metadata.fields.product_id) {
productIds.add(item.metadata.fields.product_id);
}
});
if (productIds.size) {
const catalogProduts = yield this.billiaSDKCatalog.getCatalogProducts([...productIds], { page_size: -1 }, { advanced: true }, session);
const options = {};
catalogProduts.items.forEach((product) => {
options[product.product_id] = product.options
? product.options.sort((a, b) => a.sort_weight - b.sort_weight)
: [];
});
cart._embedded.cart = cart._embedded.cart.map((item) => {
if (item.product) {
item.options = options[item.product.product_id] || [];
}
if (item.type === 'edit') {
const metaIds = item.metadata.options.map((option) => option.option_id);
if (item.product) {
item.options = options[item.product.product_id]
? options[item.product.product_id].filter((option) => metaIds.indexOf(option.option_id) > -1)
: [];
}
}
if (item.type === 'upgrade' && item.metadata.fields.product_id) {
item.product_to = catalogProduts.items.filter((p) => p.product_id === item.metadata.fields.product_id)[0];
}
const values = {};
item.metadata.options.forEach((metaOption) => {
values[item.item_id] = values[item.item_id] || {};
if (typeof metaOption.value !== 'undefined') {
values[item.item_id][metaOption.option.option_id] = {
value: metaOption.value
};
}
else if (typeof metaOption.choice_id !== 'undefined') {
values[item.item_id][metaOption.option.option_id] = {
choice_id: metaOption.choice_id
};
}
});
// Durty but works. For same product in cart options
item.options = JSON.parse(JSON.stringify(item.options.map((option) => {
return this._updateOptionValue(item.item_id, option, values);
})));
return item;
});
}
const categoryIds = new Set();
cart._embedded.cart.forEach((item) => {
categoryIds.add(item.product.category_id);
});
const categoriesFilter = qs.stringify({
where: [
{
field: 'id',
where: 'and',
type: 'in',
// prevents QueryBuilder from throwing errors when passing empty array
values: categoryIds.size > 0 ? Array.from(categoryIds) : [-1]
}
]
});
const categories = yield this.api.call({
url: `/billing/category?${categoriesFilter}`,
method: 'GET',
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json',
'Accept-Response': 'Advanced'
},
session
});
const categoryIndex = {};
if (categories) {
categories._embedded.catalog_category.forEach((category) => {
categoryIndex[category.id] = category;
});
cart._embedded.cart.forEach((item) => {
if (item.product) {
item.product.category = categoryIndex[item.product.category_id];
}
});
}
return to_rest_resource_1.toRestResource(cart, 'cart');
});
}
/**
* Add cart items
* @param {ICartItemToAdd[]} items
* @param {IApihawkSession} session
* @returns {Promise<boolean>}
* @private
*/
_addCartItems(items, session) {
return __awaiter(this, void 0, void 0, function* () {
if (!items || !items.length) {
throw new Error('Array of cart items is empty.');
}
const promises = [];
if (items && items.length && session) {
items.forEach((item) => {
if (item.quantity) {
promises.push(this.api.call({
url: '/billing/cart',
method: 'POST',
body: item,
session,
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json'
}
}));
}
});
}
return yield Promise.all(promises).then(() => true);
});
}
/**
* Update option value
* @param {number} itemId
* @param option
* @param values
* @returns {any}
* @private
*/
_updateOptionValue(itemId, option, values) {
if (values[itemId] && values[itemId][option.option_id]) {
if (typeof values[itemId][option.option_id].value !== 'undefined') {
option.value = values[itemId][option.option_id].value;
}
else if (typeof values[itemId][option.option_id].choice_id !== 'undefined') {
option.choice_id = values[itemId][option.option_id].choice_id;
}
option.default = false;
// If does not have a set value
}
else {
if (option.option_type === 'functional') {
if (option.choices) {
option.choice_id = parseInt(option.choices
.filter((choice) => choice.default.toString() === '1')
.filter((choice, id) => id === 0)
.map((choice) => choice.choice_id)
.join(''), 10);
}
else {
option.choice_id = 0; // Just in case
}
}
else if (option.option_type === 'group') {
const result = [];
option.group.forEach((subOption) => {
subOption = this._updateOptionValue(itemId, subOption, values);
if (subOption.default === false) {
if (typeof subOption.value !== 'undefined') {
result.push({
option_id: subOption.option_id,
value: subOption.value
});
}
else if (typeof subOption.choice_id !== 'undefined') {
result.push({
option_id: subOption.option_id,
choice_id: subOption.choice_id
});
}
}
});
option.value = result;
}
else {
option.values = '';
}
option.default = true;
}
return option;
}
}
exports.BilliaSDKCart = BilliaSDKCart;