@megaads/wm
Version:
To install the library, use npm:
149 lines (131 loc) • 5.07 kB
text/typescript
import { PriceChangeFilter, Money, FlashSaleData } from "./types";
class PriceChangeService {
readonly flashSalePercent: number;
constructor() {
this.flashSalePercent = 30;
}
/**
* Decorates items with price changes based on tracking history
* @param items - Array of items to decorate
* @param options - Configuration options
*/
public decor(items: any[], options: any) {
if (items && items.length > 0) {
const filter = this.buildFilter(options);
items.forEach((item) => {
const pId = this.getByCol(item, filter.pIdCol);
if (!pId) {
return;
}
if (filter.decorMoney) {
this.decorItem(item, filter.decorMoney, filter.columns);
console.log(item);
}
this.decorItemFlashSale(item, filter.columns, filter);
});
}
}
/**
* Builds filter options from provided options
* @param options - Configuration options
* @returns Filter options
*/
protected buildFilter(options: any): PriceChangeFilter {
const columns = options.columns || ["price", "high_price"];
const pIdCol = options.pIdCol || "id";
const flashSaleData = options.flashSaleData;
const decorMoney = options.decorMoney;
const result: PriceChangeFilter = {
columns,
pIdCol,
flashSaleData,
decorMoney,
};
return result;
}
/**
* Decorates a single item
* @param item - Item to decorate
* @param money - Money to apply
* @param columns - Columns to update
*/
public decorItem(item: any, money: Money, columns: string[] = ["price", "high_price"]) {
columns.forEach((column) => {
const value = this.getByCol(item, column);
if (!value || value < 1) {
return;
}
let newValue = value;
if (money.type === "replace") {
newValue = money.value;
} else if (money.type === "add") {
newValue += money.value;
} else if (money.type === "percent") {
newValue *= money.value;
newValue = Math.round(newValue * 100) / 100;
}
if (item[column] !== undefined) {
item[column] = newValue;
}
});
}
/**
* Decorates a flash sale item
* @param item - Item to decorate
* @param columns - Columns to update
* @param filter - Filter options
*/
public decorItemFlashSale(item: any, columns: string[] = ["high_price"], filter: PriceChangeFilter) {
columns.forEach((column) => {
if (column === "high_price") {
const flashSaleData = this.decorFlashSaleHighPrice(item, filter);
if (flashSaleData.is_flash_sale && flashSaleData.high_price) {
this.decorItem(item, { type: "replace", value: flashSaleData.high_price }, [column]);
item.flash_sale_data = {
is_flash_sale: 1,
end_at: flashSaleData.end_at,
sale_percent: flashSaleData.sale_percent,
high_price: flashSaleData.high_price,
}
}
}
});
}
/**
* Decorates flash sale high price
* @param item - Item to decorate
* @param column - Column to update
* @param filter - Filter options
* @returns Flash sale data
*/
protected decorFlashSaleHighPrice(item: any, filter: PriceChangeFilter): FlashSaleData {
const result: FlashSaleData = {
is_flash_sale: false,
};
if (filter.flashSaleData && filter.flashSaleData.sale_percent) {
const flashSale = filter.flashSaleData;
const percentFlashSale = flashSale.sale_percent || this.flashSalePercent;
const price = this.getByCol(item, "price");
let highPrice = Math.round((price / (100 - percentFlashSale)) * 100 * 100) / 100;
const fee = this.getByCol(item, "fee");
if (fee && fee > 0) {
highPrice = Math.round(((price - fee) / (100 - percentFlashSale)) * 100 + fee * 100) / 100;
}
result.is_flash_sale = true;
result.end_at = flashSale.end_at || undefined;
result.sale_percent = percentFlashSale;
result.high_price = highPrice;
return result;
}
return result;
}
protected getByCol(item: any, column: string) {
let val = null;
if (item && item[column]) {
val = item[column];
}
return val;
}
}
// Export a singleton instance
export default PriceChangeService;