| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627 | '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 MaterialBills extends app.BaseService {        /**         * 构造函数         *         * @param {Object} ctx - egg全局变量         * @return {void}         */        constructor(ctx) {            super(ctx);            this.tableName = 'material_bills';        }        /**         * 添加工料         * @return {void}         */        async add() {            if (!this.ctx.tender || !this.ctx.material) {                throw '数据错误';            }            const order = await this._getMaxOrder(this.ctx.tender.id);            const transaction = await this.db.beginTransaction();            try {                const resultData = {};                const newBills = {                    tid: this.ctx.tender.id,                    mid: this.ctx.material.id,                    order: order + 1,                    in_time: new Date(),                };                // 新增工料                const result = await transaction.insert(this.tableName, newBills);                if (result.affectedRows !== 1) {                    throw '新增工料数据失败';                }                if (this.ctx.material.is_stage_self) {                    await this.ctx.service.materialStageBills.add(transaction, result.insertId);                    resultData.pushStageBillsData = await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id, mb_id: result.insertId } });                }                const insertArray = [];                const material_month = this.ctx.material.months ? this.ctx.material.months.split(',') : [];                for (const ym of material_month) {                    const one_month = {                        tid: this.ctx.tender.id,                        mid: this.ctx.material.id,                        mb_id: result.insertId,                        msg_tp: null,                        yearmonth: ym,                    };                    insertArray.push(one_month);                }                if (insertArray.length !== 0) await transaction.insert(this.ctx.service.materialMonth.tableName, insertArray);                await transaction.commit();                resultData.info = await this.getDataById(result.insertId);                return resultData;            } catch (error) {                console.log(error);                await transaction.rollback();                throw error;            }        }        async _getMaxOrder(tenderId) {            const sql = 'SELECT Max(??) As value FROM ?? Where tid = ' + tenderId;            const sqlParam = ['order', this.tableName];            const queryResult = await this.db.queryOne(sql, sqlParam);            return queryResult.value ? queryResult.value : 0;        }        /**         * 删除工料         * @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 materialListNum = await this.ctx.service.materialList.count({ tid: this.ctx.tender.id, mb_id: id });                if (materialListNum > 0) {                    throw '该工料已存在对应的清单工料含量,删除失败';                }                const mbInfo = await this.getDataById(id);                await transaction.delete(this.tableName, { id });                const m_tp = this.ctx.material.m_tp;                const result = { m_tp };                if (this.ctx.material.is_stage_self) {                    await transaction.delete(this.ctx.service.materialStageBills.tableName, { mb_id: id });                    // 金额发生变化,则重新计算本期金额                    for (const sid of this.ctx.material.stage_id.split(',')) {                        const msInfo = await transaction.get(this.ctx.service.materialStage.tableName, { tid: this.ctx.tender.id, sid });                        await this.ctx.service.materialStage.updateMtp(transaction, msInfo.id);                    }                    result.stageBillsData = await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id } });                    result.stageData = await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } });                    result.m_tp = await this.calcMaterialMTp(transaction);                } else if (mbInfo.t_type === materialConst.t_type[1].value && mbInfo.quantity !== null && mbInfo.m_spread !== null) {                    // 金额发生变化,则重新计算本期金额                    result.m_tp = await this.calcMaterialMTp(transaction);                }                const material_month = this.ctx.material.months ? this.ctx.material.months.split(',') : [];                if (material_month.length > 0) {                    await transaction.delete(this.ctx.service.materialMonth.tableName, { mb_id: id });                }                await transaction.commit();                return result;            } catch (err) {                await transaction.rollback();                throw err;            }        }        /**         * 交换两个工料的顺序         * @param {Number} id1 - 工料1的id         * @param {Number} id2 - 工料2的id         * @returns {Promise<void>}         */        async changeOrder(id1, id2) {            if (!this.ctx.tender || !this.ctx.material) {                throw '数据错误';            }            const bill1 = await this.getDataByCondition({ tid: this.ctx.tender.id, id: id1 });            const bill2 = await this.getDataByCondition({ tid: this.ctx.tender.id, id: id2 });            if (!bill1 || !bill2) {                throw '数据错误';            }            const transaction = await this.db.beginTransaction();            try {                const order = bill1.order;                bill1.order = bill2.order;                bill2.order = order;                await transaction.update(this.tableName, { id: bill1.id, order: bill1.order });                await transaction.update(this.tableName, { id: bill2.id, order: bill2.order });                await transaction.commit();                return true;            } catch (err) {                await transaction.rollback();                throw err;            }        }        /**         * 修改工料信息         * @param {Object} data 工料内容         * @return {void}         */        async save(data, ms_id = null) {            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 {                const result = {};                if (this.ctx.material.is_stage_self) {                    if (!ms_id) {                        throw '期参数有误';                    }                    const needUp = await this.updateOneBillsData(transaction, data, ms_id);                    const [one_m_tp, one_tax_tp] = await this.ctx.service.materialStageBills.update(transaction, data, ms_id);                    // 更新materialStage 值                    data.m_tp = this.ctx.helper.round(one_m_tp, this.ctx.material.decimal.tp);                    data.m_tax_tp = this.ctx.helper.round(one_tax_tp, this.ctx.material.decimal.tp);                    data.quantity = null;                    data.msg_tp = null;                    data.msg_times = null;                    data.msg_spread = null;                    data.m_spread = null;                    delete data.ms_id;                    // 更新materialStage 值                    await this.ctx.service.materialStage.updateMtp(transaction, ms_id);                    result.stageBillsData = this.ctx.material.is_stage_self && needUp ?                        await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id, mb_id: data.id } }) :                        await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id, ms_id, mb_id: data.id } });                    result.stageData = this.ctx.material.is_stage_self && needUp ?                        await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } }) :                        await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id, id: ms_id } });                }                await transaction.update(this.tableName, data);                result.m_tp = await this.calcMaterialMTp(transaction);                await transaction.commit();                return result;            } catch (err) {                await transaction.rollback();                throw err;            }        }        async updateOneBillsData(transaction, data, ms_id) {            // 当以下值和bills值不相同时,需要同步更新最新的计算值到stageBills表里            const updateColsArray = ['t_type', 'm_tax', 'basic_price', 'm_up_risk', 'm_down_risk', 'is_summary'];            let needUp = null;            const mbInfo = await this.getDataById(data.id);            for (const uc of updateColsArray) {                if (data[uc] !== undefined && data[uc] !== mbInfo[uc]) {                    needUp = uc;                    break;                }            }            if (needUp) {                const msList = await this.ctx.service.materialStage.getAllDataByCondition({ where: { mid: this.ctx.material.id } });                for (const ms of msList) {                    if (ms.id !== parseInt(ms_id)) {                        const msbInfo = await this.ctx.service.materialStageBills.getDataByCondition({                            mid: this.ctx.material.id,                            ms_id: ms.id,                            mb_id: data.id,                        });                        const updateData = {                            id: msbInfo.id,                        };                        if (needUp === 'm_tax') {                            updateData.m_tax_tp = this.ctx.helper.round(this.ctx.helper.mul(msbInfo.m_tp, (1 + this.ctx.helper.div(data.m_tax, 100))), this.ctx.material.decimal.tp);                        } else if (needUp === 'm_up_risk' || needUp === 'm_down_risk' || needUp === 'basic_price') {                            const basic_price = needUp === 'basic_price' ? data.basic_price : mbInfo.basic_price;                            const [msg_spread, m_spread] = await this.getSpread(mbInfo, msbInfo.msg_tp, this.ctx.material.decimal.up, basic_price);                            updateData.msg_spread = msg_spread;                            updateData.m_spread = m_spread;                            const newTp = this.ctx.helper.round(this.ctx.helper.mul(msbInfo.quantity, m_spread), this.ctx.material.decimal.tp);                            updateData.m_tp = newTp;                            updateData.m_tax_tp = this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mbInfo.m_tax, 100))), this.ctx.material.decimal.tp);                        } else if (needUp === 't_type') {                            updateData.quantity = null;                            updateData.m_tp = null;                            updateData.m_tax_tp = null;                        } else if (needUp === 'is_summary') {                            updateData.is_summary = data.is_summary;                        }                        await transaction.update(this.ctx.service.materialStageBills.tableName, updateData);                        await this.ctx.service.materialStage.updateMtp(transaction, ms.id);                    }                }            }            return needUp;        }        async saveOrigin(data) {            if (!this.ctx.tender || !this.ctx.material) {                throw '数据错误';            }            return await this.db.update(this.tableName, { id: data.mb_id, origin: data.value });        }        async saveOrigins(datas) {            if (!this.ctx.tender || !this.ctx.material) {                throw '数据错误';            }            const updateData = [];            for (const data of datas) {                updateData.push({                    id: data.mb_id,                    origin: data.origin,                });            }            if (updateData.length > 0) await this.db.updateRows(this.tableName, updateData);            return true;        }        /**         * 修改工料信息         * @param {Object} data 工料内容         * @return {void}         */        async saveDatas(datas, ms_id = null) {            if (!this.ctx.tender || !this.ctx.material) {                throw '数据错误';            }            // 判断是否可修改            // 判断t_type是否为费用            const transaction = await this.db.beginTransaction();            try {                for (const data of datas) {                    delete data.in_time;                    let needUp = null;                    if (this.ctx.material.is_stage_self) {                        needUp = await this.updateOneBillsData(transaction, data, ms_id);                        const [one_m_tp, one_tax_tp] = await this.ctx.service.materialStageBills.update(transaction, data, ms_id);                        // 更新materialStage 值                        data.m_tp = this.ctx.helper.round(one_m_tp, this.ctx.material.decimal.tp);                        data.m_tax_tp = this.ctx.helper.round(one_tax_tp, this.ctx.material.decimal.tp);                        data.quantity = null;                        data.msg_tp = null;                        data.msg_times = null;                        data.msg_spread = null;                        data.msg_spread = null;                        data.m_spread = null;                    }                    // delete data.m_tp;                    // console.log(data);                    await transaction.update(this.tableName, data);                }                // 更新materialStage 值                const result = {};                if (this.ctx.material.is_stage_self) {                    await this.ctx.service.materialStage.updateMtp(transaction, ms_id);                    result.stageBillsData = await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id } });                    result.stageData = await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } });                }                result.m_tp = await this.calcMaterialMTp(transaction);                await transaction.commit();                return result;            } catch (err) {                await transaction.rollback();                throw err;            }        }        /**         * 更新新一期的quantity和截止上期金额并返回本期总金额         * @param transaction         * @param tid         * @param mid         * @returns {Promise<number>}         */        async updateNewMaterial(transaction, tid, mid, ctx, stage_id, decimal) {            const materialBillsData = await this.getAllDataByCondition({ where: { tid } });            let m_tp = 0;            let m_tax_tp = 0;            const materialCalculator = new MaterialCalculator(ctx, stage_id, ctx.tender.info);            for (const mb of materialBillsData) {                const [one_tp, one_tax_tp] = await this.calcQuantityByMB(transaction, mid, mb, materialCalculator, decimal);                m_tp = this.ctx.helper.add(m_tp, one_tp);                m_tax_tp = this.ctx.helper.add(m_tax_tp, one_tax_tp);            }            return [m_tp, m_tax_tp];        }        /**         * 修改quantity,m_spread值和返回单条调差金额(新增一期)         * @param transaction         * @param mid         * @param mb         * @returns {Promise<*>}         */        async calcQuantityByMB(transaction, mid, mb, materialCalculator, decimal) {            const [newmsg_spread, newm_spread] = await this.getSpread(mb, null, decimal.up);            if (mb.t_type === materialConst.t_type[0].value) {                const sql = 'SELECT SUM(`gather_qty`*`quantity`) as quantity FROM ' + this.ctx.service.materialList.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `is_join`=1';                const sqlParam = [mid, mb.id];                const mb_quantity = await transaction.queryOne(sql, sqlParam);                console.log(mb_quantity);                // 取历史期记录获取截止上期调差金额,并清空本期单价和时间,来源地,重新计算价差和有效价差                const newQuantity = this.ctx.helper.round(mb_quantity.quantity, decimal.qty);                const newTp = this.ctx.helper.round(this.ctx.helper.mul(newQuantity, newm_spread), decimal.tp);                const updateData = {                    id: mb.id,                    quantity: newQuantity,                    msg_tp: null,                    msg_times: null,                    msg_spread: newmsg_spread,                    m_spread: newm_spread,                    origin: null,                    m_tp: newTp,                    pre_tp: mb.m_tp !== null ? this.ctx.helper.add(mb.pre_tp, mb.m_tp) : mb.pre_tp,                    m_tax_tp: this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mb.m_tax, 100))), decimal.tp),                    tax_pre_tp: mb.m_tax_tp !== null ? this.ctx.helper.add(mb.tax_pre_tp, mb.m_tax_tp) : mb.tax_pre_tp,                };                await transaction.update(this.tableName, updateData);                const m_tp = mb.is_summary === 1 ? await this.ctx.helper.round(this.ctx.helper.mul(mb_quantity.quantity, newm_spread), decimal.tp) : 0;                const m_tax_tp = this.ctx.helper.round(this.ctx.helper.mul(m_tp, (1 + this.ctx.helper.div(mb.m_tax, 100))), decimal.tp);                return [m_tp, m_tax_tp];            } else if (mb.t_type === materialConst.t_type[1].value) {                const quantity = await materialCalculator.calculateExpr(mb.expr);                const newTp = quantity !== 0 && quantity !== null ? this.ctx.helper.round(this.ctx.helper.mul(this.ctx.helper.round(quantity, decimal.qty), newm_spread), decimal.tp) : null;                const updateData = {                    id: mb.id,                    quantity: quantity !== 0 && quantity !== null ? this.ctx.helper.round(quantity, decimal.qty) : null,                    msg_tp: null,                    msg_times: null,                    msg_spread: newmsg_spread,                    m_spread: newm_spread,                    origin: null,                    m_tp: newTp,                    pre_tp: mb.m_tp !== null ? this.ctx.helper.add(mb.pre_tp, mb.m_tp) : mb.pre_tp,                    m_tax_tp: this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mb.m_tax, 100))), decimal.tp),                    tax_pre_tp: mb.m_tax_tp !== null ? this.ctx.helper.add(mb.tax_pre_tp, mb.m_tax_tp) : mb.tax_pre_tp,                };                await transaction.update(this.tableName, updateData);                const m_tp = mb.is_summary === 1 ? await this.ctx.helper.round(this.ctx.helper.mul(quantity, newm_spread), decimal.tp) : 0;                const m_tax_tp = this.ctx.helper.round(this.ctx.helper.mul(m_tp, (1 + this.ctx.helper.div(mb.m_tax, 100))), decimal.tp);                return [m_tp, m_tax_tp];            }        }        /**         * 清空本期信息价后更新价差和有效价差         * @param data         * @returns {Promise<void>}         */        async getSpread(data, msg_tp, newDecimalUp = this.ctx.material.decimal.up, basic_price = null) {            data.msg_tp = msg_tp;            const newBp = basic_price ? basic_price : data.basic_price;            const msg_spread = this.ctx.helper.round(this.ctx.helper.sub(data.msg_tp, newBp), newDecimalUp);            const cor = msg_spread >= 0 ? this.ctx.helper.mul(newBp, this.ctx.helper.div(data.m_up_risk, 100)) : this.ctx.helper.mul(newBp, this.ctx.helper.div(data.m_down_risk, 100));            const m_spread = Math.abs(msg_spread) > Math.abs(cor) ? (msg_spread > 0 ? this.ctx.helper.round(this.ctx.helper.sub(msg_spread, cor), newDecimalUp) : this.ctx.helper.round(this.ctx.helper.add(msg_spread, cor), newDecimalUp)) : 0;            return [msg_spread, m_spread];        }        /**         * 修改 expr和quantity值,返回本期金额和单条数据         * @param data         * @returns {Promise<void>}         */        async updateFYQuantity(data) {            if (!this.ctx.tender || !this.ctx.material) {                throw '数据错误';            }            const transaction = await this.db.beginTransaction();            try {                const returnData = {};                returnData.m_tp = this.ctx.material.m_tp;                if (this.ctx.material.is_stage_self) {                    const mbInfo = await this.getDataById(data.id);                    let all_m_tp = 0;                    let all_tax_tp = 0;                    for (const sid of this.ctx.material.stage_id.split(',')) {                        const materialCalculator = new MaterialCalculator(this.ctx, sid, this.ctx.tender.info);                        const quantity = await materialCalculator.calculateExpr(data.expr);                        const msInfo = await this.ctx.service.materialStage.getDataByCondition({ mid: this.ctx.material.id, sid });                        const msbInfo = await this.ctx.service.materialStageBills.getDataByCondition({ mid: this.ctx.material.id, mb_id: data.id, ms_id: msInfo.id });                        const newQuantity = quantity !== 0 ? this.ctx.helper.round(quantity, this.ctx.material.decimal.qty) : null;                        const m_tp = newQuantity ? this.ctx.helper.round(this.ctx.helper.mul(newQuantity, msbInfo.m_spread), this.ctx.material.decimal.tp) : null;                        const updateData = {                            id: data.id,                            quantity: newQuantity,                            m_tp,                            m_tax_tp: this.ctx.helper.round(this.ctx.helper.mul(m_tp, (1 + this.ctx.helper.div(mbInfo.m_tax, 100))), this.ctx.material.decimal.tp),                        };                        const [one_bill_m_tp, one_bill_tax_tp] = await this.ctx.service.materialStageBills.update(transaction, updateData, msInfo.id);                        await this.ctx.service.materialStage.updateMtp(transaction, msInfo.id);                        all_m_tp = this.ctx.helper.round(one_bill_m_tp, this.ctx.material.decimal.tp);                        all_tax_tp = this.ctx.helper.round(one_bill_tax_tp, this.ctx.material.decimal.tp);                    }                    const updateBillsData = {                        id: data.id,                        expr: data.expr,                        m_tp: all_m_tp ? all_m_tp : null,                        m_tax_tp: all_tax_tp ? all_tax_tp : null,                    };                    console.log(all_m_tp);                    await transaction.update(this.tableName, updateBillsData);                    returnData.m_tp = await this.calcMaterialMTp(transaction);                    returnData.stageBillsData = await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id, mb_id: data.id } });                    returnData.stageData = await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } });                } else {                    const materialCalculator = new MaterialCalculator(this.ctx, this.ctx.material.stage_id, this.ctx.tender.info);                    const quantity = await materialCalculator.calculateExpr(data.expr);                    // 更新quantity值并重新返回计算本期金额,截止本期金额                    const updateData = {                        id: data.id,                        quantity: quantity !== 0 ? this.ctx.helper.round(quantity, this.ctx.material.decimal.qty) : null,                        expr: data.expr,                    };                    const mbInfo = await this.getDataById(updateData.id);                    updateData.m_tp = this.ctx.helper.round(this.ctx.helper.mul(updateData.quantity, mbInfo.m_spread), this.ctx.material.decimal.tp);                    updateData.m_tax_tp = this.ctx.helper.round(this.ctx.helper.mul(updateData.m_tp, (1 + this.ctx.helper.div(mbInfo.m_tax, 100))), this.ctx.material.decimal.tp);                    await transaction.update(this.tableName, updateData);                    if (mbInfo.quantity !== updateData.quantity) {                        returnData.m_tp = await this.calcMaterialMTp(transaction);                    }                }                await transaction.commit();                returnData.info = await this.getDataById(data.id);                return returnData;            } catch (err) {                await transaction.rollback();                throw err;            }        }        // 更改计算总金额并返回值        async calcMaterialMTp(transaction) {            // 金额发生变化,则重新计算本期金额            const sql = 'SELECT SUM(`m_tp`) as total_price, SUM(IF(`m_tax_tp` is null, `m_tp`, `m_tax_tp`)) as tax_total_price FROM ' + this.tableName + ' WHERE `tid` = ? AND `is_summary` = 1';            const sqlParam = [this.ctx.tender.id];            const tp = await transaction.queryOne(sql, sqlParam);            const updateData2 = {                id: this.ctx.material.id,                m_tp: tp.total_price,                m_tax_tp: tp.tax_total_price,            };            console.log(tp);            // if (this.ctx.material.material_tax) {            //     updateData2.m_tax_tp = tp.tax_total_price;            // }            await transaction.update(this.ctx.service.material.tableName, updateData2);            return tp.total_price;        }        // 小数位变化更新单价和金额        async resetDecimal(transaction, newDecimalUp, newDecimalTp, newDecimalQty) {            const mbList = await transaction.select(this.tableName, { where: { tid: this.ctx.tender.id }, orders: [['order', 'asc']] });            const updateList = [];            const material_month = this.ctx.material.months ? this.ctx.material.months.split(',') : [];            const updateMonthList = [];            const materialStageList = this.ctx.material.is_stage_self ? await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } }) : [];            for (const mb of mbList) {                const updateData = {                    id: mb.id,                };                if (this.ctx.material.is_stage_self) {                    const updateStageBillsList = [];                    for (const ms of materialStageList) {                        const msb = await transaction.get(this.ctx.service.materialStageBills.tableName, { mid: this.ctx.material.id, mb_id: mb.id, ms_id: ms.id });                        const updateStageBillData = {                            id: msb.id,                        };                        if (newDecimalQty !== this.ctx.material.decimal.qty) {                            // 通过管理重新算出quantity并保留小数位                            const sql = 'SELECT SUM(`gather_qty`*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `ms_id`=? AND `is_join`=1';                            const sqlParam = [this.ctx.material.id, mb.id, ms.id];                            const mb_quantity = await transaction.queryOne(sql, sqlParam);                            const newQuantity = this.ctx.helper.round(mb_quantity.quantity, newDecimalQty);                            if (newQuantity !== msb.quantity) {                                updateStageBillData.quantity = newQuantity;                                msb.quantity = newQuantity;                            }                        }                        if (newDecimalUp !== this.ctx.material.decimal.up) {                            const newmsg_tp = this.ctx.helper.round(msb.msg_tp, newDecimalUp);                            msb.msg_tp = newmsg_tp;                            const newbasic_price = this.ctx.helper.round(mb.basic_price, newDecimalUp);                            const [newmsg_spread, newm_spread] = await this.getSpread(msb, msb.msg_tp, newDecimalUp, newbasic_price);                            mb.m_spread = newm_spread;                            updateStageBillData.msg_tp = newmsg_tp;                            updateStageBillData.msg_spread = newmsg_spread;                            updateStageBillData.m_spread = newm_spread;                        }                        const newTp = this.ctx.helper.round(this.ctx.helper.mul(msb.quantity, msb.m_spread), newDecimalTp);                        updateStageBillData.m_tp = newTp;                        updateStageBillData.m_tax_tp = this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mb.m_tax, 100))), newDecimalTp);                        updateStageBillsList.push(updateStageBillData);                    }                    if (newDecimalUp !== this.ctx.material.decimal.up) {                        const newbasic_price = this.ctx.helper.round(mb.basic_price, newDecimalUp);                        updateData.basic_price = newbasic_price;                    }                    const sql = 'SELECT SUM(`m_tp`) as total_price, SUM(IF(`m_tax_tp` is null, `m_tp`, `m_tax_tp`)) as tax_total_price FROM ' + this.tableName + ' WHERE `tid` = ? AND `mid` = ? AND `mb_id` = ? AND `is_summary` = 1';                    const sqlParam = [this.ctx.tender.id, this.ctx.material.id, mb.id];                    const tp = await transaction.queryOne(sql, sqlParam);                    updateData.m_tp = this.ctx.helper.round(tp.total_price, newDecimalTp);                    updateData.m_tax_tp = this.ctx.helper.round(tp.tax_total_price, newDecimalTp);                    updateList.push(updateData);                    if (updateStageBillsList.length > 0) await transaction.updateRows(this.ctx.service.materialStageBills.tableName, updateStageBillsList);                } else {                    if (newDecimalUp !== this.ctx.material.decimal.up) {                        let newmsg_tp = this.ctx.helper.round(mb.msg_tp, newDecimalUp);                        mb.msg_tp = newmsg_tp;                        // 判断是否有月信息价,如果有则msg_tp值由月信息价的平均单价获得,并更新月信息价单价                        if (material_month.length > 0) {                            const monthList = await transaction.select(this.ctx.service.materialMonth.tableName, { where: { mb_id: mb.id, mid: this.ctx.material.id } });                            if (monthList.length !== 0) {                                for (const m of monthList) {                                    // 更新月信息单价小数位                                    const newMonthMsgTP = this.ctx.helper.round(m.msg_tp, newDecimalUp);                                    if (m.msg_tp && newMonthMsgTP !== m.msg_tp) {                                        m.msg_tp = newMonthMsgTP;                                        updateMonthList.push({ id: m.id, msg_tp: m.msg_tp });                                    }                                }                                const mb_msg_tp_sum = this._.sumBy(monthList, 'msg_tp');                                const month_num = material_month.length - this.ctx.helper.arrayCount(this._.map(monthList, 'msg_tp'), [null, '', 0]);                                newmsg_tp = month_num !== 0 ? this.ctx.helper.round(this.ctx.helper.div(mb_msg_tp_sum, month_num), newDecimalUp) : null;                                mb.msg_tp = newmsg_tp;                            }                        }                        const newbasic_price = this.ctx.helper.round(mb.basic_price, newDecimalUp);                        mb.basic_price = newbasic_price;                        const [newmsg_spread, newm_spread] = await this.getSpread(mb, mb.msg_tp, newDecimalUp);                        mb.m_spread = newm_spread;                        updateData.basic_price = newbasic_price;                        updateData.msg_tp = newmsg_tp;                        updateData.msg_spread = newmsg_spread;                        updateData.m_spread = newm_spread;                    }                    if (newDecimalQty !== this.ctx.material.decimal.qty) {                        // 通过管理重新算出quantity并保留小数位                        const sql = 'SELECT SUM(`gather_qty`*`quantity`) as quantity FROM ' + this.tableName + ' WHERE `mid`=? AND `mb_id`=? AND `is_join`=1';                        const sqlParam = [this.ctx.material.id, mb.id];                        const mb_quantity = await transaction.queryOne(sql, sqlParam);                        const newQuantity = this.ctx.helper.round(mb_quantity.quantity, newDecimalQty);                        mb.quantity = newQuantity;                        updateData.quantity = newQuantity;                    }                    const newTp = this.ctx.helper.round(this.ctx.helper.mul(mb.quantity, mb.m_spread), newDecimalTp);                    updateData.m_tp = newTp;                    updateData.m_tax_tp = this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mb.m_tax, 100))), newDecimalTp);                    updateList.push(updateData);                }            }            if (this.ctx.material.is_stage_self) {                for (const ms of materialStageList) {                    await this.ctx.service.materialStage.updateMtp(transaction, ms.id);                }            }            if (updateMonthList.length > 0) await transaction.updateRows(this.ctx.service.materialMonth.tableName, updateMonthList);            if (updateList.length > 0) await transaction.updateRows(this.tableName, updateList);        }    }    return MaterialBills;};
 |