'use strict'; /** * 期计量 数据模型 * * @author Mai * @date 2018/8/13 * @version */ const auditConst = require('../const/audit').stage; const payConst = require('../const/deal_pay.js'); module.exports = app => { class Stage extends app.BaseService { /** * 构造函数 * * @param {Object} ctx - egg全局变量 * @return {void} */ constructor(ctx) { super(ctx); this.tableName = 'stage'; } /** * 获取 最新一期 期计量 * @param tenderId * @param includeUnCheck * @returns {Promise<*>} */ async getLastestStage(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 stage = await this.db.queryOne(sql, sqlParam); return stage; } /** * 获取 最新一期 审批完成的 期计量 * @param tenderId * @returns {Promise<*>} */ async getLastestCompleteStage(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 stage = await this.db.queryOne(sql, sqlParam); return stage; } /** * 获取标段下的全部计量期,按倒序 * @param tenderId * @returns {Promise} */ async getValidStages(tenderId) { const stages = await this.db.select(this.tableName, { where: {tid: tenderId}, orders: [['order', 'desc']], }); for (const s of stages) { s.tp = this.ctx.helper.add(s.contract_tp, s.qc_tp); s.pre_tp = this.ctx.helper.add(s.pre_contract_tp, s.pre_qc_tp); s.end_tp = this.ctx.helper.add(s.pre_tp, s.tp); } if (stages.length !== 0) { const lastStage = stages[stages.length - 1]; if (lastStage.status === auditConst.status.uncheck && lastStage.user_id !== this.ctx.session.sessionUser.accountId) { stages.splice(stages.length - 1, 1); } } // 最新一期计量(未审批完成),当前操作人的期详细数据,应实时计算 if (stages.length > 0 && stages[0].status !== auditConst.status.checked) { const stage = stages[0]; const curAuditor = await this.ctx.service.stageAudit.getCurAuditor(stage.id, stage.times); const isActive = curAuditor ? curAuditor.id === this.ctx.session.sessionUser.accountId : stage.user_id === this.ctx.session.sessionUser.accountId; if (isActive) { const tpData = await this.ctx.service.stageBills.getSumTotalPrice(stage); stage.contract_tp = tpData.contract_tp; stage.qc_tp = tpData.qc_tp; stage.tp = this.ctx.helper.add(stage.contract_tp, stage.qc_tp); stage.end_tp = this.ctx.helper.add(stage.pre_tp, stage.tp); } } return stages; } /** * * @param tenderId - 标段id * @param date - 计量年月 * @param period - 开始-截止日期 * @returns {Promise} */ async addStage(tenderId, date, period) { const stages = await this.getAllDataByCondition({ where: {tid: tenderId}, order: ['order'], }); const preStage = stages[stages.length - 1]; if (stages.length > 0 && stages[stages.length - 1].status !== auditConst.status.checked) { throw '上一期未审批通过,请等待上一期审批通过后,再新增数据'; }; const order = stages.length + 1; const newStage = { sid: this.uuid.v4(), tid: tenderId, order: order, in_time: new Date(), s_time: date, period: period, times: 1, status: auditConst.status.uncheck, user_id: this.ctx.session.sessionUser.accountId, }; if (preStage) { newStage.pre_contract_tp = this.ctx.helper.add(preStage.pre_contract_tp, preStage.contract_tp); newStage.pre_qc_tp = this.ctx.helper.add(preStage.pre_qc_tp, preStage.qc_tp); } const transaction = await this.db.beginTransaction(); try { // 新增期记录 const result = await transaction.insert(this.tableName, newStage); if (result.affectedRows === 1) { newStage.id = result.insertId; } else { throw '新增期数据失败'; } // 存在上一期时,复制上一期审批流程 if (preStage) { const auditResult = await this.ctx.service.stageAudit.copyPreStageAuditors(transaction, preStage, newStage); if (!auditResult) { throw '复制上一期审批流程失败'; } } // 新增期合同支付数据 const dealResult = await this.ctx.service.stagePay.addInitialStageData(newStage, transaction); if (!dealResult) { throw '新增期合同支付数据失败'; } await transaction.commit(); return newStage; } catch (err) { await transaction.rollback(); throw err; } } /** * 编辑计量期 * * @param {Number} tenderId - 标段Id * @param {Number} order - 第N期 * @param {String} date - 计量年月 * @param {String} period - 开始-截止时间 * @returns {Promise} */ async saveStage(tenderId, order, date, period) { await this.db.update(this.tableName, { s_time: date, period: period, }, { where: { tid: tenderId, order: order } }); } /** * 设置 中间计量 生成规则,并生成数据 * @param {Number} tenderId - 标段id * @param {Number} order - 期序号 * @param {Number} data - 中间计量生成规则 * @returns {Promise} */ async buildDetailData(tenderId, order, data) { const conn = await this.db.beginTransaction(); try { await conn.update(this.tableName, { im_type: data.im_type, im_pre: data.im_pre }, { where: { tid: tenderId, order: order } }); // to do 生成中间计量数据 await conn.commit(); } catch (err) { await conn.rollback(); throw err; } } /** * 获取 当期的 计算基数 * @returns {Promise} */ async getStagePayCalcBase() { const calcBase = JSON.parse(JSON.stringify(payConst.calcBase)); const param = this.ctx.tender.info.deal_param; for (const cb of calcBase) { switch (cb.code) { case 'htj': cb.value = param.contractPrice; break; case 'zlje': cb.value = param.zanLiePrice; break; case 'htjszl': cb.value = this.ctx.helper.sub(param.contractPrice, param.zanLiePrice); break; case 'kgyfk': cb.value = param.startAdvance; break; case 'clyfk': cb.value = param.materialAdvance; break; case 'bqwc': const sum = await this.ctx.service.stageBills.getSumTotalPrice(this.ctx.stage); cb.value = this.ctx.helper.add(sum.contract_tp, sum.qc_tp); break; case 'ybbqwc': const sumGcl = await this.ctx.service.stageBills.getSumTotalPriceGcl(this.ctx.stage, '^1[0-9]{2}-'); cb.value = this.ctx.helper.add(sumGcl.contract_tp, sumGcl.qc_tp); break; default: cb.value = 0; } } return calcBase; } /** * 更新 check_detail 标识 * @param {Integer}sid - 期id * @param {Boolean}check - 标记 * @returns {Promise} */ async updateCheckDetailFlag(sid, check) { const result = await this.db.update(this.tableName, {id: sid, check_detail: check}); return result.affectedRows === 1; } } return Stage; };