| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 | '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<void>}         */        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<number>}         */        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;};
 |