@apihawk/billia-sdk
Version:
The ApiHawk Billia SDK
519 lines (518 loc) • 19.6 kB
JavaScript
"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 errors_1 = require("@apihawk/errors");
const qs = require("qs");
const billia_sdk_service_base_1 = require("../lib/billia-sdk-service-base");
const parse_product_translations_1 = require("./common/parse-product-translations");
const to_rest_resource_1 = require("./common/to-rest-resource");
class BilliaSDKCatalog extends billia_sdk_service_base_1.BilliaSDKServiceBase {
/**
* Get top-level categories
*/
getTopLevelCategories() {
return __awaiter(this, void 0, void 0, function* () {
const filter = qs.stringify({
where: [
{
field: 'parent_category_id',
where: 'and',
type: 'equalTo',
value: 0
},
{
field: 'state',
where: 'and',
type: 'notEqualTo',
value: 'disabled'
}
]
});
const response = yield this.api.call({
url: `/billing/category?${filter}`,
method: 'GET',
headers: {
Accept: 'application/vnd.image+json',
'Accept-Response': 'Advanced'
}
});
// filter children categories which are 'disabled'
const categories = response._embedded.catalog_category.map((cat) => {
if (Array.isArray(cat.child)) {
cat.child = cat.child.filter((child) => child.state !== 'disabled');
}
return cat;
});
return categories;
});
}
/**
* Get all product categories.
* Optionally you can filter categories by providing a list of category IDs.
*/
getAllCategories(categoryIds = []) {
return __awaiter(this, void 0, void 0, function* () {
const query = {
where: [
{
field: 'id',
where: 'and',
type: 'in',
values: categoryIds
},
{
// 'disabled' categories should not be shown to the customer
field: 'state',
where: 'and',
type: 'notEqualTo',
value: 'disabled'
}
]
};
const response = yield this.api.call({
url: '/billing/category',
method: 'GET',
headers: {
Accept: 'application/vnd.image+json',
'Accept-Response': 'Advanced'
},
query: categoryIds.length > 0 ? query : null
});
return to_rest_resource_1.toRestResource(response, 'catalog_category');
});
}
/**
* Get category by ID
*
* @param categoryId the category ID
*/
getCategoryById(categoryId) {
return __awaiter(this, void 0, void 0, function* () {
const category = yield this.api.call({
url: `/billing/category/${categoryId}`,
method: 'GET',
headers: {
'Accept-Response': 'Advanced'
}
});
if (category.state === 'disabled') {
throw new errors_1.NotFoundError('Category could not be found.');
}
// Remove "disabled" sub-categories.
// Only "active" and "hidden" should be sent to the front-end.
if (category.child) {
category.child = category.child.filter((cat) => cat.state !== 'disabled');
}
return category;
});
}
/**
* Get catalog product.
*
* @param id catalog product ID
* @param session user session
*/
getCatalogProduct(id, session) {
return __awaiter(this, void 0, void 0, function* () {
const product = yield this.api.call({
url: `/billing/product/${id}`,
method: 'GET',
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json',
'Accept-Response': 'Advanced'
},
session
});
// inactive products should not be accesed by customers
if (product.status === 'inactive') {
throw new errors_1.NotFoundError('Catalog product not found.');
}
return product;
});
}
/**
* Get catalog products by category.
*
* @param categoryId the category ID
* @param session user session
* @param subcategoryItems whether to include products from subcategories
*/
getProductsByCategory(categoryId, session, subcategoryItems) {
return __awaiter(this, void 0, void 0, function* () {
if (subcategoryItems) {
const category = yield this.getCategoryById(categoryId);
let categoryIds = [category.id];
if (category.child) {
// if a category has subcategories, fetch its children's products
// unless for child categories which are disabled
categoryIds = categoryIds.concat(category.child
.filter((child) => child.state !== 'disabled')
.map((child) => child.id));
}
return this._getProductsByCategory(categoryIds, session);
}
return this._getProductsByCategory(categoryId, session);
});
}
/**
* Get catalog products
* @param ids catalog product IDs list
* @param pagination pagination query object
* @param options options for listing products
*/
getCatalogProducts(ids, pagination = {}, options = {}, session) {
return __awaiter(this, void 0, void 0, function* () {
const filter = {
page: pagination.page || 1,
page_size: pagination.page_size || 25,
where: [
{
field: 'status',
where: 'and',
type: 'notEqualTo',
value: 'inactive'
}
]
};
if (ids && ids.length) {
filter.where.push({
field: 'product_id',
where: 'and',
type: 'in',
values: ids
});
}
const headers = {
Accept: 'application/hal+json',
'Content-Type': 'application/json'
};
if (options && Boolean(options.advanced)) {
headers['Accept-Response'] = 'Advanced';
}
if (options && Boolean(options.images)) {
headers.Accept = 'application/vnd.image+json';
}
const products = yield this.api.call({
url: `/billing/product?${qs.stringify(filter)}`,
method: 'GET',
headers,
session
});
return to_rest_resource_1.toRestResource(products, 'catalog_product');
});
}
/**
* Lists the catalog product prices for a specified set of quantities/periods.
*
* @param productId the catalog product ID
* @param quantities list of quantities for which prices will be calculated
* @param session user session
* @returns hash-map of quantity -> price relations
*/
productCalculator(productId, quantities = [], session) {
return __awaiter(this, void 0, void 0, function* () {
let body = null;
if (quantities && quantities.length) {
body = {
quantities
};
}
return this.api.call({
url: `/billing/product-calculator/${productId}`,
method: 'POST',
body,
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json'
},
session
});
});
}
/**
* Gets all Domain products.
*
* @param session user session
*/
getDomainProducts(session) {
return __awaiter(this, void 0, void 0, function* () {
const filter = qs.stringify({
where: [
{
field: 'parent_category_id',
where: 'and',
type: 'equalTo',
value: 0
},
{
field: 'layout',
where: 'and',
type: 'equalTo',
value: 'domain'
},
{
field: 'state',
where: 'and',
type: 'notEqualTo',
value: 'disabled'
}
]
});
const categories = yield this.api.call({
url: `/billing/category?${filter}`,
method: 'GET',
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json',
'Accept-Response': 'Advanced'
}
});
if (categories._embedded.catalog_category.length) {
const productsFilter = qs.stringify({
page_size: -1,
where: [
{
field: 'category_id',
where: 'and',
type: 'equalTo',
value: categories._embedded.catalog_category[0].id
},
{
field: 'status',
where: 'and',
type: 'notEqualTo',
value: 'inactive'
}
]
});
const products = yield this.api.call({
url: `/billing/product?${productsFilter}`,
method: 'GET',
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json',
'Accept-Response': 'Advanced'
},
session
});
// Parse visible_quantity field
products._embedded.catalog_product = products._embedded.catalog_product.map((product) => {
try {
product.visible_quantity = JSON.parse(product.visible_quantity);
}
catch (err) {
// do nothing...
}
return product;
});
return products._embedded.catalog_product;
}
throw new errors_1.NotFoundError('Domains category not found');
});
}
/**
* Gets all TLDs.
*/
getAllTlds(session) {
return __awaiter(this, void 0, void 0, function* () {
const domainProducts = yield this.getDomainProducts(session);
const tlds = domainProducts.map((p) => p.name);
return tlds;
});
}
/**
* Get suggested products
*
* @param id catalog product ID
* @param session user session
* @param options catalog products fetch options object
*/
getSuggestedProducts(id, session, options) {
return __awaiter(this, void 0, void 0, function* () {
const body = {
suggest: [
{
product_id: id,
quantity: 12,
item_type: 'new'
}
]
};
const suggestedProducts = yield this.api.call({
url: '/billing/product-suggest-with-type',
method: 'POST',
body,
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/json',
'Accept-Response': 'Advanced'
},
session
});
const productIds = suggestedProducts[id].map((product) => product.right_product_id);
if (!productIds.length) {
throw new errors_1.NotFoundError('There are no suggestions for this product.');
}
const products = yield this.getCatalogProducts(productIds, {}, { images: options && options.images, advanced: true }, session);
products.items.forEach((product) => {
Object.keys(product._language.translations.description).forEach((lang) => {
try {
product._language.translations.description[lang].value = JSON.parse(product._language.translations.description[lang].value);
}
catch (err) {
// do nothing
}
});
});
return products.items;
});
}
/**
* Get product suggestions
*
* @param items list of product IDs
* @param session user session
* @param visibility resource visibility string
* @param images whether to include product images
*/
getProductSuggestions(items, session, visibility, images) {
return __awaiter(this, void 0, void 0, function* () {
const body = {
suggest: items
};
if (visibility) {
body.visibility = visibility;
}
const headers = {
Accept: 'application/hal+json',
'Content-Type': 'application/json',
'Accept-Response': 'Advanced'
};
if (images) {
headers.Accept = 'application/vnd.image+json';
}
const productSuggestions = yield this.api.call({
url: '/billing/product-suggest-with-type',
method: 'POST',
body,
headers,
session
});
Object.keys(productSuggestions).forEach((key) => {
productSuggestions[key].forEach((suggestion) => {
if (suggestion.right_product._language.translations.description) {
Object.keys(suggestion.right_product._language.translations.description).forEach((lang) => {
try {
suggestion.right_product._language.translations.description[lang].value = JSON.parse(suggestion.right_product._language.translations.description[lang].value);
}
catch (err) {
// Do nothing
}
});
}
});
});
return productSuggestions;
});
}
/**
* Get product upgrades
*
* @param productId catalog product ID
* @param session user session
*/
getProductUpgrades(productId, session) {
return __awaiter(this, void 0, void 0, function* () {
const queryObj = {
where: [
{
field: 'current_product_id',
where: 'and',
type: 'equalTo',
value: productId
}
]
};
const queryString = qs.stringify(queryObj);
const productUpgradesResult = yield this.api.call({
url: `/billing/product-upgrade?${queryString}`,
method: 'GET',
session
});
const productUpgrades = to_rest_resource_1.toRestResource(productUpgradesResult, 'catalog_product_upgrade');
const productIds = productUpgrades.items.map((u) => u.upgrade_product_id);
if (!productIds || !productIds.length) {
return productUpgrades;
}
const catalogProducts = yield this.getCatalogProducts(productIds, {}, null, session);
return catalogProducts;
});
}
/**
* Get catalog products by category or by list of categories.
*
* @param categoryId category ID or a list of category IDs
* @param session user session
*/
_getProductsByCategory(categoryId, session) {
return __awaiter(this, void 0, void 0, function* () {
const query = {
page_size: -1,
where: [
{
field: 'status',
where: 'and',
type: 'notEqualTo',
value: 'disabled'
},
{
field: 'product_type',
where: 'and',
type: 'notEqualTo',
value: 'bundle'
}
]
};
if (Array.isArray(categoryId)) {
query.where.push({
field: 'category_id',
where: 'and',
type: 'in',
values: categoryId
});
}
else {
query.where.push({
field: 'category_id',
where: 'and',
type: 'equalTo',
value: categoryId.toString()
});
}
const queryString = qs.stringify(query);
const products = yield this.api.call({
url: `/billing/product?${queryString}`,
method: 'GET',
headers: {
'Accept-Response': 'Advanced'
},
session
});
const restResponse = to_rest_resource_1.toRestResource(products, 'catalog_product');
restResponse.items.forEach((i) => {
const translations = Object.assign({}, i._language.translations);
i._language.translations = parse_product_translations_1.default(translations);
});
return restResponse;
});
}
}
exports.BilliaSDKCatalog = BilliaSDKCatalog;