'use strict'; /** * 期计量 数据模型 * * @author Mai * @date 2018/8/13 * @version */ const auditConst = require('../const/audit').material; const materialConst = require('../const/material'); const MaterialCalculator = require('../lib/material_calc'); module.exports = app => { class MaterialExponent extends app.BaseService { /** * 构造函数 * * @param {Object} ctx - egg全局变量 * @return {void} */ constructor(ctx) { super(ctx); this.tableName = 'material_exponent'; } /** * 添加指数清单 * @return {void} */ async add() { if (!this.ctx.tender || !this.ctx.material) { throw '数据错误'; } const transaction = await this.db.beginTransaction(); try { const newExponent = { tid: this.ctx.tender.id, mid: this.ctx.material.id, in_time: new Date(), }; // 新增工料 const result = await transaction.insert(this.tableName, newExponent); if (result.affectedRows !== 1) { throw '新增指数数据失败'; } await transaction.commit(); return await this.getDataById(result.insertId); } catch (error) { console.log(error); await transaction.rollback(); throw error; } } /** * 删除指数清单 * @param {int} id 工料id * @return {void} */ async del(id) { if (!this.ctx.tender || !this.ctx.material) { throw '数据错误'; } // 判断t_type是否为费用,且存在quantity,m_spread值 const transaction = await this.db.beginTransaction(); try { const meInfo = await this.getDataById(id); await transaction.delete(this.tableName, { id }); if (meInfo.weight_num === null) { await transaction.delete(this.ctx.service.materialExponentHistory.tableName, { mid: id }); } let ex_tp = this.ctx.material.ex_tp; let ex_expr = this.ctx.material.ex_expr; if (meInfo.is_summary === materialConst.is_summary.yes) { // 金额发生变化,则重新计算本期金额 [ex_tp, ex_expr] = await this.ctx.service.materialExponent.calcMaterialExTp(transaction); } await transaction.commit(); return [ex_tp, ex_expr]; } catch (err) { await transaction.rollback(); throw err; } } /** * 修改指数清单信息 * @param {Object} data 工料内容 * @return {void} */ async save(data) { if (!this.ctx.tender || !this.ctx.material) { throw '数据错误'; } delete data.in_time; // delete data.m_tp; // 判断是否可修改 // 判断t_type是否为费用 const transaction = await this.db.beginTransaction(); try { await transaction.update(this.tableName, data); const [ex_tp, ex_expr] = await this.calcMaterialExTp(transaction); await transaction.commit(); return [ex_tp, ex_expr]; } catch (err) { await transaction.rollback(); throw err; } } /** * 复制粘贴指数清单 * @param {Object} data 工料内容 * @return {void} */ async saveDatas(datas) { if (!this.ctx.tender || !this.ctx.material) { throw '数据错误'; } // 判断是否可修改 // 判断t_type是否为费用 const transaction = await this.db.beginTransaction(); try { await transaction.updateRows(this.tableName, datas); const [ex_tp, ex_expr] = await this.calcMaterialExTp(transaction); await transaction.commit(); return [ex_tp, ex_expr]; } catch (err) { await transaction.rollback(); throw err; } } /** * 旧数据补充定值和历史数据 * @returns {Promise} */ async addOldData() { if (!this.ctx.tender || !this.ctx.material) { throw '数据错误'; } const transaction = await this.db.beginTransaction(); try { // 先获取第一期的mid const first_material = await this.ctx.service.material.getDataByCondition({ tid: this.ctx.tender.id, order: 1, }); const insert_data = { tid: this.ctx.tender.id, mid: first_material.id, type: materialConst.ex_type[0].value, symbol: 'X', symbol_desc: '非可调因子', code: 'A', weight_num: 0, is_summary: materialConst.is_summary.yes, in_time: new Date(), }; const result = await transaction.insert(this.tableName, insert_data); // 获取最新期数据 const high_material = await this.ctx.service.material.getDataByCondition({ tid: this.ctx.tender.id, order: this.ctx.material.highOrder, }); const qi_order = high_material.status === auditConst.status.uncheck || high_material.status === auditConst.status.checkNo ? high_material.order - 1 : high_material; const insert_history_data = []; for (let i = 1; i <= qi_order; i++) { const one_insert = { tid: this.ctx.tender.id, mid: first_material.id, order: i, me_id: result.insertId, type: materialConst.ex_type[0].value, weight_num: 0, is_summary: materialConst.is_summary.yes, }; insert_history_data.push(one_insert); } if (insert_history_data.length > 0) await transaction.insert(this.ctx.service.materialExponentHistory.tableName, insert_history_data); await transaction.commit(); } catch (err) { await transaction.rollback(); throw err; } } // 更改计算总指数金额并返回值和公式 async calcMaterialExTp(transaction, ex_calc = (this.ctx.material.ex_calc ? JSON.parse(this.ctx.material.ex_calc) : null), mid = null, decimal = (this.ctx.material.decimal ? this.ctx.material.decimal : materialConst.decimal)) { let basic_calc = 0; if (ex_calc) { for (const calc of ex_calc) { if (calc.select) { basic_calc = this.ctx.helper.add(basic_calc, calc.value); } } } let expr = basic_calc + '*['; const exponentList = await transaction.select(this.tableName, { where: { tid: this.ctx.tender.id, is_summary: materialConst.is_summary.yes } }); let sumByChange = 0; let constant = 0; for (const ex of exponentList) { if (ex.type === materialConst.ex_type[0].value) { constant = ex.weight_num ? ex.weight_num : 0; expr += constant.toString(); } else if (ex.type === materialConst.ex_type[1].value) { const change = ex.calc_num ? ex.calc_num : 0; expr = expr + (change !== 0 ? '+' + ex.weight_num.toString() + '*(' + ex.m_price.toString() + '/' + ex.basic_price.toString() + ')' : ''); sumByChange = this.ctx.helper.add(sumByChange, change); } } expr += '-1]'; expr = constant !== 0 ? expr : null; const ex_tp = constant !== 0 ? this.ctx.helper.round(this.ctx.helper.mul(basic_calc, this.ctx.helper.sub(this.ctx.helper.add(constant, sumByChange), 1)), decimal.tp) : null; await transaction.update(this.ctx.service.material.tableName, { id: mid ? mid : this.ctx.material.id, ex_tp, ex_expr: expr, }); console.log(ex_tp, expr); return [ex_tp, expr]; } /** * 更新新一期的现行价格指数,并返回指数总金额和公式 * @param transaction * @param tid * @param mid * @returns {Promise} */ async updateNewMaterial(transaction, mid, ctx, stage_id, ex_calc, decimal) { const stage_list = await ctx.service.stage.getStageMsgByStageId(stage_id); const calcBase = await ctx.service.stage.getMaterialCalcBase(stage_list, ctx.tender.info); const old_ex_calc = ex_calc ? JSON.parse(ex_calc) : null; const new_ex_calc = materialConst.ex_calc; for (const bq of new_ex_calc) { const calc = this._.find(calcBase, { code: bq.code }) || this._.find(calcBase, { code: 'bqwc' }); const oldcalc = old_ex_calc ? this._.find(old_ex_calc, { code: bq.code }) : null; bq.value = calc.value; bq.select = oldcalc ? oldcalc.select : false; } await this.calcMaterialExTp(transaction, new_ex_calc, mid, decimal); return new_ex_calc; } } return MaterialExponent; };