'use strict'; const auditConst = require('../const/audit').advance; module.exports = app => { class Advance extends app.BaseService { constructor(ctx) { super(ctx); this.tableName = 'advance_pay'; } /** * 获取预付款列表 * @param {Number} tid - 标段id * @param {Number} type - 预付款类型 * @param {Number} decimal - 小数位数 * @param {Number} advancePayTotal - 预付款总额 */ async getAdvanceList(tid, type, decimal, advancePayTotal) { this.initSqlBuilder(); this.sqlBuilder.setAndWhere('tid', { value: tid, operate: '=', }); this.sqlBuilder.setAndWhere('type', { value: type, operate: '=', }); if (this.ctx.session.sessionUser.accountId !== this.ctx.tender.data.user_id) { this.sqlBuilder.setAndWhere('status', { value: auditConst.status.uncheck, operate: '!=', }); } this.sqlBuilder.orderBy = [['order', 'desc']]; const [sql, sqlParam] = this.sqlBuilder.build(this.tableName); const advance = await this.db.query(sql, sqlParam); for (const item of advance) { let s1, s3; const s2 = item.prev_amount.toString().split('.')[1]; item.pay_ratio = this.ctx.helper.mul(this.ctx.helper.div(item.cur_amount, advancePayTotal), 100, 2) || 0; if (item.status === auditConst.status.uncheck || item.status === auditConst.status.checkNo) { const cur_amount = item.cur_amount && this.ctx.helper.round(item.cur_amount, decimal) || 0; s1 = parseFloat(cur_amount).toString().split('.')[1]; s3 = parseFloat(this.ctx.helper.add(cur_amount, item.prev_amount)).toString().split('.')[1]; item.cur_amount = this.ctx.helper.formatMoney(cur_amount, ',', s1 && s1.length || 0); item.prev_total_amount = this.ctx.helper.formatMoney(this.ctx.helper.add(cur_amount, item.prev_amount), ',', s3 && s3.length || 0); } else { s1 = item.cur_amount && item.cur_amount.toString().split('.')[1]; s3 = item.prev_total_amount.toString().split('.')[1]; item.cur_amount = this.ctx.helper.formatMoney(item.cur_amount, ',', s1 && s1.length || 0); item.prev_total_amount = this.ctx.helper.formatMoney(item.prev_total_amount, ',', s3 && s3.length || 0); } item.prev_amount = this.ctx.helper.formatMoney(item.prev_amount, ',', s2 && s2.length || 0); item.curAuditor = await this.ctx.service.advanceAudit.getAuditorByStatus(item.id, item.status, item.times); if (item.status === auditConst.status.checkNoPre) { item.curAuditor2 = await this.ctx.service.advanceAudit.getAuditorByStatus(item.id, auditConst.status.checking); } item.fileList = await this.ctx.service.advanceFile.getAdvanceFiles({ vid: item.id }); } return advance; } /** * 获取预付款最新一期 * @param {Number} tid 标段id * @param {String} type 类型: 开工预付款|材料预付款 (0|1) * @param {Boolean} includeUnCheck 包括未上报的 * @return {Promise<*>} 实例结果集 */ async getLastestAdvance(tid, type, includeUnCheck = false) { this.initSqlBuilder(); this.sqlBuilder.setAndWhere('tid', { value: tid, operate: '=', }); this.sqlBuilder.setAndWhere('type', { value: type, 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 advance = await this.db.queryOne(sql, sqlParam); return advance; } async getSumAdvance(tid) { const sql = 'Select sum(cur_amount) as tp From ' + this.tableName + ' where tid = ?'; const result = await this.db.queryOne(sql, [tid]); return result ? result.tp : 0; } /** * 创建一条新的记录 * @param {String} type 类型: 开工预付款|材料预付款 (start|material) * @return {Promise<*>} 插入结果集 */ async createRecord(type) { const { ctx } = this; const uid = ctx.session.sessionUser.accountId; const tid = ctx.tender.id; let latestOrder = await this.getLastestAdvance(tid, type); if (!latestOrder) { latestOrder = { order: 1, prev_amount: 0, prev_total_amount: 0, }; } else { latestOrder.order = latestOrder.order + 1; } const record = await this.db.insert(this.tableName, { type, uid, tid, status: auditConst.status.uncheck, order: latestOrder.order, prev_amount: latestOrder.prev_total_amount, prev_total_amount: latestOrder.prev_total_amount }); const auditors = await ctx.service.advanceAudit.getAuditGroupByList(latestOrder.id, latestOrder.times); for (let idx = 0; idx < auditors.length; idx++) { const { audit_id } = auditors[idx]; await ctx.service.advanceAudit.db.insert(ctx.service.advanceAudit.tableName, { tid: latestOrder.tid, audit_id, type: latestOrder.type, vid: record.insertId, times: 1, order: idx + 1, status: 1, create_time: new Date(), }); } // auditors.forEach(async (auditor, idx) => { // const { audit_id } = auditor; // await ctx.service.advanceAudit.db.insert(ctx.service.advanceAudit.tableName, { // tid: latestOrder.tid, audit_id, type: latestOrder.type, vid: record.insertId, times: 1, order: idx + 1, status: 1, create_time: new Date(), // }); // }); return await this.getDataById(record.insertId); } /** * 获取上一期预付款记录 * @param {Number} tid 标段id * @param {Number} type 预付款类型 */ async getPreviousRecord(tid, type) { this.initSqlBuilder(); this.sqlBuilder.setAndWhere('tid', { value: tid, operate: '=', }); this.sqlBuilder.setAndWhere('type', { value: type, operate: '=', }); this.sqlBuilder.setAndWhere('order', { value: this.ctx.advance.order - 1, operate: '=', }); this.sqlBuilder.orderBy = [['order', 'desc']]; const [sql, sqlParam] = this.sqlBuilder.build(this.tableName); return await this.db.queryOne(sql, sqlParam); } /** * 计算列表进度条所需数据 * @param {Object} latest 最新期的数据 * @param {Number} payTotal 预付款金额总数 * @return {Object} progress所需数据 */ async calcProgress(latest, payTotal) { const { ctx } = this; if (!latest) { latest = { prev_total_amount: 0, prev_amount: 0, cur_amount: 0 }; } const surplus = ctx.helper.sub(payTotal, latest.prev_total_amount || 0); const p_ratio = ctx.helper.mul(ctx.helper.div(latest.prev_amount || 0, payTotal), 100, 2); // 截止上期金额总数 const c_ratio = ctx.helper.mul(ctx.helper.div(latest.cur_amount || 0, payTotal), 100, 2); // 截止本期金额总数 const s_ratio = ctx.helper.mul(ctx.helper.div(surplus, payTotal), 100, 2); // 剩余金额总数 return { p_amount: latest.prev_amount, c_amount: latest.cur_amount, s_amount: surplus, p_ratio, c_ratio, s_ratio, }; } /** * 更新预付款记录 * @param {Object} payload 载荷 * @param {Number} id 预付款id */ async updateAdvance(payload, id) { const { ctx } = this; const prevRecord = await this.getPreviousRecord(ctx.tender.id, ctx.advance.type) || { prev_total_amount: 0 }; const { cur_amount } = payload; payload.prev_total_amount = ctx.helper.add(cur_amount, prevRecord.prev_total_amount); return await this.update(payload, { id, }); } } return Advance; };