UNPKG

@apihawk/billia-sdk

Version:

The ApiHawk Billia SDK

463 lines (462 loc) 17.6 kB
"use strict"; 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;