| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 | 'use strict';/** * 期计量 数据模型 * * @author Mai * @date 2018/8/13 * @version */const auditConst = require('../const/audit').material;const projectLogConst = require('../const/project_log');module.exports = app => {    class Material extends app.BaseService {        /**         * 构造函数         *         * @param {Object} ctx - egg全局变量         * @return {void}         */        constructor(ctx) {            super(ctx);            this.tableName = 'material';        }        /**         * 获取 最新一期 材料调差期计量         * @param tenderId         * @param includeUnCheck         * @return {Promise<*>}         */        async getLastestMaterial(tenderId, includeUnCheck = false) {            this.initSqlBuilder();            this.sqlBuilder.setAndWhere('tid', {                value: tenderId,                operate: '=',            });            if (!includeUnCheck) {                this.sqlBuilder.setAndWhere('status', {                    value: auditConst.status.uncheck,                    operate: '!=',                });            }            this.sqlBuilder.orderBy = [['order', 'desc']];            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);            const material = await this.db.queryOne(sql, sqlParam);            return material;        }        /**         * 获取 最新一期 审批完成的 材料调差期计量         * @param tenderId         * @return {Promise<*>}         */        async getLastestCompleteMaterial(tenderId) {            this.initSqlBuilder();            this.sqlBuilder.setAndWhere('tid', {                value: tenderId,                operate: '=',            });            this.sqlBuilder.setAndWhere('status', {                value: auditConst.status.checked,                operate: '=',            });            this.sqlBuilder.orderBy = [['order', 'desc']];            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);            const material = await this.db.queryOne(sql, sqlParam);            return material;        }        /**         * 获取标段下的全部计量期,按倒序         * @param tenderId         * @return {Promise<void>}         */        async getValidMaterials(tenderId) {            const materials = await this.db.select(this.tableName, {                where: { tid: tenderId },                orders: [['order', 'desc']],            });            if (materials.length !== 0) {                const lastMaterial = materials[materials.length - 1];                if (lastMaterial.status === auditConst.status.uncheck && lastMaterial.user_id !== this.ctx.session.sessionUser.accountId && !this.ctx.tender.isTourist) {                    materials.splice(materials.length - 1, 1);                }            }            // 最新一期计量(未审批完成),当前操作人的期详细数据,应实时计算            if (materials.length > 0 && materials[0].status !== auditConst.status.checked) {                const material = materials[0];                const curAuditor = await this.ctx.service.materialAudit.getCurAuditor(material.id, material.times);                const isActive = curAuditor ? curAuditor.id === this.ctx.session.sessionUser.accountId : material.user_id === this.ctx.session.sessionUser.accountId;                if (isActive) {                    material.curTimes = material.times;                    material.curOrder = curAuditor ? curAuditor.order : 0;                }            }            return materials;        }        /**         * 添加材料调差期         * @param tenderId - 标段id         * @param data - post的数据         * @return {Promise<void>}         */        async addMaterial(tenderId, data) {            const materials = await this.getAllDataByCondition({                where: { tid: tenderId },                order: ['order'],            });            const preMaterial = materials[materials.length - 1];            if (materials.length > 0 && materials[materials.length - 1].status !== auditConst.status.checked) {                throw '上一期未审批通过,请等待上一期审批通过后,再新增数据';            }            const order = materials.length + 1;            const newMaterial = {                tid: tenderId,                order,                in_time: new Date(),                times: 1,                status: auditConst.status.uncheck,                user_id: this.ctx.session.sessionUser.accountId,                stage_id: data.stage_id.join(','),                s_order: data.s_order,            };            const transaction = await this.db.beginTransaction();            try {                if (preMaterial) {                    newMaterial.rate = preMaterial.rate;                    newMaterial.pre_tp = this.ctx.helper.add(preMaterial.m_tp, preMaterial.pre_tp);                    newMaterial.ex_pre_tp = this.ctx.helper.add(preMaterial.ex_tp, preMaterial.ex_pre_tp);                }                // 新增期记录                const result = await transaction.insert(this.tableName, newMaterial);                if (result.affectedRows === 1) {                    newMaterial.id = result.insertId;                } else {                    throw '新增期数据失败';                }                // 存在上一期时,复制上一期审批流程、不参与调差的清单、上期清单并算本期有效价差,本期应耗数量,并算本期总金额                if (preMaterial) {                    const auditResult = await this.ctx.service.materialAudit.copyPreMaterialAuditors(transaction, preMaterial, newMaterial);                    if (!auditResult) {                        throw '复制上一期审批流程失败';                    }                    // 复制不参与调差清单                    const preNotJoinList = await this.ctx.service.materialListNotjoin.getAllDataByCondition({ where: { tid: this.ctx.tender.id, mid: preMaterial.id } });                    await this.ctx.service.materialListNotjoin.copyNewStageNotJoinList(transaction, preNotJoinList, newMaterial.id);                    // 复制调差清单工料关联表                    await this.ctx.service.materialList.copyPreMaterialList(transaction, preMaterial, newMaterial);                    // 修改本期应耗数量值和有效价差,需要剔除不参与调差的清单数据,并返回总金额                    const m_tp = await this.ctx.service.materialBills.updateNewMaterial(transaction, this.ctx.tender.id, newMaterial.id, this.ctx, newMaterial.stage_id);                    // 修改现行价格指数,并返回调差基数json                    const ex_calc = await this.ctx.service.materialExponent.updateNewMaterial(transaction, newMaterial.id, this.ctx, newMaterial.stage_id, preMaterial.ex_calc);                    // 计算得出本期总金额                    const updateMaterialData = {                        id: newMaterial.id,                        m_tp,                        ex_calc: JSON.stringify(ex_calc),                    };                    await transaction.update(this.tableName, updateMaterialData);                }                await transaction.commit();                return newMaterial;            } catch (err) {                await transaction.rollback();                throw err;            }        }        /**         * 删除材料调差期         *         * @param {Number} id - 期Id         * @return {Promise<void>}         */        async deleteMaterial(id) {            const transaction = await this.db.beginTransaction();            try {                // 删除文件                const attList = await this.ctx.service.materialFile.getAllMaterialFiles(this.ctx.tender.id, id);                await this.ctx.helper.delFiles(attList);                await transaction.delete(this.ctx.service.materialAudit.tableName, { mid: id });                await transaction.delete(this.ctx.service.materialBills.tableName, { mid: id });                await transaction.delete(this.ctx.service.materialList.tableName, { mid: id });                await transaction.delete(this.ctx.service.materialListNotjoin.tableName, { mid: id });                await transaction.delete(this.ctx.service.materialBillsHistory.tableName, { mid: id });                await transaction.delete(this.ctx.service.materialFile.tableName, { mid: id });                await transaction.delete(this.ctx.service.materialExponent.tableName, { mid: id });                await transaction.delete(this.ctx.service.materialExponentHistory.tableName, { mid: id });                // 如果存在上一期,把上一期的quantity,expr,msg_tp,msg_times,msg_spread,m_up_risk,m_down_risk,m_spread,m_tp,pre_tp,is_summary添加到bill中                const materialInfo = await this.getDataById(id);                if (materialInfo.order > 1) {                    const sql = 'UPDATE ' + this.ctx.service.materialBills.tableName + ' as mb, ' +                        this.ctx.service.materialBillsHistory.tableName + ' as mbh ' +                        'SET mb.`quantity` = mbh.`quantity`, mb.`expr` = mbh.`expr`, ' +                        'mb.`msg_tp` = mbh.`msg_tp`, mb.`msg_times` = mbh.`msg_times`, ' +                        'mb.`msg_spread` = mbh.`msg_spread`, mb.`m_up_risk` = mbh.`m_up_risk`, ' +                        'mb.`m_down_risk` = mbh.`m_down_risk`, mb.`m_spread` = mbh.`m_spread`, ' +                        'mb.`m_tp` = mbh.`m_tp`, mb.`pre_tp` = mbh.`pre_tp`, ' +                        'mb.`is_summary` = mbh.`is_summary` ' +                        'WHERE mbh.`tid` = ? AND mbh.`order` = ? AND mbh.`mb_id` = mb.`id`';                    const sqlParam = [this.ctx.tender.id, materialInfo.order - 1];                    await transaction.query(sql, sqlParam);                    const sql2 = 'UPDATE ' + this.ctx.service.materialExponent.tableName + ' as me, ' +                        this.ctx.service.materialExponentHistory.tableName + ' as meh ' +                        'SET me.`weight_num` = meh.`weight_num`, me.`basic_price` = meh.`basic_price`, ' +                        'me.`basic_times` = meh.`basic_times`, me.`m_price` = meh.`m_price`, ' +                        'me.`calc_num` = meh.`calc_num`, me.`is_summary` = meh.`is_summary` ' +                        'WHERE meh.`tid` = ? AND meh.`order` = ? AND meh.`me_id` = me.`id`';                    const sqlParam2 = [this.ctx.tender.id, materialInfo.order - 1];                    await transaction.query(sql2, sqlParam2);                }                await transaction.delete(this.tableName, { id });                // 记录删除日志                await this.ctx.service.projectLog.addProjectLog(transaction, projectLogConst.type.material, projectLogConst.status.delete, '第' + materialInfo.order + '期');                await transaction.commit();                return true;            } catch (err) {                await transaction.rollback();                throw err;            }        }        /**         * 获取包含当前期之前的调差期id         *         * @param {Number} id - 期Id         * @return {Promise<void>}         */        async getPreMidList(tid, order) {            const midList = await this.getAllDataByCondition({                where: { tid },                columns: ['id'],                limit: order,                offset: 0,            });            const list = [];            for (const ml of midList) {                list.push(ml.id);            }            return list;        }        /**         * 修改增税税率         * @param {int} rate 税率         * @return {Promise<*>}         */        async changeRate(rate) {            const updateData = {                id: this.ctx.material.id,                rate,            };            return await this.db.update(this.tableName, updateData);        }        /**         * 修改调差基数         * @param {int} rate 税率         * @return {Promise<*>}         */        async changeExCalc(ex_calc) {            const transaction = await this.db.beginTransaction();            try {                const updateData = {                    id: this.ctx.material.id,                    ex_calc: JSON.stringify(ex_calc),                };                await transaction.update(this.tableName, updateData);                const [ex_tp, ex_expr] = await this.ctx.service.materialExponent.calcMaterialExTp(transaction, ex_calc);                await transaction.commit();                return [ex_tp, ex_expr];            } catch (err) {                await transaction.rollback();                throw err;            }        }        /**         * 取当前期截止上期含税金额         * @param {int} tid 标段id         * @param {int} order 调差期数         * @return {Promise<*>}         */        async getPreTpHs(tid, order) {            const sql = 'SELECT SUM(ROUND(`m_tp`*(1+ `rate`/100),2)) AS `pre_tp_hs` FROM ?? WHERE `tid` = ? AND `order` < ?';            const sqlParam = [this.tableName, tid, order];            const result = await this.db.queryOne(sql, sqlParam);            return result.pre_tp_hs;        }        /**         * 取当前期截止上期含税指数金额         * @param {int} tid 标段id         * @param {int} order 调差期数         * @return {Promise<*>}         */        async getExPreTpHs(tid, order) {            const sql = 'SELECT SUM(ROUND(`ex_tp`*(1+ `rate`/100),2)) AS `ex_pre_tp_hs` FROM ?? WHERE `tid` = ? AND `order` < ?';            const sqlParam = [this.tableName, tid, order];            const result = await this.db.queryOne(sql, sqlParam);            return result.ex_pre_tp_hs;        }    }    return Material;};
 |