'use strict'; /** * * * @author Mai * @date 2021/11/9 * @version */ const defaultDecimal = { qty: 3, tp: 0, up: 2, }; const FinalObj = require('../lib/budget_final'); module.exports = app => { class Budget extends app.BaseService { /** * 构造函数 * * @param {Object} ctx - egg全局变量 * @return {void} */ constructor(ctx) { super(ctx); this.tableName = 'budget'; } /** * 数据规则 * * @param {String} scene - 场景 * @return {Object} - 返回数据规则 */ rule(scene) { let rule = {}; switch (scene) { case 'add': rule = { name: { type: 'string', required: true, min: 2 }, std_id: { type: 'string', required: true, min: 1 }, }; break; case 'save': rule = { name: { type: 'string', required: true, min: 2, max: 100, }, }; default: break; } return rule; } async getBudget(admin) { let result = await this.getAllDataByCondition({ where: { pid: this.ctx.session.sessionProject.id }, orders: [['name', 'asc']], }); if (admin) return result; const permissionConst = this.ctx.service.subProjPermission.PermissionConst.budget; const permissionBudget = await this.ctx.service.subProjPermission.getUserPermission(); result = result.filter(x => { const pb = permissionBudget.find(y => { return x.id === y.bid}); if (pb) { x.canEdit = pb.budget_permission.indexOf(permissionConst.edit.value) >= 0; } return !!pb; }); return result; } async getCurBudget(id) { const result = await this.getDataById(id); result.decimal = result.decimal ? JSON.parse(result.decimal) : {}; this.ctx.helper._.defaults(result.decimal, defaultDecimal); return result; } /** * 新增标段 * * @param {Object} data - 提交的数据 * @return {Boolean} - 返回新增结果 */ async add(transaction, data, budgetStd) { if (!transaction) throw '数据错误'; data.in_time = new Date(); data.std_id = budgetStd.id; const operate = await transaction.insert(this.tableName, data); if (operate.insertId === 0) throw '初始化动态投资数据失败'; // 获取合同支付模板 并添加到标段 await this.ctx.service.budgetGu.initByTemplate(transaction, operate.insertId, budgetStd.gu_template_id); await this.ctx.service.budgetGai.initByTemplate(transaction, operate.insertId, budgetStd.gai_template_id); await this.ctx.service.budgetYu.initByTemplate(transaction, operate.insertId, budgetStd.yu_template_id); return operate.insertId; } /** * 保存标段 * * @param {Number} id * @param {Object} postData - 表单post过来的数 * @return {Boolean} - 返回执行结果 */ async save(data) { const result = await this.db.update(this.tableName, data); return result.affectedRows > 0; } /** * 假删除 * * @param {Number} id - 删除的id * @return {Boolean} - 删除结果 */ async deleteBudget(id) { const updateData = { id, status: this.status.DISABLE }; const result = await this.db.update(this.tableName, updateData); return result.affectedRows > 0; } /** * 真删除 * @param {Number} id - 删除的标段id * @return {Promise} - 结果 */ async deleteBudgetNoBackup(id) { const transaction = await this.db.beginTransaction(); try { await transaction.delete(this.tableName, { id }); await transaction.delete(this.ctx.service.budgetGu.tableName, { bid: id }); await transaction.delete(this.ctx.service.budgetGai.tableName, { bid: id }); await transaction.delete(this.ctx.service.budgetYu.tableName, { bid: id }); await transaction.commit(); return true; } catch (err) { this.ctx.log(err); await transaction.rollback(); return false; } } async _getGuUpdateData(newDecimal, orgDecimal) { if (newDecimal.qty >= orgDecimal.qty && newDecimal.tp >= orgDecimal.tp) return []; const datas = await this.ctx.service.budgetGu.getData(this.ctx.budget.id); const result = []; for (const d of datas) { const dgn_qty1 = this.ctx.helper.round(d.dgn_qty1, newDecimal.qty); const dgn_qty2 = this.ctx.helper.round(d.dgn_qty2, newDecimal.qty); const total_price = d.is_leaf ? this.ctx.helper.round(d.total_price, newDecimal.tp) : 0; if (dgn_qty1 !== d.dgn_qty1 || dgn_qty2 !== d.dgn_qty2 || total_price !== d.total_price) { result.push({ id: d.id, tree_id: d.tree_id, dgn_qty1, dgn_qty2, total_price }); } } return result; } async _getGaiUpdateData(newDecimal, orgDecimal) { if (newDecimal.qty >= orgDecimal.qty && newDecimal.tp >= orgDecimal.tp) return []; const datas = await this.ctx.service.budgetGai.getData(this.ctx.budget.id); const result = []; for (const d of datas) { const dgn_qty1 = this.ctx.helper.round(d.dgn_qty1, newDecimal.qty); const dgn_qty2 = this.ctx.helper.round(d.dgn_qty2, newDecimal.qty); const total_price = d.is_leaf ? this.ctx.helper.round(d.total_price, newDecimal.tp) : 0; if (dgn_qty1 !== d.dgn_qty1 || dgn_qty2 !== d.dgn_qty2 || total_price !== d.total_price) { result.push({ id: d.id, tree_id: d.tree_id, dgn_qty1, dgn_qty2, total_price }); } } return result; } async _getYuUpdateData(newDecimal, orgDecimal) { if (newDecimal.qty >= orgDecimal.qty && newDecimal.up >= orgDecimal.up && newDecimal.tp === orgDecimal.tp) return []; const datas = await this.ctx.service.budgetYu.getData(this.ctx.budget.id); const result = []; for (const d of datas) { if (d.b_code) { if (!d.is_leaf) continue; const quantity = this.ctx.helper.round(d.quantity, newDecimal.qty); const unit_price = this.ctx.helper.round(d.unit_price, newDecimal.up); const total_price = this.ctx.helper.mul(unit_price, quantity, newDecimal.tp); if (quantity !== d.quantity || unit_price !== d.unit_price || total_price !== d.total_price) { result.push({ id: d.id, tree_id: d.tree_id, quantity, unit_price, total_price }); } } else { const dgn_qty1 = this.ctx.helper.round(d.dgn_qty1, newDecimal.qty); const dgn_qty2 = this.ctx.helper.round(d.dgn_qty2, newDecimal.qty); const total_price = d.is_leaf ? this.ctx.helper.round(d.total_price, newDecimal.tp) : 0; if (dgn_qty1 !== d.dgn_qty1 || dgn_qty2 !== d.dgn_qty2 || total_price !== d.total_price) { result.push({ id: d.id, tree_id: d.tree_id, dgn_qty1, dgn_qty2, total_price }); } } } return result; } async saveDecimal(decimal, page) { const newDecimal = JSON.parse(JSON.stringify(this.ctx.budget.decimal)); if (decimal.qty >= 0 && decimal.qty <= 6) newDecimal.qty = decimal.qty; if (decimal.up >= 0 && decimal.up <= 6) newDecimal.up = decimal.up; if (decimal.tp >= 0 && decimal.tp <= 6) newDecimal.tp = decimal.tp; const guDatas = await this._getGuUpdateData(newDecimal, this.ctx.budget.decimal); const gaiDatas = await this._getGaiUpdateData(newDecimal, this.ctx.budget.decimal); const yuDatas = await this._getYuUpdateData(newDecimal, this.ctx.budget.decimal); const conn = await this.db.beginTransaction(); try { const result = await conn.update(this.tableName, { id: this.ctx.budget.id, decimal: JSON.stringify(newDecimal) }); if (guDatas.length > 0) await conn.updateRows(this.ctx.service.budgetGu.tableName, guDatas); if (gaiDatas.length > 0) await conn.updateRows(this.ctx.service.budgetGai.tableName, gaiDatas); if (yuDatas.length > 0) await conn.updateRows(this.ctx.service.budgetYu.tableName, yuDatas); await conn.commit(); switch (page) { case 'gu': return { update: guDatas }; case 'gai': return { update: gaiDatas }; case 'yu': return { update: yuDatas }; } } catch (err) { await conn.rollback(); throw err; } } async doFinal(budget, final) { const finalObj = new FinalObj(this.ctx); let finalData; try { finalData = await finalObj.doFinal(budget, final); } catch (err) { this.db.update(this.ctx.service.budgetFinalList.tableName, { id: final.id, status: 4}); this.ctx.log(err); throw '生成决算数据错误'; } const conn = await this.db.beginTransaction(); try { await conn.update(this.tableName, {id: budget.id, final_id: final.id, final_time: new Date() }); await conn.insert(this.ctx.service.budgetFinal.tableName, finalData); await conn.update(this.ctx.service.budgetFinalList.tableName, { id: final.id, tender_info: JSON.stringify(final.tender_info), status: 3}); await conn.commit(); return finalData; } catch (err) { this.ctx.log(err); await conn.rollback(); this.db.update(this.ctx.service.budgetFinalList.tableName, { id: final.id, status: 4}); throw '保存决算数据错误'; } } } return Budget; };