@tomei/live-price
Version:
Tomei live-price Package
480 lines • 23.6 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
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) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TomeiPriceHistory = void 0;
const general_1 = require("@tomei/general");
const log_1 = require("@tomei/log");
const tomei_price_repository_1 = require("./tomei-price.repository");
const tomei_price_latest_repository_1 = require("./tomei-price-latest.repository");
const sequelize_1 = require("sequelize");
const price_feed_history_entity_1 = require("../../models/price-feed-history.entity");
const feed_manual_price_history_1 = require("../feed-manual-price-history/feed-manual-price-history");
const feed_1 = require("../feed/feed");
const feed_enum_1 = require("../../enum/feed.enum");
const company_feed_access_1 = require("../company-feed-access/company-feed-access");
class TomeiPriceHistory extends general_1.ObjectBase {
get TomeiPriceHistoryId() {
return this.ObjectId;
}
set TomeiPriceHistoryId(value) {
this.ObjectId = value;
}
constructor(tomeiPriceHistoryAttr) {
super();
if (tomeiPriceHistoryAttr) {
this.TomeiPriceHistoryId = tomeiPriceHistoryAttr.TomeiPriceHistoryId;
this.FeedHistoryId = tomeiPriceHistoryAttr.FeedHistoryId;
this.FeedName = tomeiPriceHistoryAttr.FeedName;
this.DateTime = tomeiPriceHistoryAttr.DateTime;
this.AdjustBuyPercentage = tomeiPriceHistoryAttr.AdjustBuyPercentage;
this.AdjustSellPercentage = tomeiPriceHistoryAttr.AdjustSellPercentage;
this.TomeiBuyPrice = tomeiPriceHistoryAttr.TomeiBuyPrice;
this.TomeiSellPrice = tomeiPriceHistoryAttr.TomeiSellPrice;
this.AdjustedById = tomeiPriceHistoryAttr.AdjustedById;
this.Currency = tomeiPriceHistoryAttr.Currency;
this.AdjustedDateTime = tomeiPriceHistoryAttr.AdjustedDateTime;
this.IsManualPriceActivatedYN =
tomeiPriceHistoryAttr.IsManualPriceActivatedYN;
this.BuyLabourCharges = tomeiPriceHistoryAttr.BuyLabourCharges;
this.SellLabourCharges = tomeiPriceHistoryAttr.SellLabourCharges;
this.CompanyCode = tomeiPriceHistoryAttr.CompanyCode;
}
}
static init(dbTransaction, tomeiPriceHistoryId) {
return __awaiter(this, void 0, void 0, function* () {
try {
if (tomeiPriceHistoryId) {
const data = yield TomeiPriceHistory._Repo.findByPk(tomeiPriceHistoryId, dbTransaction);
if (data) {
return new TomeiPriceHistory(data);
}
else {
const error = new general_1.ClassError('TomeiPriceHistory', 'TomeiPriceHistoryErrMsg00', 'TomeiPriceHistory Not Found');
yield TomeiPriceHistory.logger.error({
error,
methodName: 'init',
transaction: dbTransaction,
});
throw error;
}
}
return new TomeiPriceHistory();
}
catch (error) {
yield TomeiPriceHistory.logger.error({
error,
methodName: 'init',
transaction: dbTransaction,
});
throw new general_1.ClassError('TomeiPriceHistory', 'TomeiPriceHistoryErrMsg00', 'TomeiPriceHistory To Initialize FeedHistory');
}
});
}
saveTomeiPrice(feedName_1, feedHistory_1, loginUser_1, adjustmentPercentage_1, manualPrice_1) {
return __awaiter(this, arguments, void 0, function* (feedName, feedHistory, loginUser, adjustmentPercentage, manualPrice, companyCode = 'CTH', dbTransaction) {
try {
if (!feedHistory || !feedHistory.FeedHistoryId) {
const error = new general_1.ClassError('TomeiPriceHistory', 'TomeiPriceHistoryErrMsg01', 'FeedHistoryId is required to create tomei price');
yield TomeiPriceHistory.logger.error({
error,
methodName: 'saveTomeiPrice',
transaction: dbTransaction,
});
throw error;
}
let adjustmentBy = null;
let adjustmentDateTime = new Date();
const latestPrice = yield TomeiPriceHistory.getLatestPrice(feedName, feedHistory.Currency, companyCode, undefined, dbTransaction);
if (!adjustmentPercentage) {
if (!latestPrice) {
adjustmentPercentage = {
adjustBuyPercentage: 0,
adjustSellPercentage: 0,
buyLabourCharges: 0,
sellLabourCharges: 0,
};
}
else {
adjustmentPercentage = {
adjustBuyPercentage: latestPrice.AdjustBuyPercentage,
adjustSellPercentage: latestPrice.AdjustSellPercentage,
buyLabourCharges: latestPrice.BuyLabourCharges,
sellLabourCharges: latestPrice.SellLabourCharges,
};
adjustmentBy = latestPrice.AdjustedById;
adjustmentDateTime = latestPrice.AdjustedDateTime;
}
}
else if (!loginUser && adjustmentPercentage) {
const error = new general_1.ClassError('TomeiPriceHistory', 'TomeiPriceHistoryErrMsg01', 'Login user is required to create tomei price when updating adjustment buy and sell percentage');
yield TomeiPriceHistory.logger.error({
error,
methodName: 'saveTomeiPrice',
transaction: dbTransaction,
});
throw error;
}
const priceResult = yield this.calculateTomeiPrices(feedName, feedHistory, adjustmentPercentage, companyCode, manualPrice, latestPrice, dbTransaction);
const { tomeiBuyPrice, tomeiSellPrice, IsManualPriceActivatedYN } = priceResult;
const payload = {
TomeiPriceHistoryId: this.createId(),
FeedHistoryId: feedHistory.FeedHistoryId,
FeedName: feedName,
DateTime: new Date(),
Currency: feedHistory.Currency,
AdjustBuyPercentage: adjustmentPercentage.adjustBuyPercentage,
AdjustSellPercentage: adjustmentPercentage.adjustSellPercentage,
TomeiBuyPrice: tomeiBuyPrice,
TomeiSellPrice: tomeiSellPrice,
AdjustedById: loginUser ? loginUser.ObjectId : adjustmentBy,
AdjustedDateTime: adjustmentDateTime,
IsManualPriceActivatedYN: IsManualPriceActivatedYN,
BuyLabourCharges: adjustmentPercentage.buyLabourCharges,
SellLabourCharges: adjustmentPercentage.sellLabourCharges,
CompanyCode: companyCode,
};
const tomeiPriceHistory = yield TomeiPriceHistory._Repo.create(payload, {
transaction: dbTransaction,
});
if (tomeiPriceHistory) {
yield TomeiPriceHistory.upsertTomeiPriceLatest(payload, dbTransaction);
return new TomeiPriceHistory(tomeiPriceHistory);
}
else {
const error = new general_1.ClassError('TomeiPriceHistory', 'TomeiPriceHistoryErrMsg01', 'TomeiPriceHistory To Save TomeiPrice');
throw error;
}
}
catch (error) {
yield TomeiPriceHistory.logger.error({
error,
methodName: 'saveTomeiPrice',
transaction: dbTransaction,
});
throw error;
}
});
}
static upsertTomeiPriceLatest(payload, dbTransaction) {
return __awaiter(this, void 0, void 0, function* () {
try {
const latestPayload = {
FeedName: payload.FeedName,
TomeiPriceHistoryId: payload.TomeiPriceHistoryId,
Currency: payload.Currency,
CompanyCode: payload.CompanyCode,
DateTime: payload.DateTime,
AdjustBuyPercentage: payload.AdjustBuyPercentage,
AdjustSellPercentage: payload.AdjustSellPercentage,
TomeiBuyPrice: payload.TomeiBuyPrice,
TomeiSellPrice: payload.TomeiSellPrice,
AdjustedById: payload.AdjustedById,
AdjustedDateTime: payload.AdjustedDateTime,
UpdatedAt: new Date(),
};
const existingRecord = yield TomeiPriceHistory._LatestRepo.findOne({
where: {
FeedName: payload.FeedName,
Currency: payload.Currency,
},
transaction: dbTransaction,
});
if (existingRecord) {
yield TomeiPriceHistory._LatestRepo.update(latestPayload, {
where: {
FeedName: payload.FeedName,
Currency: payload.Currency,
},
transaction: dbTransaction,
});
}
else {
yield TomeiPriceHistory._LatestRepo.create(latestPayload, {
transaction: dbTransaction,
});
}
}
catch (error) {
yield TomeiPriceHistory.logger.error({
error,
methodName: 'upsertTomeiPriceLatest',
transaction: dbTransaction,
});
throw error;
}
});
}
calculateTomeiPrices(feedName, feedHistory, adjustmentPercentage, companyCode, manualPrice, latestPrice, dbTransaction) {
return __awaiter(this, void 0, void 0, function* () {
if (manualPrice) {
return this.applyManualPrice(manualPrice);
}
const feedManualPrice = yield this.getFeedManualPrice(feedName, companyCode, dbTransaction);
if (feedManualPrice) {
return this.applyFeedManualPrice(feedManualPrice, latestPrice);
}
return yield this.calculatePriceFromFeed(feedName, feedHistory, adjustmentPercentage, companyCode, dbTransaction);
});
}
applyManualPrice(manualPrice) {
return {
tomeiBuyPrice: manualPrice.buyPrice,
tomeiSellPrice: manualPrice.sellPrice,
IsManualPriceActivatedYN: 'Y',
};
}
getFeedManualPrice(feedName, companyCode, dbTransaction) {
return __awaiter(this, void 0, void 0, function* () {
const feedManualPrice = yield feed_manual_price_history_1.FeedManualPriceHistory.findAll(1, 1, Object.assign({ FeedName: feedName, Status: feed_enum_1.ManualPriceStatus.ACTIVE }, (companyCode && { CompanyCode: companyCode })), dbTransaction);
return feedManualPrice.count > 0 ? feedManualPrice.rows[0] : null;
});
}
applyFeedManualPrice(feedManualPrice, latestPrice) {
var _a, _b, _c, _d;
return {
tomeiBuyPrice: (_b = (_a = feedManualPrice.BuyPrice) !== null && _a !== void 0 ? _a : latestPrice === null || latestPrice === void 0 ? void 0 : latestPrice.TomeiBuyPrice) !== null && _b !== void 0 ? _b : 0,
tomeiSellPrice: (_d = (_c = feedManualPrice.SellPrice) !== null && _c !== void 0 ? _c : latestPrice === null || latestPrice === void 0 ? void 0 : latestPrice.TomeiSellPrice) !== null && _d !== void 0 ? _d : 0,
IsManualPriceActivatedYN: 'Y',
};
}
calculatePriceFromFeed(feedName, feedHistory, adjustmentPercentage, companyCode, dbTransaction) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (feedHistory.FeedBuyPrice <= 0 || feedHistory.FeedSellPrice <= 0) {
return {
tomeiBuyPrice: 0,
tomeiSellPrice: 0,
IsManualPriceActivatedYN: 'N',
};
}
const feed = yield feed_1.Feed.init(dbTransaction, feedName);
const weight = (_a = feed.Weight) !== null && _a !== void 0 ? _a : 0;
const pricingLogic = yield company_feed_access_1.CompanyFeedAccess.getPricingLogic(dbTransaction, feedName, companyCode);
return this.applyPricingLogic(feedHistory, weight, adjustmentPercentage, pricingLogic);
});
}
applyPricingLogic(feedHistory, weight, adjustmentPercentage, pricingLogic) {
if (pricingLogic === feed_enum_1.PricingLogic.BUY_BUY_SELL) {
return {
tomeiBuyPrice: feedHistory.FeedBuyPrice *
weight *
(1 + adjustmentPercentage.adjustBuyPercentage / 100) +
adjustmentPercentage.buyLabourCharges,
tomeiSellPrice: feedHistory.FeedSellPrice *
weight *
(1 + adjustmentPercentage.adjustSellPercentage / 100) +
adjustmentPercentage.sellLabourCharges,
IsManualPriceActivatedYN: 'N',
};
}
else {
return {
tomeiBuyPrice: feedHistory.FeedSellPrice *
weight *
(1 + adjustmentPercentage.adjustBuyPercentage / 100) +
adjustmentPercentage.buyLabourCharges,
tomeiSellPrice: feedHistory.FeedSellPrice *
weight *
(1 + adjustmentPercentage.adjustSellPercentage / 100) +
adjustmentPercentage.sellLabourCharges,
IsManualPriceActivatedYN: 'N',
};
}
}
static getLatestPrice(feedName_1, currency_1) {
return __awaiter(this, arguments, void 0, function* (feedName, currency, companyCode = 'CTH', timestamp, dbTransaction) {
var _a, _b;
try {
if (timestamp) {
return yield TomeiPriceHistory.getClosestHistoricalPrice(feedName, currency, companyCode, timestamp, dbTransaction);
}
const latestPrice = yield TomeiPriceHistory.getFromLatestTable(feedName, currency, companyCode, dbTransaction);
if (latestPrice)
return latestPrice;
const historicalPrice = yield TomeiPriceHistory.getMostRecentHistoricalPrice(feedName, currency, companyCode, dbTransaction);
if (!historicalPrice) {
return null;
}
return historicalPrice;
}
catch (error) {
yield log_1.ApplicationLog.warning({
message: 'Non-critical error in getLatestPrice, returning null',
details: {
error: error.message,
feedName,
currency,
companyCode,
timestamp,
},
source: 'live-price',
className: 'TomeiPriceHistory',
methodName: 'getLatestPrice',
transaction: dbTransaction,
});
if (error.name === 'SequelizeConnectionError' ||
error.name === 'SequelizeDatabaseError' ||
((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('connection')) ||
((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('database'))) {
const classError = new general_1.ClassError('TomeiPriceHistory', 'DatabaseConnectionError', `Database error while retrieving latest price: ${error.message}`);
yield TomeiPriceHistory.logger.error({
error,
methodName: 'getLatestPrice',
transaction: dbTransaction,
});
throw classError;
}
return null;
}
});
}
static getLatestPriceRequired(feedName_1, currency_1) {
return __awaiter(this, arguments, void 0, function* (feedName, currency, companyCode = 'CTH', timestamp, dbTransaction) {
const latestPrice = yield TomeiPriceHistory.getLatestPrice(feedName, currency, companyCode, timestamp, dbTransaction);
if (!latestPrice) {
const error = new general_1.ClassError('TomeiPriceHistory', 'NoDataFoundError', `No price data found for feed ${feedName}, currency ${currency}, company ${companyCode}`);
yield TomeiPriceHistory.logger.error({
error,
methodName: 'getLatestPriceRequired',
transaction: dbTransaction,
});
throw error;
}
return latestPrice;
});
}
static getClosestHistoricalPrice(feedName, currency, companyCode, timestamp, dbTransaction) {
return __awaiter(this, void 0, void 0, function* () {
try {
const options = {
where: {
FeedName: feedName,
Currency: currency,
CompanyCode: companyCode,
},
order: [
[
sequelize_1.Sequelize.literal(`ABS(TIMESTAMPDIFF(SECOND, DateTime, '${timestamp.toISOString()}'))`),
'ASC',
],
],
limit: 1,
transaction: dbTransaction,
};
return yield TomeiPriceHistory._Repo.findOne(options);
}
catch (error) {
return null;
}
});
}
static getFromLatestTable(feedName, currency, companyCode, dbTransaction) {
return __awaiter(this, void 0, void 0, function* () {
try {
const latestPrice = yield TomeiPriceHistory._LatestRepo.findOne({
where: {
FeedName: feedName,
Currency: currency,
CompanyCode: companyCode,
},
transaction: dbTransaction,
});
if (!latestPrice)
return null;
const tomeiPrice = yield TomeiPriceHistory.init(dbTransaction, latestPrice.TomeiPriceHistoryId);
return {
TomeiPriceHistoryId: latestPrice.TomeiPriceHistoryId,
FeedHistoryId: tomeiPrice.FeedHistoryId,
FeedName: latestPrice.FeedName,
Currency: latestPrice.Currency,
DateTime: latestPrice.DateTime,
AdjustBuyPercentage: latestPrice.AdjustBuyPercentage,
AdjustSellPercentage: latestPrice.AdjustSellPercentage,
TomeiBuyPrice: latestPrice.TomeiBuyPrice,
TomeiSellPrice: latestPrice.TomeiSellPrice,
AdjustedById: latestPrice.AdjustedById,
AdjustedDateTime: latestPrice.AdjustedDateTime,
IsManualPriceActivatedYN: tomeiPrice.IsManualPriceActivatedYN,
BuyLabourCharges: tomeiPrice.BuyLabourCharges,
SellLabourCharges: tomeiPrice.SellLabourCharges,
CompanyCode: latestPrice.CompanyCode,
};
}
catch (error) {
return null;
}
});
}
static getMostRecentHistoricalPrice(feedName, currency, companyCode, dbTransaction) {
return __awaiter(this, void 0, void 0, function* () {
try {
const options = {
where: {
FeedName: feedName,
Currency: currency,
CompanyCode: companyCode,
},
order: [['DateTime', 'DESC']],
limit: 1,
transaction: dbTransaction,
};
return yield TomeiPriceHistory._Repo.findOne(options);
}
catch (error) {
return null;
}
});
}
static findAll(page, row, feedName, search, dbTransaction) {
return __awaiter(this, void 0, void 0, function* () {
try {
const queryObj = {
FeedName: feedName,
};
const options = {
transaction: dbTransaction,
limit: row,
offset: row * (page - 1),
order: [['DateTime', 'DESC']],
include: [
{
model: price_feed_history_entity_1.default,
},
],
};
if (search) {
if (search.DateTime) {
queryObj.DateTime = {
[sequelize_1.Op.between]: [search.DateTime.startDate, search.DateTime.endDate],
};
}
if (search.CompanyCode) {
queryObj.CompanyCode = search.CompanyCode;
}
}
return yield TomeiPriceHistory._Repo.findAllWithPagination(Object.assign({ where: queryObj }, options));
}
catch (error) {
yield TomeiPriceHistory.logger.error({
error,
methodName: 'findAll',
transaction: dbTransaction,
});
throw error;
}
});
}
}
exports.TomeiPriceHistory = TomeiPriceHistory;
TomeiPriceHistory.logger = new log_1.ApplicationLog('live-price', 'TomeiPriceHistory');
TomeiPriceHistory._Repo = new tomei_price_repository_1.TomeiPriceHistoryRepository();
TomeiPriceHistory._LatestRepo = new tomei_price_latest_repository_1.TomeiPriceLatestRepository();
//# sourceMappingURL=tomei-price.js.map