| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 | 'use strict';/** * 期计量 - 部位明细计量 * * @author Mai * @date 2018/12/8 * @version */const calcFields = ['contract_qty', 'qc_qty'];const auditConst = require('../const/audit');const timesLen = auditConst.stage.timesLen;module.exports = app => {    class StageBills extends app.BaseService {        /**         * 构造函数         *         * @param {Object} ctx - egg全局变量         * @return {void}         */        constructor(ctx) {            super(ctx);            this.tableName = 'stage_bills';        }        /**         * 查询期计量最后审核人数据         * @param {Number} tid - 标段id         * @param {Number} sid - 期id         * @param {Number|Array} lid - 台账节点id(可以为空)         * @returns {Promise<*>}         */        async getLastestStageData(tid, sid, lid) {            let lidSql = '', result;            if (lid) {                if (lid instanceof Array) {                    lidSql = lid.length > 0 ? ' And lid in (' + this.ctx.helper.getInArrStrSqlFilter(lid) + ')' : '';                } else {                    lidSql = ' And lid in (' + this.db.escape(lid) + ')';                }            }            const sql = 'SELECT Bills.* FROM ' + this.tableName + ' As Bills ' +                        '  INNER JOIN ( ' +                        '    SELECT MAX(`times` * ' + timesLen + ' + `order`) As `progress`, `lid`, `sid` From ' + this.tableName +                        '      WHERE tid = ? And sid = ?' + lidSql +                        '      GROUP BY `lid`' +                        '  ) As MaxFilter ' +                        '  ON (Bills.times * ' + timesLen + ' + `order`) = MaxFilter.progress And Bills.lid = MaxFilter.lid And Bills.`sid` = MaxFilter.`sid`';            const sqlParam = [tid, sid];            if (!lid) {                return await this.db.query(sql, sqlParam);            } else if (lid instanceof Array) {                return await this.db.query(sql, sqlParam);            } else {                return await this.db.queryOne(sql, sqlParam);            }        }        /**         * 查询 某期 某轮审批 某人数据         * @param {Number} tid - 标段id         * @param {Number} sid - 期id         * @param {Number} times - 第几轮         * @param {Number} order - 流程         * @param {Number|Array} lid - 台账节点id(可以为空)         * @returns {Promise<*>}         */        async getAuditorStageData(tid, sid, times, order, lid) {            const lidSql = lid ? ' And Bills.lid in (?)' : '';            const sql = 'SELECT Bills.* FROM ' + this.tableName + ' As Bills ' +                '  INNER JOIN ( ' +                '    SELECT MAX(`times` * ' + timesLen + ' + `order`) As `progress`, `lid`, `tid`, `sid` From ' + this.tableName +                '      WHERE `times` < ? OR (`times` = ? AND `order` <= ?) And tid = ? And sid = ?' + lidSql +                '      GROUP BY `lid`' +                '  ) As MaxFilter ' +                '  ON (Bills.times * ' + timesLen + ' + `order`) = MaxFilter.progress And Bills.lid = MaxFilter.lid' +                '    AND Bills.sid = MaxFilter.sid';            const sqlParam = [times, times, order, tid, sid];            if (!lid) {                return await this.db.query(sql, sqlParam);            } else if (lid instanceof Array) {                sqlParam.push(lid.join(', '));                return await this.db.query(sql, sqlParam);            } else {                sqlParam.push(lid);                return await this.db.queryOne(sql, sqlParam);            }        }        async getLastestStageData2(tid, sid, lid) {            let lidSql = '', result;            if (lid) {                if (lid instanceof Array) {                    lidSql = lid.length > 0 ? ' And lid in (' + this.ctx.helper.getInArrStrSqlFilter(lid) + ')' : '';                } else {                    lidSql = ' And lid in (' + this.db.escape(lid) + ')';                }            }            const sql = 'SELECT Bills.* FROM ' + this.tableName + ' As Bills ' +                '  INNER JOIN ( ' +                '    SELECT MAX(`times` * ' + timesLen + ' + `order`) As `progress`, `lid`, `sid` From ' + this.tableName +                '      WHERE tid = ? And sid = ?' + lidSql +                '      GROUP BY `lid`' +                '  ) As MaxFilter ' +                '  ON (Bills.times * ' + timesLen + ' + `order`) = MaxFilter.progress And Bills.lid = MaxFilter.lid And Bills.`sid` = MaxFilter.`sid`';            const sqlParam = [tid, sid];            if (!lid) {                return await this.db.query(sql, sqlParam);            } else if (lid instanceof Array) {                return await this.db.query(sql, sqlParam);            } else {                return await this.db.queryOne(sql, sqlParam);            }        }        async getUsedStageBills(tid, sid) {            const sql = 'SELECT Bills.lid, (Bills.contract_qty <> 0 and Bills.qc_qty <> 0) As used FROM ' + this.tableName + ' As Bills ' +                '  INNER JOIN ( ' +                '    SELECT MAX(`times` * ' + timesLen + ' + `order`) As `progress`, `lid`, `sid` From ' + this.tableName +                '      WHERE tid = ? And sid = ?' +                '      GROUP BY `lid`' +                '  ) As MaxFilter ' +                '  ON (Bills.times * ' + timesLen + ' + `order`) = MaxFilter.progress And Bills.lid = MaxFilter.lid And Bills.`sid` = MaxFilter.`sid`';            const sqlParam = [tid, sid];            const stageBills = await this.db.query(sql, sqlParam);            return this._.map(this._.filter(stageBills, 'used'), pid);        }        /**         * 获取截止本期数据         * @param {Number} tid - 标段id         * @param {Number} sorder - 截止期序号         * @param {String|Array[String]} lid - 台账id         * @returns {Promise<*>}         */        async getEndStageData(tid, sorder, lid) {            let lidSql = '';            if (lid) {                if (lid instanceof Array) {                    lidSql = lid.length > 0 ? ' And lid in (' + this.ctx.helper.getInArrStrSqlFilter(lid) + ')' : '';                } else {                    lidSql = ' And lid in (' + this.db.escape(lid) + ')';                }            }            const sql = 'SELECT Bills.tid, Bills.lid,' +                '  Sum(Bills.contract_qty) As contract_qty, Sum(Bills.contract_tp) As contract_tp,' +                '  Sum(Bills.qc_qty) As qc_qty, Sum(Bills.qc_tp) As qc_tp FROM ' + this.tableName + ' As Bills ' +                '  INNER JOIN ( ' +                '    SELECT MAX(`times` * ' + timesLen + ' + `order`) As `progress`, `lid`, `sid` From ' + this.tableName +                '      WHERE tid = ? ' + lidSql +                '      GROUP BY `lid`, `sid`' +                '  ) As MaxFilter ' +                '  ON (Bills.times * ' + timesLen + ' + `order`) = MaxFilter.progress And Bills.lid = MaxFilter.lid And Bills.`sid` = MaxFilter.`sid`' +                '  INNER JOIN ' + this.ctx.service.stage.tableName + ' As Stage' +                '  ON Bills.sid = Stage.id' +                '  WHERE Stage.order <= ?' +                '  GROUP BY `lid`';            const sqlParam = [tid, sorder];            if (!lid) {                return await this.db.query(sql, sqlParam);            } else if (lid instanceof Array) {                return await this.db.query(sql, sqlParam);            } else {                return await this.db.queryOne(sql, sqlParam);            }        }        async getStageBills(tid, sid, lid) {            const sql = 'SELECT Stage.*, Ledger.unit_price FROM ?? As Stage, ?? As Ledger ' +                        '  Where Stage.tid = ?, Stage.sid = ?, Stage.lid = ?, Stage.lid = Ledger.id ' +                        '  Order Stage.time DESC, Stage.order DESC ';            const sqlParam = [this.tableName, this.ctx.service.ledger.tableName];            sqlParam.push(this.db.escape(tid));            sqlParam.push(this.db.escape(sid));            sqlParam.push(this.db.escape(lid));            return await this.db.queryOne(sql, sqlParam);        }        async _insertStageBillsData(transaction, insertData, orgData, ledgerData) {            const info = this.ctx.tender.info;            const d = {                tid: this.ctx.tender.id,                lid: ledgerData.id,                sid: this.ctx.stage.id,                times: this.ctx.stage.curTimes,                order: this.ctx.stage.curOrder,                said: this.ctx.session.sessionUser.accountId,            };            if (orgData) {                d.contract_qty = orgData.contract_qty;                d.contract_tp = orgData.contract_tp;                d.qc_qty = orgData.qc_qty;                d.qc_tp = orgData.qc_tp;                d.postil = orgData.postil;            }            const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, ledgerData.unit);            if (insertData.contract_qty) {                d.contract_qty = this.round(insertData.contract_qty, precision.value);                d.contract_tp = this.ctx.helper.mul(d.contract_qty, ledgerData.unit_price, info.decimal.tp);            }            if (insertData.qc_qty) {                d.qc_qty = this.round(insertData.qc_qty, precision.value);                d.qc_tp = this.ctx.helper.mul(d.qc_qty, ledgerData.unit_price, info.decimal.tp);            }            if (insertData.postil) {                d.postil = insertData.postil;            }            await transaction.insert(this.tableName, d);        }        /**         * 前端提交数据         * @param {Object|Array} data - 提交的数据         * @returns {Promise<void>}         */        async updateStageData(data) {            const info = this.ctx.tender.info;            const datas = data instanceof Array ? data : [data];            const transaction = await this.db.beginTransaction();            try {                for (const d of datas) {                    const stageBills = await this.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, d.lid);                    const ledgerBills = await this.ctx.service.ledger.getDataById(d.lid);                    const precision = this.ctx.helper.findPrecision(info.precision, ledgerBills.unit);                    if (d.contract_qty !== undefined) {                        d.contract_qty = this.round(d.contract_qty, precision.value);                        d.contract_tp = this.ctx.helper.mul(d.contract_qty, ledgerBills.unit_price, info.decimal.tp);                    }                    if (d.qc_qty !== undefined) {                        d.qc_qty = this.round(d.qc_qty, precision.value);                        d.qc_tp = this.ctx.helper.mul(d.qc_qty, ledgerBills.unit_price, info.decimal.tp);                    }                    if (!stageBills || stageBills.times !== this.ctx.stage.curTimes || stageBills.order !== this.ctx.stage.curOrder) {                        await this._insertStageBillsData(transaction, d, stageBills, ledgerBills);                        // d.tid = this.ctx.tender.id;                        // d.sid = this.ctx.stage.id;                        // d.said = this.ctx.session.sessionUser.accountId;                        // d.times = this.ctx.stage.curTimes;                        // d.order = this.ctx.stage.curOrder;                        // await transaction.insert(this.tableName, d);                    } else {                        d.id = stageBills.id;                        await transaction.update(this.tableName, d);                    }                }                await transaction.commit();            } catch (err) {                await transaction.rollback();                throw err;            }            return await this.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, this._.map(datas, 'lid'));        }        /**         * 根据         * @param transaction         * @param ledgerBills         * @param stageBills         * @param data         * @returns {Promise<void>}         * @private         */        async updateStageBillsQty(transaction, ledgerBills, stageBills, data) {            const info = this.ctx.tender.info;            const precision = this.ctx.helper.findPrecision(info.precision, ledgerBills.unit);            const updateData = {};            if (data.contract_qty !== undefined) {                updateData.contract_qty = this.round(data.contract_qty, precision.value);                updateData.contract_tp = this.ctx.helper.mul(updateData.contract_qty, ledgerBills.unit_price, info.decimal.tp);            }            if (data.qc_qty !== undefined) {                updateData.qc_qty = this.round(data.qc_qty, precision.value);                updateData.qc_tp = this.ctx.helper.mul(updateData.qc_qty, ledgerBills.unit_price, info.decimal.tp);            }            if (stageBills) {                if ((updateData.contract_qty === undefined || stageBills.contract_qty !== updateData.contract_qty) ||                    (updateData.qc_qty === undefined || stageBills.qc_qty !== updateData.qc_qty)) {                    if (stageBills.times === this.ctx.stage.curTimes && stageBills.order === this.ctx.stage.curOrder) {                        updateData.id = stageBills.id;                        await transaction.update(this.tableName, updateData);                    } else {                        await this._insertStageBillsData(transaction, updateData, stageBills, ledgerBills);                    }                }            } else {                await this._insertStageBillsData(transaction, updateData, stageBills, ledgerBills);            }        };        /**         * 重算 本期计量 数量 (根据部位明细)         * @param {Number} tid - 标段id         * @param {Number} id - 需要计算的节点的id         * @param {Number} lid - 台账id         * @param {Object} transaction - 操作所属事务         * @returns {Promise<void>}         */        async calc(tid, sid, lid, transaction) {            const info = this.ctx.tender.info;            const stageBills = await this.getLastestStageData(tid, sid, lid);            const ledgerBills = await this.ctx.service.ledger.getDataById(lid);            if (!ledgerBills) {                throw '提交数据错误';            }            const posGather = await this.ctx.service.stagePos.getPosGather(tid, sid, lid, transaction);            if (!posGather) { return; }            const precision = this.ctx.helper.findPrecision(info.precision, ledgerBills.unit);            // 计算            if (posGather.contract_qty !== undefined) {                posGather.contract_qty = this.round(posGather.contract_qty, precision.value);                posGather.contract_tp = this.ctx.helper.mul(posGather.contract_qty, ledgerBills.unit_price, info.decimal.tp);            }            if (posGather.qc_qty !== undefined) {                posGather.qc_qty = this.round(posGather.qc_qty, precision.value);                posGather.qc_tp = this.ctx.helper.mul(posGather.qc_qty, ledgerBills.unit_price, info.decimal.tp);            }            if (stageBills) {                if (stageBills.contract_qty === posGather.contract_qty && stageBills.qc_qty === posGather.qc_qty) {                    return;                } else {                    const curOrder = this.ctx.stage.curAuditor ? this.ctx.stage.curAuditor.order : 0;                    if (stageBills.times === this.ctx.stage.curTimes && stageBills.order === this.ctx.stage.curOrder) {                        posGather.id = stageBills.id;                        await transaction.update(this.tableName, posGather);                    } else {                        await this._insertStageBillsData(transaction, posGather, stageBills, ledgerBills);                    }                }            } else {                await this._insertStageBillsData(transaction, posGather, stageBills, ledgerBills);            }        }        async getSumTotalPrice(stage) {            const sql = 'SELECT Sum(`contract_tp`) As `contract_tp`, Sum(`qc_tp`) As `qc_tp` FROM ' + this.tableName + ' As Bills ' +                '  INNER JOIN ( ' +                '    SELECT MAX(`times` * ' + timesLen + ' + `order`) As `flow`, `lid` From ' + this.tableName +                '      WHERE `times` <= ? AND `order` <= ?' +                '      GROUP BY `lid`' +                '  ) As MaxFilter ' +                '  ON (Bills.times * ' + timesLen + ' + `order`) = MaxFilter.flow And Bills.lid = MaxFilter.lid' +                '  WHERE Bills.sid = ?';            const sqlParam = [stage.curTimes, stage.curOrder, stage.id];            const result = await this.db.queryOne(sql, sqlParam);            return result;        }        async getSumTotalPriceFilter(stage, operate, filter) {            const sql = 'SELECT Sum(`contract_tp`) As `contract_tp`, Sum(`qc_tp`) As `qc_tp`' +                '  FROM ' + this.tableName + ' As Bills ' +                '  INNER JOIN ( ' +                '    SELECT MAX(`times` * ' + timesLen + ' + `order`) As `flow`, `lid` From ' + this.tableName +                '      WHERE `times` <= ? AND `order` <= ?' +                '      GROUP BY `lid`' +                '  ) As MaxFilter ' +                '  ON (Bills.times * ' + timesLen + ' + `order`) = MaxFilter.flow And Bills.lid = MaxFilter.lid ' +                '  INNER JOIN ' + this.ctx.service.ledger.tableName + ' As Ledger ON Bills.lid = Ledger.id' +                '  WHERE Bills.sid = ? And Ledger.b_code ' + operate + ' ?';            const sqlParam = [stage.times, stage.curAuditor ? stage.curAuditor.order : 0, stage.id, filter];            const result = await this.db.queryOne(sql, sqlParam);            return result;        }        async getSumTotalPriceGcl(stage, regText) {            if (regText) {                return await this.getSumTotalPriceFilter(stage, 'REGEXP', regText);            } else {                return await this.getSumTotalPriceFilter(stage, '<>', this.db.escape(''));            }        }        async getSumTotalPriceNotGcl(stage) {            return await this.getSumTotalPriceFilter(stage, '=', this.db.escape(''));        }    }    return StageBills;};
 |