| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- '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');
- const needUpdateArray = ['weight_num', 'm_price', 'remark'];
- module.exports = app => {
- class MaterialExponentShard extends app.BaseService {
- /**
- * 构造函数
- *
- * @param {Object} ctx - egg全局变量
- * @return {void}
- */
- constructor(ctx) {
- super(ctx);
- this.tableName = 'material_exponent_shard';
- }
- /**
- * 添加指数清单
- * @return {void}
- */
- async add(transaction, material, id, remark = null) {
- const materialStages = material.is_stage_self ? await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: material.id } }) : [];
- const materialNodes = material.exponent_node ? await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: material.id } }) : [];
- const insertDatas = [];
- const copyInsertData = {
- tid: this.ctx.tender.id,
- mid: material.id,
- me_id: id,
- };
- if (remark) copyInsertData.remark = remark;
- if (materialStages.length > 0) {
- for (const ms of materialStages) {
- if (materialNodes.length > 0) {
- const stageNodes = this._.filter(materialNodes, { ms_id: ms.id });
- for (const mn of stageNodes) {
- const insertData = this._.cloneDeep(copyInsertData);
- insertData.ms_id = ms.id;
- insertData.mn_id = mn.id;
- insertDatas.push(insertData);
- }
- } else {
- const insertData = this._.cloneDeep(copyInsertData);
- insertData.ms_id = ms.id;
- insertDatas.push(insertData);
- }
- }
- } else if (materialStages.length === 0 && materialNodes.length > 0) {
- for (const mn of materialNodes) {
- const insertData = this._.cloneDeep(copyInsertData);
- insertData.mn_id = mn.id;
- insertDatas.push(insertData);
- }
- }
- if (insertDatas.length > 0) await transaction.insert(this.tableName, insertDatas);
- }
- // 单个修改工料时同步修改
- async update(transaction, data, ms_id = null, mn_id = null, needCalc = false) {
- const mesInfo = await transaction.get(this.tableName, { tid: this.ctx.tender.id, ms_id, mn_id, me_id: data.id });
- const updateData = {
- id: mesInfo.id,
- };
- for (const nu of needUpdateArray) {
- if (data[nu] !== undefined && mesInfo[nu] !== data[nu]) updateData[nu] = data[nu];
- }
- // 如果只有id,则不更新
- if (Object.keys(updateData).length > 1) await transaction.update(this.tableName, updateData);
- if (updateData.m_price !== undefined || updateData.weight_num !== undefined || needCalc) {
- const mnInfo = mn_id ? await transaction.get(this.ctx.service.materialExponentNode.tableName, { mid: this.ctx.material.id, id: mn_id }) : null;
- const msInfo = ms_id && !mn_id ? await transaction.get(this.ctx.service.materialStage.tableName, { mid: this.ctx.material.id, id: ms_id }) : null;
- const ex_calc = mnInfo ? JSON.parse(mnInfo.ex_calc) : msInfo ? JSON.parse(msInfo.ex_calc) : materialConst.ex_calc;
- await this.calcMaterialExTp(transaction, ex_calc, this.ctx.material.id, ms_id, mn_id);
- }
- return true;
- }
- async calcMaterialAllExTpByStage(transaction, mid, extra_ms_id = null, decimal = this.ctx.material.exponent_decimal ? this.ctx.material.exponent_decimal : materialConst.exponent_decimal, rate = this.ctx.material.exponent_rate) {
- const msList = await this.ctx.service.materialStage.getAllDataByCondition({ where: { mid } });
- const exponentList = await transaction.select(this.ctx.service.materialExponent.tableName, { where: { tid: this.ctx.tender.id, is_summary: materialConst.is_summary.yes } });
- const allStageExponentList = await transaction.select(this.tableName, { where: { mid } });
- const updateStages = [];
- for (const ms of msList) {
- if (extra_ms_id && ms.id === extra_ms_id) continue;
- const [ex_tp, ex_tax_tp, expr] = await this._calcOneExTp(transaction, JSON.parse(ms.ex_calc), ms.id, null, exponentList, allStageExponentList, decimal, rate);
- updateStages.push({
- id: ms.id,
- ex_tp,
- ex_tax_tp,
- ex_expr: expr,
- });
- }
- if (updateStages.length > 0) await transaction.updateRows(this.ctx.service.materialStage.tableName, updateStages);
- }
- async calcMaterialAllExTpByNode(transaction, mid, extra_mn_id = null, needCalcStage = true, decimal = this.ctx.material.exponent_decimal ? this.ctx.material.exponent_decimal : materialConst.exponent_decimal, rate = this.ctx.material.exponent_rate) {
- const mnList = await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid } });
- const exponentList = await transaction.select(this.ctx.service.materialExponent.tableName, { where: { tid: this.ctx.tender.id, is_summary: materialConst.is_summary.yes } });
- const allExponentShardList = await transaction.select(this.tableName, { where: { mid } });
- const updateNodes = [];
- for (const mn of mnList) {
- if (extra_mn_id && mn.id === extra_mn_id) continue;
- [mn.ex_tp, mn.ex_tax_tp, mn.expr] = await this._calcOneExTp(transaction, JSON.parse(mn.ex_calc), null, mn.id, exponentList, allExponentShardList, decimal, rate);
- updateNodes.push({
- id: mn.id,
- ex_tp: mn.ex_tp,
- ex_tax_tp: mn.ex_tax_tp,
- ex_expr: mn.expr,
- });
- }
- if (updateNodes.length > 0) await transaction.updateRows(this.ctx.service.materialExponentNode.tableName, updateNodes);
- if (needCalcStage) {
- const updateStages = [];
- const msList = await this.ctx.service.materialStage.getAllDataByCondition({ where: { mid } });
- for (const ms of msList) {
- // const extra_ms = extra_mn_id ? this._.find(mnList, { id: extra_mn_id }) : null;
- // if (extra_ms && extra_ms.ms_id === ms.id) continue;
- let stage_ex_tp = 0;
- let stage_ex_tax_tp = 0;
- const stageMnList = this._.filter(mnList, { ms_id: ms.id });
- for (const mn of stageMnList) {
- stage_ex_tp = this.ctx.helper.add(stage_ex_tp, mn.ex_tp ? mn.ex_tp : 0);
- stage_ex_tax_tp = this.ctx.helper.add(stage_ex_tax_tp, mn.ex_tax_tp ? mn.ex_tax_tp : 0);
- }
- updateStages.push({
- id: ms.id,
- ex_tp: stage_ex_tp,
- ex_tax_tp: stage_ex_tax_tp,
- });
- }
- if (updateStages.length > 0) await transaction.updateRows(this.ctx.service.materialStage.tableName, updateStages);
- }
- }
- async _calcOneExTp(transaction, ex_calc, msid = null, mnid = null, exponentList, allStageExponentList, decimal, rate) {
- let basic_calc = 0;
- // let basic_expr = 0;
- if (ex_calc) {
- for (const calc of ex_calc) {
- if (calc.select) {
- if (calc.code === 'zdy' && calc.result) {
- basic_calc = this.ctx.helper.add(basic_calc, calc.result);
- // basic_expr = calc.value;
- } else {
- basic_calc = this.ctx.helper.add(basic_calc, calc.value);
- // basic_expr = this.ctx.helper.add(basic_expr, calc.value);
- }
- }
- }
- }
- let expr = basic_calc + '*[';
- const condition = {};
- if (msid !== null) condition.ms_id = msid;
- if (mnid !== null) condition.mn_id = mnid;
- const stageExponentList = this._.filter(allStageExponentList, condition);
- let sumByChange = 0;
- let constant = 0;
- for (const ex of exponentList) {
- const stageEx = this._.find(stageExponentList, { me_id: ex.id });
- if (ex.type === materialConst.ex_type[0].value) {
- constant = stageEx.weight_num ? stageEx.weight_num : 0;
- expr += constant.toString();
- } else if (ex.type === materialConst.ex_type[1].value) {
- const calc_num = ex.basic_price > 0 ? this.ctx.helper.mul(stageEx.weight_num, this.ctx.helper.div(stageEx.m_price, ex.basic_price)) : 0;
- const change = calc_num ? this.ctx.helper.round(calc_num, decimal.qty) : 0;
- expr = expr + (change !== 0 ? '+' + stageEx.weight_num.toString() + '*(' + stageEx.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;
- const ex_tax_tp = ex_tp !== null ? this.ctx.helper.round(this.ctx.helper.mul(ex_tp, 1 + rate / 100), decimal.tp) : null;
- return [ex_tp, ex_tax_tp, expr];
- }
- // 更改计算总指数金额并返回值和公式
- async calcMaterialExTp(transaction, ex_calc, mid, msid = null, mnid = null, decimal = this.ctx.material.exponent_decimal, rate = this.ctx.material.exponent_rate, needCalcStage = true) {
- if (!msid && !mnid) throw '参数有误';
- const exponentList = await transaction.select(this.ctx.service.materialExponent.tableName, { where: { tid: this.ctx.tender.id, is_summary: materialConst.is_summary.yes } });
- const condition = {};
- if (msid !== null) condition.ms_id = msid;
- if (mnid !== null) condition.mn_id = mnid;
- const exponentShardList = await transaction.select(this.tableName, { where: condition });
- const [ex_tp, ex_tax_tp, expr] = await this._calcOneExTp(transaction, ex_calc, msid, mnid, exponentList, exponentShardList, decimal, rate);
- if (!mnid) {
- await transaction.update(this.ctx.service.materialStage.tableName, {
- id: msid,
- ex_tp,
- ex_tax_tp,
- ex_expr: expr,
- ex_calc: JSON.stringify(ex_calc),
- });
- } else {
- await transaction.update(this.ctx.service.materialExponentNode.tableName, {
- id: mnid,
- ex_tp,
- ex_tax_tp,
- ex_expr: expr,
- ex_calc: JSON.stringify(ex_calc),
- });
- if (needCalcStage && msid) {
- await this.ctx.service.materialExponentNode.calcStageExTpByNode(transaction, mid, msid);
- }
- }
- return [ex_tp, ex_tax_tp, expr];
- }
- /**
- * 更新新一期的现行价格指数,并返回指数总金额和公式
- * @param transaction
- * @param tid
- * @param mid
- * @returns {Promise<number>}
- */
- async updateNewMaterial(transaction, mid, msid, ctx, stage_id, ex_calc, decimal, rate) {
- 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 = this._.cloneDeep(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 : bq.select;
- }
- await this.calcMaterialExTp(transaction, new_ex_calc, mid, msid, null, decimal, rate);
- return new_ex_calc;
- }
- async makeExponentList(tid, data) {
- if (!data.mid || !data.stage_id) {
- throw '参数错误';
- }
- const transaction = await this.db.beginTransaction();
- try {
- const material = await this.ctx.service.material.getDataById(data.mid);
- if (!material) {
- throw '调差不存在';
- }
- if (!material.is_stage_self || material.is_new_exponent) {
- throw '独立期指数调差工料已生成或非独立期调差';
- }
- const materialExponentList = await this.ctx.service.materialExponent.getAllDataByCondition({ where: { tid } });
- const materialStageInfo = await this.ctx.service.materialStage.getDataByCondition({ mid: data.mid, sid: data.stage_id });
- await transaction.delete(this.tableName, { ms_id: materialStageInfo.id });
- await transaction.update(this.ctx.service.materialStage.tableName, {
- id: materialStageInfo.id,
- ex_tp: null,
- ex_tax_tp: null,
- ex_expr: null,
- ex_calc: null,
- });
- const newExponentList = [];
- for (const me of materialExponentList) {
- const newExponent = {
- tid,
- mid: material.id,
- ms_id: materialStageInfo.id,
- me_id: me.id,
- type: me.type,
- weight_num: me.weight_num,
- m_price: me.m_price,
- remark: me.remark,
- };
- newExponentList.push(newExponent);
- }
- if (newExponentList.length > 0) await transaction.insert(this.tableName, newExponentList);
- // 计算金额
- const ex_calc = await this.updateNewMaterial(transaction, material.id, materialStageInfo.id, this.ctx, materialStageInfo.sid, material.ex_calc, material.exponent_decimal ? JSON.parse(material.exponent_decimal) : materialConst.exponent_decimal, material.exponent_rate);
- await transaction.commit();
- return true;
- } catch (err) {
- await transaction.rollback();
- throw err;
- }
- }
- async insertMsExponent(transaction, tid, mid, ms, preMaterial = null, decimal, rate) {
- // 复制工料表并生成
- const meList = await transaction.select(this.ctx.service.materialExponent.tableName, { where: { tid } });
- if (meList.length > 0) {
- const insertStageExponentData = [];
- for (const e of meList) {
- const oneStageExponentData = {
- tid,
- mid,
- me_id: e.id,
- ms_id: ms.id,
- type: e.type,
- weight_num: e.weight_num,
- m_price: e.m_price,
- };
- insertStageExponentData.push(oneStageExponentData);
- }
- await transaction.insert(this.tableName, insertStageExponentData);
- const stage_list = await this.ctx.service.stage.getStageMsgByStageId(ms.sid);
- const calcBase = await this.ctx.service.stage.getMaterialCalcBase(stage_list, this.ctx.tender.info);
- let old_ex_calc = null;
- if (preMaterial && preMaterial.ex_calc) {
- old_ex_calc = JSON.parse(preMaterial.ex_calc);
- } else if (preMaterial && preMaterial.is_stage_self) {
- // 判断历史期是否存在相同独立期
- const allPreMs = await this.ctx.service.materialStage.getAllDataByCondition({ where: { tid: this.ctx.tender.id, sid: ms.sid }, orders: [['id', 'desc']] });
- const preMs = this._.find(allPreMs, m => m.mid !== mid);
- if (preMs && preMs.ex_calc) {
- old_ex_calc = JSON.parse(preMs.ex_calc);
- }
- }
- const new_ex_calc = this._.cloneDeep(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 : bq.select;
- }
- await this.calcMaterialExTp(transaction, new_ex_calc, mid, ms.id, null, decimal, rate);
- }
- }
- }
- return MaterialExponentShard;
- };
|