UNPKG

wistroni40-bnft

Version:

Benefit platform parameters publish job template

260 lines (259 loc) 8.68 kB
"use strict"; /** * 專案名稱: @wistroni40/bnft * 部門代號: ML8100 * 檔案說明: 抽象效益計算範本 * @CREATE Thu Jan 21 2021 下午1:44:54 * @author Steve Y Lin * @contact Steve_Y_Lin@wistron.com #1342 * ----------------------------------------------------------------------------- * @NOTE */ Object.defineProperty(exports, "__esModule", { value: true }); exports.BnftTemplate = void 0; const axios_1 = require("axios"); const schedule = require("node-schedule"); const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const api_1 = require("./../api"); const http_1 = require("./../http"); const logger_1 = require("./../logger"); const retry_1 = require("./../retry"); const utils_1 = require("./../utils"); const api_2 = require("./api"); const models_1 = require("./api/models"); const classes_1 = require("./classes"); const models_2 = require("./models"); /** * 抽象效益計算範本 */ class BnftTemplate { /** * @param config 效益設定檔 */ constructor(config) { this.config = config; /** * 日誌 */ this.console = new logger_1.Log4js('bnft'); /** * API服務器 */ this.apiServer = api_1.Server.instance.register(this); /** * HTTP請求 */ this.http = new http_1.AxiosHttpService(axios_1.default); /** * 效益激活系統服務 */ this.activedSystemService = new api_2.BenefitActivedSystemService(this.http); /** * 效益DL及IDL人員工時服務 */ this.benefitLaborCostService = new api_2.BenefitLaborCostService(this.http); /** * 排程設定 */ this.cron = null; this.config = new models_2.BenefitConfigEntity(this.config); api_2.ApiConfig.path = this.config.benefitApi; this.producer = new retry_1.HttpProducer(this.http, { count: this.config.retry, interval: this.config.retryInterval, }); this.sendCompleted = this.producer.sendCompleted; } /** * 取得預設的效益參數資料 * * @method private * @return 回傳預設的效益參數資料 */ getDefaultProcucePayload() { return rxjs_1.of(new retry_1.ProducePayloadEntity(this.config.publishApi, new models_2.BenefitSavingEntity())); } /** * 建構效益參數實體 * * @method protected * @param timestamp 資料時間戳 * @param condition 效益查詢條件 * @param params 效益參數 */ buildBenefitEntity(timestamp, condition, params) { return new models_2.BenefitSavingEntity({ evt_dt: timestamp.getTime(), freq: 'D', site: condition.site, company: condition.company, plant: condition.plant, plant_code: condition.plantCode, system_id: this.config.systemId, type_id: this.config.typeId, benefit_type: this.config.benefitType, params, }); } /** * 建構查詢激活系統的查詢條件 * * @method protected * @return 回傳查詢條件 */ buildQueryActivatedSystemsFilter() { return { include: 'benefitPlant', where: { system_id: this.config.systemId }, }; } /** * 查詢效益參數 * * @method protected * @param plant 廠別資料作為查詢條件 * @param timestamp 查詢開始時間 * @return 回傳效益參數 */ queryBenefit(plant, timestamp) { const start = utils_1.TimeManager.getStartTime(timestamp); const end = utils_1.TimeManager.getEndTime(timestamp); const condition = new classes_1.BenefitQueryConvertor(plant) .setStartTime(start) .setEndTime(end) .build(); return this.buildPayload(start, condition); } /** * 設定查詢用的HTTP * * @method public * @param http HTTP請求 * @return 回傳物件本身 */ setHttp(http) { this.http = http; this.activedSystemService = new api_2.BenefitActivedSystemService(this.http); return this; } /** * 設定排程計算效益 * * @method public * @param cron 排程 * @return 回傳物件本身 */ setSchedule(cron) { this.cron = cron; if (this.cron) { schedule.scheduleJob(this.cron, this.execute.bind(this)); } return this.sendCompleted; } /** * 過濾無須或異常的廠別 * * @method public * @param plant 廠別資料 * @return 回傳該廠別是否要保留 */ filterPlant(plant) { const isNotUndefined = plant !== undefined; let isAllowedPlant = true; if (plant && this.enabledPlant && this.enabledPlant.length > 0) { isAllowedPlant = this.enabledPlant.includes(plant.plantcode); } return isNotUndefined && isAllowedPlant; } /** * 建構效益參數資料 * * @method public * @param timestamp 資料時間戳 * @param condition 效益查詢條件 * @return 回傳效益參數資料 */ buildPayload(timestamp, condition) { return rxjs_1.from(this.getBenefitParams(condition)).pipe(operators_1.map(params => this.buildBenefitEntity(timestamp, condition, params))); } /** * 處理效益參數 * * @method public * @param response 查詢激活的效益系統 * @param timestamp 查詢開始時間 * @return 回傳處理後效益參數 */ processBenefitParams(response, timestamp) { return response.pipe( // 取出HTTP回應的資料 operators_1.map(res => res.data), // 從系統資料中取出廠別資料 operators_1.map(systems => systems.map(system => system.benefitPlant)), // 將廠別資料重新建成Subject operators_1.map(plants => rxjs_1.from(plants)), // 將廠別打散成單筆數據 operators_1.concatAll(), // 保留需要計算及無異常的廠別 operators_1.filter(plant => this.filterPlant(plant)), // 查詢效益參數 operators_1.map(plant => this.queryBenefit(plant, timestamp)), // 將效益參數打散成單筆數據 operators_1.concatAll(), // 打包成拋送的資料格式 operators_1.map(benefit => new retry_1.ProducePayloadEntity(this.config.publishApi, benefit)), // 發生錯誤給定預設值 operators_1.catchError(() => this.getDefaultProcucePayload())); } /** * 執行效益參數撈取 * * @method public * @param timestamp 查詢開始時間 * @return 回傳效益參數上拋結果 */ execute(timestamp) { const dev = this.config.dev; const query = this.buildQueryActivatedSystemsFilter(); const system$ = this.activedSystemService.find(query); const param$ = this.processBenefitParams(system$, timestamp); param$.subscribe(payload => this.send(payload, !dev)); return this.sendCompleted; } /** * 將效益參數上拋 * * @method public * @param payload 效益參數 * @param sendable 效益參數是否上拋 */ async send(payload, sendable = true) { if (sendable) { this.producer.publish(payload); } else { this.console.debug(JSON.stringify(payload)); this.sendCompleted.next({ error: null, result: payload }); } } /** * 取得最新的IDL或ID人員工時 * * @method public * @param site Site * @param plantCode 廠別代碼 * @param laborType 人員類別(IDL or DL) * @return 回傳最新的IDL或ID人員工時 */ findLatestLaborCost(site, plantCode, type) { return this.benefitLaborCostService .getLatestCost(site, plantCode, type) .pipe( // 將工時資料取出 operators_1.map(response => response.data), // 發生錯誤給定預設值 operators_1.catchError(() => rxjs_1.of(new models_1.BenefitLatestLaborCostEntity({ site, plant: plantCode, type })))); } } exports.BnftTemplate = BnftTemplate;