Quellcode durchsuchen

补充合同功能

ellisran vor 2 Monaten
Ursprung
Commit
6a6e19ec49

+ 49 - 24
app/controller/contract_controller.js

@@ -406,26 +406,36 @@ module.exports = app => {
         async checkAudit(ctx) {
             try {
                 const data = JSON.parse(ctx.request.body.data);
-                if (!data.postType || !data.id) throw '数据错误';
+                if (!data.postType || !data.id || !data.type) throw '数据错误';
                 const responseData = {
                     err: 0, msg: '', data: {},
                 };
-                const contract = isNaN(data.id) ? await ctx.service.contract.getDataById(data.id) : await ctx.service.contractPay.getDataById(data.id);
+                const contract = await this._getContractByType(ctx, data);
                 if (!contract) {
                     throw '未找到合同相关数据';
                 }
-                const tip = isNaN(data.id) ? '' : contractConst.typeName[contract.contract_type];
+                let tip = '';
                 // 判断功能是否已关闭
                 const shenpi_status = ctx.contract_tender ? ctx.subProject.page_show.openContractTenderShenpi : ctx.subProject.page_show.openContractSubProjectShenpi;
                 const pay_shenpi_status = ctx.contract_tender ? ctx.subProject.page_show.openContractPayTenderShenpi : ctx.subProject.page_show.openContractPaySubProjectShenpi;
-                if (isNaN(data.id)) {
-                    if (!shenpi_status) {
-                        throw '合同审批功能已关闭, 无法进行审批操作, 请刷新页面';
-                    }
-                } else {
-                    if (!pay_shenpi_status) {
-                        throw '合同' + tip + '审批功能已关闭, 无法进行审批操作, 请刷新页面';
-                    }
+                switch (data.type) {
+                    case 'contract':
+                        if (!shenpi_status) {
+                            throw '合同审批功能已关闭, 无法进行审批操作, 请刷新页面';
+                        }
+                        break;
+                    case 'pay':
+                        if (!pay_shenpi_status) {
+                            throw '合同' + tip + '审批功能已关闭, 无法进行审批操作, 请刷新页面';
+                        }
+                        tip = contractConst.typeName[contract.contract_type];
+                        break;
+                    case 'supplement':
+                        if (!shenpi_status) {
+                            throw '合同审批功能已关闭, 无法进行审批操作, 请刷新页面';
+                        }
+                        break;
+                    default: throw '数据错误';
                 }
                 let shenpi = '';
                 if (ctx.contract_tender) {
@@ -434,16 +444,14 @@ module.exports = app => {
                 } else {
                     shenpi = ctx.subProject.shenpi;
                 }
-                await ctx.service.contractSpAudit.loadUser(contract);
-                await ctx.service.contractSpAudit.loadAuditViewData(contract);
-                const cid = contract.cid ? contract.cid : contract.id;
-                const cpid = contract.cid ? contract.id : null;
+                await ctx.service.contractSpAudit.loadUser(contract, data.type);
+                await ctx.service.contractSpAudit.loadAuditViewData(contract, data.type);
                 switch (data.postType) {
                     case 'start':
                         if (contract.status !== auditConst.contract.status.uncheck && contract.status !== auditConst.contract.status.checkNo) {
                             throw '该合同' + tip + '当前无法上报';
                         }
-                        await ctx.service.contractSpAudit.start(ctx.contractOptions, shenpi, cid, cpid, contract.times);
+                        await ctx.service.contractSpAudit.start(ctx.contractOptions, shenpi, contract, data.type, contract.times);
                         break;
                     case 'check':
                         if (contract.status !== auditConst.contract.status.checking && contract.status !== auditConst.contract.status.checkNoPre) {
@@ -459,7 +467,7 @@ module.exports = app => {
                         if (!checkData.checkType || isNaN(checkData.checkType)) {
                             throw '提交数据错误';
                         }
-                        await ctx.service.contractSpAudit.check(contract, checkData);
+                        await ctx.service.contractSpAudit.check(contract, data.type, checkData);
                         break;
                     case 'add-audit':
                         if (shenpi.contract === shenpiConst.sp_status.gdspl) {
@@ -477,7 +485,7 @@ module.exports = app => {
                             throw '当前不允许添加审核人';
                         }
 
-                        const auditorList = await ctx.service.contractSpAudit.getAuditors(cid, cpid, contract.times, 'asc', true);
+                        const auditorList = await ctx.service.contractSpAudit.getAuditors(contract, data.type, contract.times, 'asc', true);
                         // 检查审核人是否已存在
                         const exist = this.app._.find(auditorList, { aid: add_id });
                         if (exist) {
@@ -486,7 +494,7 @@ module.exports = app => {
                         const shenpiCondition = ctx.helper._.assign({ sp_type: shenpiConst.sp_type.contract, sp_status: shenpiConst.sp_status.gdzs }, ctx.contractOptions);
                         const shenpiInfo = await ctx.service.shenpiAudit.getDataByCondition(shenpiCondition);
                         const is_gdzs = shenpiInfo && shenpi.contract === shenpiConst.sp_status.gdzs ? 1 : 0;
-                        const add_result = await ctx.service.contractSpAudit.addAuditor(ctx.contractOptions, cid, cpid, add_id, contract.times, is_gdzs);
+                        const add_result = await ctx.service.contractSpAudit.addAuditor(ctx.contractOptions, contract, data.type, add_id, contract.times, is_gdzs);
                         if (!add_result) {
                             throw '添加审核人失败';
                         }
@@ -507,7 +515,7 @@ module.exports = app => {
                             throw '当前不允许移除审核人';
                         }
 
-                        const del_result = await ctx.service.contractSpAudit.deleteAuditor(cid, cpid, del_id, contract.times);
+                        const del_result = await ctx.service.contractSpAudit.deleteAuditor(contract, data.type, del_id, contract.times);
                         if (!del_result) {
                             throw '移除审核人失败';
                         }
@@ -519,7 +527,7 @@ module.exports = app => {
                         if (contract.status !== auditConst.contract.status.uncheck && contract.status !== auditConst.contract.status.checkNo) {
                             throw '当前状态不允许切换审批组';
                         }
-                        const chagne_result = await ctx.service.contractSpAudit.changeSpGroup(contract, data.sp_group);
+                        const chagne_result = await ctx.service.contractSpAudit.changeSpGroup(contract, data.type, data.sp_group);
                         if (!chagne_result) {
                             throw '切换审批组失败';
                         }
@@ -527,9 +535,9 @@ module.exports = app => {
                     default:
                         throw '参数错误';
                 }
-                const newContract = isNaN(data.id) ? await ctx.service.contract.getDataById(data.id) : await ctx.service.contractPay.getDataById(data.id);
-                await ctx.service.contractSpAudit.loadUser(newContract);
-                await ctx.service.contractSpAudit.loadAuditViewData(newContract);
+                const newContract = await this._getContractByType(ctx, data);
+                await ctx.service.contractSpAudit.loadUser(newContract, data.type);
+                await ctx.service.contractSpAudit.loadAuditViewData(newContract, data.type);
                 responseData.data = newContract;
                 ctx.body = responseData;
             } catch (err) {
@@ -539,6 +547,23 @@ module.exports = app => {
             }
         }
 
+        async _getContractByType(ctx, data) {
+            let contract = null;
+            switch (data.type) {
+                case 'contract':
+                    contract = await ctx.service.contract.getDataById(data.id);
+                    break;
+                case 'pay':
+                    contract = await ctx.service.contractPay.getDataById(data.id);
+                    break;
+                case 'supplement':
+                    contract = await ctx.service.contractSupplement.getDataById(data.id);
+                    break;
+                default: throw '数据错误';
+            }
+            return contract;
+        }
+
         async updateBills(ctx) {
             try {
                 const data = JSON.parse(ctx.request.body.data);

+ 126 - 37
app/public/js/contract_detail.js

@@ -153,7 +153,7 @@ $(document).ready(function() {
     };
     const contractTree = createNewPathTree('revise', treeSetting);
 
-    const contractDetail = ['c_code', 'name', 'total_price', 'pay_price', 'debit_price','yf_price', 'sf_price', 'party_a', 'party_a_user', 'party_b', 'party_b_user', 'sign_date', 'address', 'entity', 'bank', 'bank_account', 'remark', 'settle_code', 'tax', 'create_time'];
+    const contractDetail = ['c_code', 'name', 'price', 'supplement_price', 'pay_price', 'debit_price','yf_price', 'sf_price', 'party_a', 'party_a_user', 'party_b', 'party_b_user', 'sign_date', 'address', 'entity', 'bank', 'bank_account', 'remark', 'settle_code', 'tax', 'create_time'];
 
     // 清单 相关方法&绑定spreadjs事件
     const contractTreeSpreadObj = {
@@ -349,6 +349,17 @@ $(document).ready(function() {
                         } else if (c === 'sign_date') {
                             $('#htdetail_' + c).text(node[c] ? moment(node[c]).format('YYYY-MM-DD') : '');
                             continue;
+                        } else if (c === 'price') {
+                            $('#htdetail_' + c).text(node.total_price || '');
+                            continue;
+                        } else if (c === 'supplement_price') {
+                            if (node[c]) {
+                                $('#show-supplement-price').show();
+                            } else {
+                                $('#show-supplement-price').hide();
+                            }
+                            $('#show-supplement-price').attr('data-original-title', '含补充合同金额:' + node[c]);
+                            continue;
                         }
                         $('#htdetail_' + c).text(node[c] || '');
                     }
@@ -662,6 +673,17 @@ $(document).ready(function() {
                     } else if (c === 'sign_date') {
                         $('#htdetail_' + c).text(node[c] ? moment(node[c]).format('YYYY-MM-DD') : '');
                         continue;
+                    } else if (c === 'price') {
+                        $('#htdetail_' + c).text(node.total_price || '');
+                        continue;
+                    } else if (c === 'supplement_price') {
+                        if (node[c]) {
+                            $('#show-supplement-price').show();
+                        } else {
+                            $('#show-supplement-price').hide();
+                        }
+                        $('#show-supplement-price').attr('data-original-title', '含补充合同金额:' + node[c]);
+                        continue;
                     }
                     $('#htdetail_' + c).text(node[c] || '');
                 }
@@ -1849,6 +1871,8 @@ $(document).ready(function() {
                     } else if (c === 'tax') {
                         $('#htdetail_' + c).html('<input type="number" min="0" max="100" step="1" class="form-control form-control-sm" value="' + (node[c] ? node[c] : '') + '">');
                         continue;
+                    } else if (c === 'supplement_price') {
+                        continue;
                     }
                     $('#htdetail_' + c).html('<input type="text" class="form-control form-control-sm" value="' + node[c] + '">');
                 }
@@ -1878,18 +1902,21 @@ $(document).ready(function() {
                     } else if (c === 'remark') {
                         data[c] = $('#htdetail_' + c + ' textarea').val();
                         continue;
+                    } else if (c === 'supplement_price') {
+                       continue;
                     }
                     data[c] = $('#htdetail_' + c + ' input').val();
                 }
             }
+            data.total_price = ZhCalc.add(node.supplement_price, parseFloat(data.price));
             if (data.c_code === '' || data.name === '') {
                 toastr.warning('合同编号和合同名称不能为空');
                 return;
             }
-            if (data.total_price === '') {
+            if (data.price === '') {
                 toastr.warning('合同金额不能为空');
                 return;
-            } else if (!/^\d+(\.\d+)?$/.test(data.total_price)) {
+            } else if (!/^\d+(\.\d+)?$/.test(data.price)) {
                 toastr.warning('合同金额只能输入数字');
                 return;
             }
@@ -1960,6 +1987,10 @@ $(document).ready(function() {
                 if ($('#htdetail_' + c) && $('#htdetail_' + c).hasClass('change-input-td')) {
                     if (c === 'sign_date') {
                         $('#htdetail_' + c).text(node[c] ? moment(node[c]).format('YYYY-MM-DD') : '');
+                    } else if (c === 'price') {
+                        $('#htdetail_' + c).text(node.total_price || '');
+                    } else if (c === 'supplement_price') {
+                        continue;
                     } else {
                         $('#htdetail_' + c).html(node[c]);
                     }
@@ -2188,6 +2219,17 @@ $(document).ready(function() {
             toastr.warning('已结算的合同不能删除补充合同');
             return;
         }
+        const supplementInfo = _.find(contractSupplements, { id: csid });
+        const oldPrice = supplementInfo ? supplementInfo.price : 0;
+        let supplement_price = ZhCalc.sum(_.map(contractSupplements, 'price'));
+        // data.price 汇总入supplement_price并去除原有值
+        supplement_price = ZhCalc.sub(supplement_price, oldPrice);
+        const total_price = ZhCalc.add(node.price, supplement_price);
+        if (parseFloat(total_price) < node.yf_price) {
+            const name = contract_type === contractConst.type.expenses ? '付' : '回';
+            toastr.error('不能删除,因删除后总合同金额汇总会小于累计应' + name + '金额 ' + node.yf_price);
+            return;
+        }
         deleteAfterHint(function () {
             postData(window.location.pathname + '/update', {postType: 'del-contract-supplement', postData: { select: node.id, supplement: csid }}, function (result) {
                 const refreshNode = contractTree.loadPostData(result.node);
@@ -2610,7 +2652,7 @@ $(document).ready(function() {
         $('#cons-add').on('show.bs.modal', function () {
             $('#cons-add input[name="code"]').val('');
             $('#cons-add input[name="name"]').val('');
-            $('#cons-add input[name="total_price"]').val('');
+            $('#cons-add input[name="price"]').val('');
             $('#cons-add input[name="party_a"]').val('');
             $('#cons-add input[name="party_b"]').val('');
             $('#cons-add input[name="sign_date"]').val('');
@@ -2628,7 +2670,7 @@ $(document).ready(function() {
             const data = {
                 code: $('#cons-add input[name="code"]').val(),
                 name: $('#cons-add input[name="name"]').val(),
-                total_price: $('#cons-add input[name="total_price"]').val(),
+                price: $('#cons-add input[name="price"]').val(),
                 party_a: $('#cons-add input[name="party_a"]').val(),
                 party_b: $('#cons-add input[name="party_b"]').val(),
                 sign_date: $('#cons-add input[name="sign_date"]').val() || null,
@@ -2643,12 +2685,12 @@ $(document).ready(function() {
                 toastr.error('请输入合同名称');
                 return;
             }
-            if (!data.total_price) {
+            if (!data.price) {
                 toastr.error('请输入合同金额');
                 return;
             }
             // 金额只能输入数字
-            if (!/^\d+(\.\d+)?$/.test(data.total_price)) {
+            if (!/^\d+(\.\d+)?$/.test(data.price)) {
                 toastr.error('合同金额只能输入数字');
                 return;
             }
@@ -2951,7 +2993,7 @@ $(document).ready(function() {
             address: $('#cons-addsupplement input[name="address"]').val(),
             content: $('#cons-addsupplement textarea[name="content"]').val(),
         }
-        if (!judgeSupplements(data)) {
+        if (!judgeSupplements(data, node)) {
             return;
         }
         console.log(node, data);
@@ -3001,7 +3043,7 @@ $(document).ready(function() {
             address: $('#cons-addsupplement input[name="address"]').val(),
             content: $('#cons-addsupplement textarea[name="content"]').val(),
         }
-        if (!judgeSupplements(data)) {
+        if (!judgeSupplements(data, node)) {
             return;
         }
         console.log(node, data);
@@ -3019,7 +3061,7 @@ $(document).ready(function() {
         })
     });
 
-    function judgeSupplements(data) {
+    function judgeSupplements(data, node) {
         let flag = true;
         if (!data.code) {
             toastr.error('请输入编号');
@@ -3029,7 +3071,6 @@ $(document).ready(function() {
             toastr.error('请输入名称');
             return false;
         }
-        console.log(data.price);
         if (data.price === '') {
             toastr.error('请输入金额');
             return false;
@@ -3039,6 +3080,17 @@ $(document).ready(function() {
             toastr.error('金额只能输入数字');
             return false;
         }
+        const oldPrice = data.id ? (_.find(contractSupplements, { id: data.id }) || {}).price : 0;
+        const newPrice = parseFloat(data.price);
+        let supplement_price = ZhCalc.sum(_.map(contractSupplements, 'price'));
+        // data.price 汇总入supplement_price并去除原有值
+        supplement_price = ZhCalc.add(ZhCalc.sub(supplement_price, oldPrice), newPrice);
+        const total_price = ZhCalc.add(node.price, supplement_price);
+        if (parseFloat(total_price) < node.yf_price) {
+            const name = contract_type === contractConst.type.expenses ? '付' : '回';
+            toastr.error('总合同金额汇总不能小于累计应' + name + '金额 ' + node.yf_price);
+            return;
+        }
         return flag;
     }
 
@@ -3194,24 +3246,24 @@ $(document).ready(function() {
             }
             shenpi_html += !reload ? `<td class="shenpi-td ${auditConst.auditProgressClass[pay.status]}">` : '';
             if ((pay.status === auditConst.status.uncheck || pay.status === auditConst.status.checkNo) && pay.uid === user_id) {
-                shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-cpid="${pay.id}" class="btn ${auditConst.statusButtonClass[pay.status]} btn-sm show-sub-sp">${auditConst.statusButton[pay.status]}</a>`;
+                shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-csid="${pay.id}" class="btn ${auditConst.statusButtonClass[pay.status]} btn-sm show-sub-sp">${auditConst.statusButton[pay.status]}</a>`;
             } else if ((pay.status === auditConst.status.checking || pay.status === auditConst.status.checkNoPre) && pay.curAuditors && pay.curAuditors.findIndex(x => { return x.aid === user_id; }) >= 0) {
-                shenpi_html += `<a href="javascript: void(0);" node-cid="${pay.cid}" node-cpid="${pay.id}" data-operate="checked" data-title="审批通过" class="btn btn-success btn-sm mr-2 show-sp-list">审批通过</a>`;
-                shenpi_html += `<a href="javascript: void(0);" node-cid="${pay.cid}" node-cpid="${pay.id}" data-operate="checkNo" data-title="审批退回" class="btn btn-warning btn-sm show-sp-list">审批退回</a>`;
+                shenpi_html += `<a href="javascript: void(0);" node-cid="${pay.cid}" node-csid="${pay.id}" data-operate="checked" data-title="审批通过" class="btn btn-success btn-sm mr-2 show-sp-list">审批通过</a>`;
+                shenpi_html += `<a href="javascript: void(0);" node-cid="${pay.cid}" node-csid="${pay.id}" data-operate="checkNo" data-title="审批退回" class="btn btn-warning btn-sm show-sp-list">审批退回</a>`;
             } else {
                 if (pay.status === auditConst.status.checked && pay.final_auditor_str) {
-                    shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-cpid="${pay.id}" class="show-sp-list">${pay.final_auditor_str}</a>`;
+                    shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-csid="${pay.id}" class="show-sp-list">${pay.final_auditor_str}</a>`;
                 } else if (pay.status === auditConst.status.checkNo && pay.curAuditors2 && pay.curAuditors2.length > 0) {
                     if (pay.curAuditors2[0].audit_type === auditType.key.common) {
-                        shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-cpid="${pay.id}" class="show-sp-list">${pay.curAuditors2[0].name}${pay.curAuditors2[0].role !== '' && pay.curAuditors2[0].role !== null ? '-' + pay.curAuditors2[0].role : ''}</a>`;
+                        shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-csid="${pay.id}" class="show-sp-list">${pay.curAuditors2[0].name}${pay.curAuditors2[0].role !== '' && pay.curAuditors2[0].role !== null ? '-' + pay.curAuditors2[0].role : ''}</a>`;
                     } else {
-                        shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-cpid="${pay.id}" class="show-sp-list">${transFormToChinese(pay.curAuditors2[0].audit_order) + '审'}</a>`;
+                        shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-csid="${pay.id}" class="show-sp-list">${transFormToChinese(pay.curAuditors2[0].audit_order) + '审'}</a>`;
                     }
                 } else if (pay.curAuditors.length > 0) {
                     if (pay.curAuditors[0].audit_type === auditType.key.common) {
-                        shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-cpid="${pay.id}" class="show-sp-list">${pay.curAuditors[0].name}${pay.curAuditors[0].role !== '' && pay.curAuditors[0].role !== null ? '-' + pay.curAuditors[0].role : ''}</a>`;
+                        shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-csid="${pay.id}" class="show-sp-list">${pay.curAuditors[0].name}${pay.curAuditors[0].role !== '' && pay.curAuditors[0].role !== null ? '-' + pay.curAuditors[0].role : ''}</a>`;
                     } else {
-                        shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-cpid="${pay.id}" class="show-sp-list">${transFormToChinese(pay.curAuditors[0].audit_order) + '审'}</a>`;
+                        shenpi_html += `<a href="javascript:void(0);" node-cid="${pay.cid}" node-csid="${pay.id}" class="show-sp-list">${transFormToChinese(pay.curAuditors[0].audit_order) + '审'}</a>`;
                     }
                 }
                 shenpi_html += ` ${auditConst.auditProgress[pay.status]}`;
@@ -3225,7 +3277,8 @@ $(document).ready(function() {
         $('body').on('click', '.show-sub-sp', function () {
             console.log($(this).attr('node-cid'));
             let node = _.find(contractTree.nodes, { id: $(this).attr('node-cid') });
-            const cpid = $(this).attr('node-cpid');
+            const cpid = $(this).attr('node-cpid') || null;
+            const csid = $(this).attr('node-csid') || null;
             if (cpid) {
                 node = _.find(contractPays, { id: parseInt(cpid) });
                 $('#contract-add-group').hide();
@@ -3233,12 +3286,22 @@ $(document).ready(function() {
                 $('#change-pay-sp-group').val(node.sp_group);
                 $('#start-sp-cid').val(node.cid);
                 $('#start-sp-cpid').val(node.id);
+                $('#start-sp-csid').val('');
+            } else if (csid) {
+                node = _.find(contractSupplements, { id: parseInt(csid) });
+                $('#contract-add-group').show();
+                $('#pay-add-group').hide();
+                $('#change-sp-group').val(node.sp_group);
+                $('#start-sp-cid').val(node.cid);
+                $('#start-sp-csid').val(node.id);
+                $('#start-sp-cpid').val('');
             } else {
                 $('#contract-add-group').show();
                 $('#pay-add-group').hide();
                 $('#change-sp-group').val(node.sp_group);
                 $('#start-sp-cid').val(node.id);
                 $('#start-sp-cpid').val('');
+                $('#start-sp-csid').val('');
             }
             if (!node) {
                 toastr.error('合同数据获取失败');
@@ -3251,14 +3314,22 @@ $(document).ready(function() {
 
         $('body').on('click', '.show-sp-list', function () {
             let node = _.find(contractTree.nodes, { id: $(this).attr('node-cid') });
-            const cpid = $(this).attr('node-cpid');
+            const cpid = $(this).attr('node-cpid') || null;
+            const csid = $(this).attr('node-csid') || null;
             if (cpid) {
                 node = _.find(contractPays, { id: parseInt(cpid) });
                 $('#check-sp-cid').val(node.cid);
                 $('#check-sp-cpid').val(node.id);
+                $('#check-sp-csid').val('');
+            } else if (csid) {
+                node = _.find(contractSupplements, { id: parseInt(csid) });
+                $('#check-sp-cid').val(node.cid);
+                $('#check-sp-csid').val(node.id);
+                $('#check-sp-cpid').val('');
             } else {
                 $('#check-sp-cid').val(node.id);
                 $('#check-sp-cpid').val('');
+                $('#check-sp-csid').val('');
             }
             if (!node) {
                 toastr.error('合同数据获取失败');
@@ -3319,15 +3390,21 @@ $(document).ready(function() {
         function getNode(from = 'start') {
             const cid = $('#'+ from +'-sp-cid').val();
             const cpid = $('#'+ from +'-sp-cpid').val();
+            const csid = $('#'+ from +'-sp-csid').val();
+            let type = 'contract';
             let node = _.find(contractTree.nodes, { id: cid });
             if (cpid) {
                 node = _.find(contractPays, { id: parseInt(cpid) });
+                type = 'pay';
+            } else if (csid) {
+                node = _.find(contractSupplements, { id: parseInt(csid) });
+                type = 'supplement';
             }
             if (!node) {
                 toastr.error('合同数据获取失败');
                 return;
             }
-            return node;
+            return [node, type];
         }
 
         function setStartAuditsHtml(node) {
@@ -3568,20 +3645,20 @@ $(document).ready(function() {
 
         // 添加到审批流程中
         $('.search-user-list').on('click', 'dd', function () {
-            const node = getNode();
+            const [node, type] = getNode();
             const id = parseInt($(this).data('id'));
             if (id) {
-                postData(window.location.pathname + '/check', {postType: 'add-audit', id: node.id, auditorId: id}, function (result) {
+                postData(window.location.pathname + '/check', {postType: 'add-audit', id: node.id, type, auditorId: id}, function (result) {
                     setStartAuditChange(node, result);
                 });
             }
         });
         // 删除审批人
         $('body').on('click', '#auditors li a', function () {
-            const node = getNode();
+            const [node, type] = getNode();
             const li = $(this).parents('li');
             const data = {
-                postType: 'del-audit', id: node.id,
+                postType: 'del-audit', id: node.id, type,
                 auditorId: parseInt(li.attr('auditorId')),
             };
             postData(window.location.pathname + '/check', data, (result) => {
@@ -3590,15 +3667,15 @@ $(document).ready(function() {
         });
 
         $('#change-sp-group').change(function () {
-            const node = getNode();
-            postData(window.location.pathname + '/check', {postType: 'change-sp', id: node.id, sp_group: $(this).val()}, function (result) {
+            const [node, type] = getNode();
+            postData(window.location.pathname + '/check', {postType: 'change-sp', id: node.id, type, sp_group: $(this).val()}, function (result) {
                 setStartAuditChange(node, result);
             });
         });
 
         $('#change-pay-sp-group').change(function () {
-            const node = getNode();
-            postData(window.location.pathname + '/check', {postType: 'change-sp', id: node.id, sp_group: $(this).val()}, function (result) {
+            const [node, type] = getNode();
+            postData(window.location.pathname + '/check', {postType: 'change-sp', id: node.id, type, sp_group: $(this).val()}, function (result) {
                 setStartAuditChange(node, result);
             });
         });
@@ -3614,15 +3691,15 @@ $(document).ready(function() {
         }
 
         $('#start-sp-btn').click(function () {
-            const node = getNode();
-            postData(window.location.pathname + '/check', {postType: 'start', id: node.id}, function (result) {
-                setShenpiChange(node, result);
+            const [node, type] = getNode();
+            postData(window.location.pathname + '/check', {postType: 'start', id: node.id, type}, function (result) {
+                setShenpiChange(node, result, type);
                 $('#sub-sp').modal('hide');
             });
         });
 
         $('body').on('click', '#check-sp-btn', function () {
-            const node = getNode('check');
+            const [node, type] = getNode('check');
             const operate = $('#check-operate').val();
             console.log(node, operate);
             const checkType = operate === 'checked' ? auditConst.status.checked : parseInt($('#audit-list').find('input[name="checkType"]:checked').val());
@@ -3635,17 +3712,18 @@ $(document).ready(function() {
                 postType: 'check',
                 id: node.id,
                 checkType,
+                type,
                 opinion: $('#audit-list').find('textarea').val().replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' '),
             }
             console.log(data);
             postData(window.location.pathname + '/check', data, function (result) {
-                setShenpiChange(node, result);
+                setShenpiChange(node, result, type);
                 $('#sp-list').modal('hide');
             });
         });
 
-        function setShenpiChange(node, result) {
-            if (node.cid) {
+        function setShenpiChange(node, result, type) {
+            if (type === 'pay') {
                 contractPays.splice(contractPays.findIndex(item => item.id === node.id), 1, result);
                 const shenpi_html = setPayShenpiHtml(result, true);
                 $("#htpay-table tbody").find(`tr[data-cpid="${node.id}"]`).children('.shenpi-td').html(shenpi_html);
@@ -3656,6 +3734,17 @@ $(document).ready(function() {
                     $('#htpay-table tbody').find(`tr[data-cpid="${node.id}"]`).find('.pay-edit').show();
                     $('#htpay-table tbody').find(`tr[data-cpid="${node.id}"]`).find('.pay-del').show();
                 }
+            } else if (type === 'supplement') {
+                contractSupplements.splice(contractSupplements.findIndex(item => item.id === node.id), 1, result);
+                const shenpi_html = setSupplementShenpiHtml(result, true);
+                $("#htsupplement-table tbody").find(`tr[data-csid="${node.id}"]`).children('.shenpi-td').html(shenpi_html);
+                $("#htsupplement-table tbody").find(`tr[data-csid="${node.id}"]`).children('.shenpi-td').addClass(auditConst.auditProgressClass[result.status]);
+                $('#htsupplement-table tbody').find(`tr[data-csid="${node.id}"]`).find('.supplement-edit').hide();
+                $('#htsupplement-table tbody').find(`tr[data-csid="${node.id}"]`).find('.supplement-del').hide();
+                if (node.uid === user_id && (result.status === auditConst.status.uncheck || result.status === auditConst.status.checkNo)) {
+                    $('#htsupplement-table tbody').find(`tr[data-csid="${node.id}"]`).find('.supplement-edit').show();
+                    $('#htsupplement-table tbody').find(`tr[data-csid="${node.id}"]`).find('.supplement-del').show();
+                }
             } else {
                 const refreshNode = contractTree.loadPostData({update: result});
                 contractTreeSpreadObj.refreshTree(contractSheet, refreshNode);

+ 4 - 3
app/service/contract.js

@@ -55,7 +55,8 @@ module.exports = app => {
                     is_leaf: 1,
                     c_code: data.code,
                     name: data.name,
-                    total_price: data.total_price ? parseFloat(data.total_price) : 0,
+                    total_price: data.price ? parseFloat(data.price) : 0,
+                    price: data.price ? parseFloat(data.price) : 0,
                     party_a: data.party_a,
                     party_b: data.party_b,
                     sign_date: data.sign_date,
@@ -75,7 +76,7 @@ module.exports = app => {
                     await transaction.update(this.ctx.service.contractTree.tableName, { id: node.id, is_leaf: 0 });
                 }
                 this.ctx.service.contractTree._cacheMaxLid(options, maxId + 1);
-                await this.ctx.service.contractSpAudit.makeAudits(transaction, options, insertId, null, this.ctx.session.sessionUser.accountId);
+                await this.ctx.service.contractSpAudit.makeAudits(transaction, options, insertData, 'contract', this.ctx.session.sessionUser.accountId);
                 await transaction.commit();
             } catch (err) {
                 await transaction.rollback();
@@ -153,7 +154,7 @@ module.exports = app => {
                     // await this.ctx.service.contractSpAudit.loadAuditViewData(l);
                     // await this.ctx.service.contractSpAudit.checkShenpi(l);
                     if (l.status !== auditConst.status.checked || !l.final_auditor_str) {
-                        l.curAuditors2 = await this.ctx.service.contractSpAudit.getAuditorsByStatus(l.id, null, l.status, l.times);
+                        l.curAuditors2 = await this.ctx.service.contractSpAudit.getAuditorsByStatus(l, 'contract', l.status, l.times);
                         if (l.status === auditConst.status.checked && !l.final_auditor_str) {
                             const final_auditor_str = l.curAuditors2[0].audit_type === auditType.key.common
                                 ? l.curAuditors2[0].name + (l.curAuditors2[0].role ? '-' + l.curAuditors2[0].role : '')

+ 9 - 5
app/service/contract_pay.js

@@ -32,16 +32,17 @@ module.exports = app => {
             const pay_shenpi_status = this.ctx.contract_tender ? this.ctx.subProject.page_show.openContractPayTenderShenpi : this.ctx.subProject.page_show.openContractPaySubProjectShenpi;
             if (list.length > 0) {
                 const userList = await this.ctx.service.projectAccount.getAllDataByCondition({ where: { id: list.map(item => item.uid) } });
+                const type = 'pay';
                 for (const l of list) {
                     const userInfo = userList.find(item => item.id === l.uid);
                     l.username = userInfo ? userInfo.name : '';
                     l.files = await this.ctx.service.contractPayAtt.getAtt(l.id);
                     if (pay_shenpi_status) {
-                        await this.ctx.service.contractSpAudit.loadUser(l);
-                        await this.ctx.service.contractSpAudit.loadAuditViewData(l);
-                        await this.ctx.service.contractSpAudit.checkShenpi(l);
+                        await this.ctx.service.contractSpAudit.loadUser(l, type);
+                        await this.ctx.service.contractSpAudit.loadAuditViewData(l, type);
+                        await this.ctx.service.contractSpAudit.checkShenpi(l, type);
                         if (l.status !== auditConst.status.checked || !l.final_auditor_str) {
-                            l.curAuditors2 = await this.ctx.service.contractSpAudit.getAuditorsByStatus(l.cid, l.id, l.status, l.times);
+                            l.curAuditors2 = await this.ctx.service.contractSpAudit.getAuditorsByStatus(l, type, l.status, l.times);
                             if (l.status === auditConst.status.checked && !l.final_auditor_str) {
                                 const final_auditor_str = l.curAuditors2[0].audit_type === auditType.key.common
                                     ? l.curAuditors2[0].name + (l.curAuditors2[0].role ? '-' + l.curAuditors2[0].role : '')
@@ -82,7 +83,8 @@ module.exports = app => {
                 };
                 const result = await transaction.insert(this.tableName, insertData);
                 await this.calcContract(transaction, node);
-                await this.ctx.service.contractSpAudit.makeAudits(transaction, options, cid, result.insertId, this.ctx.session.sessionUser.accountId);
+                insertData.id = result.insertId;
+                await this.ctx.service.contractSpAudit.makeAudits(transaction, options, insertData, 'pay', this.ctx.session.sessionUser.accountId);
                 await transaction.commit();
             } catch (err) {
                 await transaction.rollback();
@@ -214,6 +216,7 @@ module.exports = app => {
                             tid: p.tid,
                             cid: p.cid,
                             cpid: p.id,
+                            csid: null,
                             aid: fp.uid,
                             order: 0,
                             times: 1,
@@ -234,6 +237,7 @@ module.exports = app => {
                                 tid: p.tid,
                                 cid: p.cid,
                                 cpid: p.id,
+                                csid: null,
                                 aid: a.aid,
                                 order: a.order,
                                 times: 1,

+ 270 - 170
app/service/contract_sp_audit.js

@@ -27,11 +27,16 @@ module.exports = app => {
             this.tableName = 'contract_sp_audit';
         }
 
-        async checkShenpi(contract) {
+        async checkShenpi(contract, type = 'contract') {
             const cid = contract.cid ? contract.cid : contract.id;
-            const cpid = contract.cid ? contract.id : null;
-            const change_type = contract.cid ? contractConst.typeMap[contract.contract_type] : 'contract';
-            const tableName = contract.cid ? this.ctx.service.contractPay : this.ctx.service.contract;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const change_type = type === 'contract' || type === 'supplement' ? 'contract' : contractConst.typeMap[contract.contract_type];
+            const tableName = {
+                contract: this.ctx.service.contract,
+                pay: this.ctx.service.contractPay,
+                supplement: this.ctx.service.contractSupplement,
+            }[type];
             const status = auditConst.status;
             let shenpi = '';
             if (this.ctx.contract_tender) {
@@ -43,7 +48,7 @@ module.exports = app => {
             const shenpi_status = shenpi.contract;
             if ((contract.status === status.uncheck || contract.status === status.checkNo) && shenpi_status !== shenpiConst.sp_status.sqspr) {
                 // 进一步比较审批流是否与审批流程设置的相同,不同则替换为固定审批流或固定的终审
-                const auditList = await this.getAllDataByCondition({ where: { cid, cpid, times: contract.times }, orders: [['order', 'asc']] });
+                const auditList = await this.getAllDataByCondition({ where: { cid, cpid, csid, times: contract.times }, orders: [['order', 'asc']] });
                 // auditList.shift();
                 if (shenpi_status === shenpiConst.sp_status.gdspl) {
                     // 判断并获取审批组
@@ -68,9 +73,9 @@ module.exports = app => {
                             }
                         }
                         if (!sameAudit) {
-                            await this.updateNewAuditList(contract, shenpiList);
-                            await this.loadUser(contract);
-                            await this.loadAuditViewData(contract);
+                            await this.updateNewAuditList(contract, type, shenpiList);
+                            await this.loadUser(contract, type);
+                            await this.loadAuditViewData(contract, type);
                         }
                     }
                 } else if (shenpi_status === shenpiConst.sp_status.gdzs) {
@@ -78,7 +83,7 @@ module.exports = app => {
                     // 判断最后一个id是否与固定终审id相同,不同则删除原审批流中如果存在的id和添加终审
                     const lastAuditors = auditList.filter(x => { return x.audit_order === auditList.length - 1; });
                     if (shenpiInfo && (lastAuditors.length === 0 || (lastAuditors.length > 1 || shenpiInfo.audit_id !== lastAuditors[0].aid))) {
-                        await this.updateLastAudit(contract, auditList, shenpiInfo.audit_id);
+                        await this.updateLastAudit(contract, type, auditList, shenpiInfo.audit_id);
                     } else if (!shenpiInfo) {
                         // 不存在终审人的状态下这里恢复为授权审批人
                         shenpi.contract = shenpiConst.sp_status.sqspr;
@@ -87,12 +92,12 @@ module.exports = app => {
             }
         }
 
-        async loadUser(contract) {
+        async loadUser(contract, type = 'contract') {
             const status = auditConst.status;
             const accountId = this.ctx.session.sessionUser.accountId;
 
             contract.user = await this.ctx.service.projectAccount.getAccountInfoById(contract.uid);
-            contract.auditors = await this.getAuditors(contract.cid ? contract.cid : contract.id, contract.cid ? contract.id : null, contract.times); // 全部参与的审批人
+            contract.auditors = await this.getAuditors(contract, type, contract.times); // 全部参与的审批人
             contract.auditorIds = this._.map(contract.auditors, 'aid');
             contract.curAuditors = contract.auditors.filter(x => { return x.status === status.checking; }); // 当前流程中审批中的审批人
             contract.curAuditorIds = this._.map(contract.curAuditors, 'aid');
@@ -105,21 +110,21 @@ module.exports = app => {
             contract.finalAuditorIds = this._.map(contract.userGroups[contract.userGroups.length - 1], 'aid');
         }
 
-        async loadAuditViewData(contract) {
+        async loadAuditViewData(contract, type = 'contract') {
             const times = contract.status === auditConst.status.checkNo ? contract.times - 1 : contract.times;
 
             if (!contract.user) contract.user = await this.ctx.service.projectAccount.getAccountInfoById(contract.uid);
-            contract.auditHistory = await this.getAuditorHistory(contract.cid ? contract.cid : contract.id, contract.cid ? contract.id : null, times);
+            contract.auditHistory = await this.getAuditorHistory(contract, type, times);
             // 获取审批流程中左边列表
             // if ((contract.status === auditConst.status.checkNo) && !(contract.uid === this.ctx.session.sessionUser.accountId || this.ctx.contract_audit_permission.permission_edit_contract || this.ctx.session.sessionUser.is_admin)) {
-            const auditors = await this.getAuditors(contract.cid ? contract.cid : contract.id, contract.cid ? contract.id : null, times); // 全部参与的审批人
+            const auditors = await this.getAuditors(contract, type, times); // 全部参与的审批人
             const auditorGroups = this.ctx.helper.groupAuditors(auditors);
             contract.auditors2 = this.ctx.helper.groupAuditorsUniq(auditorGroups);
             // } else {
             //     contract.auditors2 = contract.userGroups;
             // }
             if (contract.status === auditConst.status.uncheck || contract.status === auditConst.status.checkNo) {
-                contract.auditorList = await this.getAuditors(contract.cid ? contract.cid : contract.id, contract.cid ? contract.id : null, contract.times);
+                contract.auditorList = await this.getAuditors(contract, type, contract.times);
             }
         }
 
@@ -130,7 +135,7 @@ module.exports = app => {
          * @param {Number} times - 第几次审批
          * @return {Promise<*>}
          */
-        async getAuditors(cid, cpid = null, times = 1, order_sort = 'asc', noYB = false) {
+        async getAuditors(contract, type, times = 1, order_sort = 'asc', noYB = false) {
             // const sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, g.`sort` ' +
             //     'FROM ?? AS la, ?? AS pa, (SELECT t1.`aid`,(@i:=@i+1) as `sort` FROM (SELECT t.`aid`, t.`order` FROM (select `aid`, `order` from ?? WHERE `cpid` = ? AND `times` = ? ORDER BY `order` LIMIT 200) t GROUP BY t.`aid` ORDER BY t.`order`) t1, (select @i:=0) as it) as g ' +
             //     'WHERE la.`cpid` = ? and la.`times` = ? and la.`aid` = pa.`id` and g.`aid` = la.`aid` order by la.`order`';
@@ -142,12 +147,20 @@ module.exports = app => {
             // for (const i in result) {
             //     result[i].max_sort = count.num;
             // }
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const cpidSql = type === 'pay'
+                ? ' AND la.cpid = ' + cpid
+                : ' AND la.cpid is null';
+            const csidSql = type === 'supplement'
+                ? ' AND la.csid = ' + csid
+                : ' AND la.csid is null';
             const ybSql = noYB ? ' AND la.audit_order != 0' : '';
-            const cpidSql = cpid ? ' AND la.cpid = ' + cpid : ' AND la.cpid is null';
             const sql = 'SELECT la.id, la.aid, la.times, la.order, la.status, la.opinion, la.begin_time, la.end_time, la.audit_type, la.audit_order,' +
                 '    pa.name, pa.company, pa.role, pa.mobile, pa.telephone' +
                 `  FROM ${this.tableName} la LEFT JOIN ${this.ctx.service.projectAccount.tableName} pa ON la.aid = pa.id` +
-                '  WHERE la.cid = ?' + cpidSql + ' AND la.times = ?' + ybSql +
+                '  WHERE la.cid = ?' + cpidSql + csidSql + ' AND la.times = ?' + ybSql +
                 '  ORDER BY la.order ' + order_sort;
             const sqlParam = [cid, times];
             const result = await this.db.query(sql, sqlParam);
@@ -165,21 +178,37 @@ module.exports = app => {
          * @param {Number} times - 第几次审批
          * @return {Promise<*>}
          */
-        async getCurAuditor(cid, cpid = null, times = 1) {
-            const cpidSql = cpid ? ' AND la.cpid = ' + cpid : ' AND la.cpid is null';
+        async getCurAuditor(contract, type, times = 1) {
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const cpidSql = type === 'pay'
+                ? ' AND la.cpid = ' + cpid
+                : ' AND la.cpid is null';
+            const csidSql = type === 'supplement'
+                ? ' AND la.csid = ' + csid
+                : ' AND la.csid is null';
             const sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
                 '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id` ' +
-                '  WHERE la.`cid` = ?' + cpidSql + ' and la.`status` = ? and la.`times` = ? and la.`audit_order` != 0';
+                '  WHERE la.`cid` = ?' + cpidSql + csidSql + ' and la.`status` = ? and la.`times` = ? and la.`audit_order` != 0';
             const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, cid, auditConst.status.checking, times];
             return await this.db.queryOne(sql, sqlParam);
         }
 
-        async getCurAuditors(cid, cpid = null, times = 1) {
-            const cpidSql = cpid ? ' AND la.cpid = ' + cpid : ' AND la.cpid is null';
+        async getCurAuditors(contract, type, times = 1) {
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const cpidSql = type === 'pay'
+                ? ' AND la.cpid = ' + cpid
+                : ' AND la.cpid is null';
+            const csidSql = type === 'supplement'
+                ? ' AND la.csid = ' + csid
+                : ' AND la.csid is null';
             const sql =
                 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, la.audit_type, la.audit_order ' +
                 '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id`' +
-                '  WHERE la.`cid` = ?' + cpidSql + ' and la.`status` = ? and la.`times` = ? and la.`audit_order` != 0';
+                '  WHERE la.`cid` = ?' + cpidSql + csidSql + ' and la.`status` = ? and la.`times` = ? and la.`audit_order` != 0';
             const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, cid, auditConst.status.checking, times];
             return await this.db.query(sql, sqlParam);
         }
@@ -205,18 +234,21 @@ module.exports = app => {
          * @param auditorId
          * @return {Promise<*>}
          */
-        async getAuditGroupByList(cid, cpid = null, times, transaction = false) {
-            // const sql =
-            //     'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`sid`, la.`aid`, la.`order`, la.`status`' +
-            //     '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id` ' +
-            //     '  WHERE la.`sid` = ? and la.`times` = ? and la.`is_old` = 0 GROUP BY la.`aid` ORDER BY la.`order`';
-            // const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, times];
-            const cpidSql = cpid ? ' AND la.`cpid` = ' + cpid : ' AND la.`cpid` is null';
+        async getAuditGroupByList(contract, type, times, transaction = false) {
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const cpidSql = type === 'pay'
+                ? ' AND la.cpid = ' + cpid
+                : ' AND la.cpid is null';
+            const csidSql = type === 'supplement'
+                ? ' AND la.csid = ' + csid
+                : ' AND la.csid is null';
             const sql =
                 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cid`, la.`cpid`, la.`aid`, la.`order`, la.`status`, la.audit_type, la.audit_order ' +
-                ' FROM (SELECT `aid`, max(`order`) `order` FROM ?? WHERE `cid` = ? and `cpid` ' + (cpid ? '= ' + cpid : 'is null') + ' and `times` = ? and `audit_order` != 0 GROUP BY aid) sa' +
+                ' FROM (SELECT `aid`, max(`order`) `order` FROM ?? WHERE `cid` = ? and `cpid` ' + (cpid ? '= ' + cpid : 'is null') + ' and `csid` ' + (csid ? '= ' + csid : 'is null') + ' and `times` = ? and `audit_order` != 0 GROUP BY aid) sa' +
                 ' LEFT JOIN ?? la ON sa.`aid` = la.`aid` AND sa.`order` = la.`order`' +
-                ' Left JOIN ?? AS pa On la.`aid` = pa.`id` WHERE la.`cid` = ?' + cpidSql + ' and la.`times` = ? and la.`audit_order` != 0 order BY la.`order`';
+                ' Left JOIN ?? AS pa On la.`aid` = pa.`id` WHERE la.`cid` = ?' + cpidSql + csidSql + ' and la.`times` = ? and la.`audit_order` != 0 order BY la.`order`';
             const sqlParam = [this.tableName, cid, times, this.tableName, this.ctx.service.projectAccount.tableName, cid, times];
             return transaction !== false ? await transaction.query(sql, sqlParam) : await this.db.query(sql, sqlParam);
         }
@@ -229,8 +261,16 @@ module.exports = app => {
          * @param {Number} status - 期次数
          * @return {Promise<boolean>}
          */
-        async getAuditorByStatus(cid, cpid = null, status, times = 1) {
-            const cpidSql = cpid ? ' AND la.cpid = ' + cpid : ' AND la.cpid is null';
+        async getAuditorByStatus(contract, type, status, times = 1) {
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const cpidSql = type === 'pay'
+                ? ' AND la.cpid = ' + cpid
+                : ' AND la.cpid is null';
+            const csidSql = type === 'supplement'
+                ? ' AND la.csid = ' + csid
+                : ' AND la.csid is null';
             let auditor = null;
             let sql = '';
             let sqlParam = '';
@@ -239,7 +279,7 @@ module.exports = app => {
                 case auditConst.status.checked :
                     sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cid`, la.`cpid`, la.`aid`, la.`order`, la.`status` ' +
                         '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id` ' +
-                        '  WHERE la.`cid` = ?' + cpidSql + ' and la.`status` = ? ' +
+                        '  WHERE la.`cid` = ?' + cpidSql + csidSql + ' and la.`status` = ? ' +
                         '  ORDER BY la.`times` desc, la.`order` desc';
                     sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, cid, status];
                     auditor = await this.db.queryOne(sql, sqlParam);
@@ -247,7 +287,7 @@ module.exports = app => {
                 case auditConst.status.checkNo :
                     sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cid`, la.`cpid`, la.`aid`, la.`order`, la.`status` ' +
                         '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id`' +
-                        '  WHERE la.`cid` = ?' + cpidSql + ' and la.`status` = ? and la.`times` = ?' +
+                        '  WHERE la.`cid` = ?' + cpidSql + csidSql + ' and la.`status` = ? and la.`times` = ?' +
                         '  ORDER BY la.`times` desc, la.`order` desc';
                     sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, cid, auditConst.status.checkNo, parseInt(times) - 1];
                     auditor = await this.db.queryOne(sql, sqlParam);
@@ -259,8 +299,16 @@ module.exports = app => {
             return auditor;
         }
 
-        async getAuditorsByStatus(cid, cpid = null, status, times = 1) {
-            const cpidSql = cpid ? ' AND la.cpid = ' + cpid : ' AND la.cpid is null';
+        async getAuditorsByStatus(contract, type, status, times = 1) {
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const cpidSql = type === 'pay'
+                ? ' AND la.cpid = ' + cpid
+                : ' AND la.cpid is null';
+            const csidSql = type === 'supplement'
+                ? ' AND la.csid = ' + csid
+                : ' AND la.csid is null';
             let auditor = [];
             let sql = '';
             let sqlParam = '';
@@ -269,22 +317,22 @@ module.exports = app => {
                 case auditConst.status.checking :
                 case auditConst.status.checked :
                 case auditConst.status.checkNoPre:
-                    cur = await this.db.queryOne('SELECT * From ?? where cid = ? AND cpid ' + (cpid ? '= ' + cpid : 'is null') + ' AND times = ? AND status = ? AND audit_order != 0 ORDER By times DESC, `order` DESC', [this.tableName, cid, times, status]);
+                    cur = await this.db.queryOne('SELECT * From ?? where cid = ? AND cpid ' + (cpid ? '= ' + cpid : 'is null') + ' AND csid ' + (csid ? '= ' + csid : 'is null') + ' AND times = ? AND status = ? AND audit_order != 0 ORDER By times DESC, `order` DESC', [this.tableName, cid, times, status]);
                     if (!cur) return [];
 
                     sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cid`, la.`cpid`, la.`order`, la.`status`, la.`audit_order`, la.`audit_type` ' +
                         '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id` ' +
-                        '  WHERE la.`cid` = ?' + cpidSql + ' and la.`order` = ? and times = ?';
+                        '  WHERE la.`cid` = ?' + cpidSql + csidSql + ' and la.`order` = ? and times = ?';
                     sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, cid, cur.order, times];
                     auditor = await this.db.query(sql, sqlParam);
                     break;
                 case auditConst.status.checkNo :
-                    cur = await this.db.queryOne('SELECT * From ?? where cid = ? AND cpid ' + (cpid ? '= ' + cpid : 'is null') + ' AND times = ? AND status = ? AND audit_order != 0 ORDER By times DESC, `order` DESC', [this.tableName, cid, parseInt(times) - 1, status]);
+                    cur = await this.db.queryOne('SELECT * From ?? where cid = ? AND cpid ' + (cpid ? '= ' + cpid : 'is null') + ' AND csid ' + (csid ? '= ' + csid : 'is null') + ' AND times = ? AND status = ? AND audit_order != 0 ORDER By times DESC, `order` DESC', [this.tableName, cid, parseInt(times) - 1, status]);
                     if (!cur) return [];
 
                     sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`cid`, la.`cpid`, la.`order`, la.`status`, la.`audit_order`, la.`audit_type` ' +
                         '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id` ' +
-                        '  WHERE la.`cid` = ?' + cpidSql + ' and la.`order` = ? and la.`times` = ?';
+                        '  WHERE la.`cid` = ?' + cpidSql + csidSql + ' and la.`order` = ? and la.`times` = ?';
                     sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, cid, cur.order, parseInt(times) - 1];
                     auditor = await this.db.query(sql, sqlParam);
                     break;
@@ -295,9 +343,17 @@ module.exports = app => {
             return auditor;
         }
 
-        async getLastAudit(cid, cpid = null, times, transaction = null) {
-            const cpidSql = cpid ? ' AND cpid = ' + cpid : ' AND cpid is null';
-            const sql = 'SELECT * FROM ?? WHERE `cid` = ?' + cpidSql + ' AND `times` = ? ORDER BY `order` DESC';
+        async getLastAudit(contract, type, times, transaction = null) {
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const cpidSql = type === 'pay'
+                ? ' AND cpid = ' + cpid
+                : ' AND cpid is null';
+            const csidSql = type === 'supplement'
+                ? ' AND csid = ' + csid
+                : ' AND csid is null';
+            const sql = 'SELECT * FROM ?? WHERE `cid` = ?' + cpidSql + csidSql + ' AND `times` = ? ORDER BY `order` DESC';
             const sqlParam = [this.tableName, cid, times];
             return transaction ? await transaction.queryOne(sql, sqlParam) : await this.db.queryOne(sql, sqlParam);
         }
@@ -308,9 +364,9 @@ module.exports = app => {
          * @param {Number} times 审核次数
          * @return {Promise<Array>} 查询结果集(包括原报)
          */
-        async getAuditorsWithOwner(cid, cpid = null, times = 1) {
+        async getAuditorsWithOwner(contract, type, times = 1) {
             // const cpidSql = cpid ? ' AND la.cpid = ' + cpid : ' AND la.cpid is null';
-            const result = await this.getAuditGroupByList(cid, cpid, times);
+            const result = await this.getAuditGroupByList(contract, type, times);
             // const sql =
             //     'SELECT pa.`id` As aid, pa.`name`, pa.`company`, pa.`role`, ? As times, ? As cpid, 0 As `order`' +
             //     '  FROM ' +
@@ -335,20 +391,24 @@ module.exports = app => {
          * @param {Number} times - 第几次审批
          * @return {Promise<number>}
          */
-        async addAuditor(options, cid, cpid = null, auditorId, times = 1, is_gdzs = 0) {
+        async addAuditor(options, contract, type, auditorId, times = 1, is_gdzs = 0) {
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
             const transaction = await this.db.beginTransaction();
             let flag = false;
             try {
-                let [newOrder, newAuditOrder] = await this.getNewOrder(cid, cpid, times);
+                let [newOrder, newAuditOrder] = await this.getNewOrder(contract, type, times);
                 // 判断是否存在固定终审,存在则newOrder - 1并使终审order+1
                 newOrder = is_gdzs === 1 ? newOrder - 1 : newOrder;
                 newAuditOrder = is_gdzs === 1 ? newAuditOrder - 1 : newAuditOrder;
-                if (is_gdzs) await this._syncOrderByDelete(transaction, cid, cpid, newOrder, times, '+');
+                if (is_gdzs) await this._syncOrderByDelete(transaction, contract, type, newOrder, times, '+');
                 const data = {
                     spid: options.spid || null,
                     tid: options.tid || null,
                     cid,
                     cpid,
+                    csid,
                     aid: auditorId,
                     times,
                     order: newOrder,
@@ -373,9 +433,17 @@ module.exports = app => {
          * @param {Number} times - 第几次审批
          * @return {Promise<number>}
          */
-        async getNewOrder(cid, cpid = null, times = 1) {
-            const cpidSql = cpid ? ' AND cpid = ' + cpid : ' AND cpid is null';
-            const sql = 'SELECT Max(`order`) As max_order, Max(audit_order) As max_audit_order FROM ?? Where `cid` = ?' + cpidSql + ' and `times` = ?';
+        async getNewOrder(contract, type, times = 1) {
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const cpidSql = type === 'pay'
+                ? ' AND cpid = ' + cpid
+                : ' AND cpid is null';
+            const csidSql = type === 'supplement'
+                ? ' AND csid = ' + csid
+                : ' AND csid is null';
+            const sql = 'SELECT Max(`order`) As max_order, Max(audit_order) As max_audit_order FROM ?? Where `cid` = ?' + cpidSql + csidSql + ' and `times` = ?';
             const sqlParam = [this.tableName, cid, times];
             const result = await this.db.queryOne(sql, sqlParam);
             return result && result.max_order ? [result.max_order + 1, result.max_audit_order + 1] : [1, 1];
@@ -389,11 +457,19 @@ module.exports = app => {
          * @param {Number} times - 第几次审批
          * @return {Promise<boolean>}
          */
-        async deleteAuditor(cid, cpid = null, auditorId, times = 1) {
+        async deleteAuditor(contract, type, auditorId, times = 1) {
             const transaction = await this.db.beginTransaction();
             try {
-                const cpidSql = cpid ? ' AND cpid = ' + cpid : ' AND cpid is null';
-                const sql = 'SELECT * FROM ?? WHERE `cid` = ?' + cpidSql + ' and `times` = ? and `aid` = ? and `audit_order` != 0 ORDER BY `order` DESC';
+                const cid = contract.cid ? contract.cid : contract.id;
+                const cpid = type === 'pay' ? contract.id : null;
+                const csid = type === 'supplement' ? contract.id : null;
+                const cpidSql = type === 'pay'
+                    ? ' AND cpid = ' + cpid
+                    : ' AND cpid is null';
+                const csidSql = type === 'supplement'
+                    ? ' AND csid = ' + csid
+                    : ' AND csid is null';
+                const sql = 'SELECT * FROM ?? WHERE `cid` = ?' + cpidSql + csidSql + ' and `times` = ? and `aid` = ? and `audit_order` != 0 ORDER BY `order` DESC';
                 const sqlParam = [this.tableName, cid, times, auditorId];
                 const auditor = await transaction.queryOne(sql, sqlParam);
                 // const condition = { cid, cpid, aid: auditorId, times };
@@ -401,8 +477,8 @@ module.exports = app => {
                 if (!auditor) {
                     throw '该审核人不存在';
                 }
-                await transaction.delete(this.tableName, { cid, cpid, order: auditor.order, times });
-                await this._syncOrderByDelete(transaction, cid, cpid, auditor.order, times);
+                await transaction.delete(this.tableName, { cid, cpid, csid, order: auditor.order, times });
+                await this._syncOrderByDelete(transaction, contract, type, auditor.order, times);
                 await transaction.commit();
             } catch (err) {
                 await transaction.rollback();
@@ -420,31 +496,11 @@ module.exports = app => {
          * @return {Promise<*>}
          * @private
          */
-        async _syncOrderByDelete(transaction, cid, cpid, order, times, selfOperate = '-') {
-            // this.initSqlBuilder();
-            // this.sqlBuilder.setAndWhere('cid', {
-            //     value: this.db.escape(cid),
-            //     operate: '=',
-            // });
-            // this.sqlBuilder.setAndWhere('order', {
-            //     value: order,
-            //     operate: '>=',
-            // });
-            // this.sqlBuilder.setAndWhere('times', {
-            //     value: times,
-            //     operate: '=',
-            // });
-            // this.sqlBuilder.setUpdateData('order', {
-            //     value: 1,
-            //     selfOperate,
-            // });
-            // this.sqlBuilder.setUpdateData('audit_order', {
-            //     value: 1,
-            //     selfOperate,
-            // });
-            // const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
-            // const data = await transaction.query(sql, sqlParam);
-            const sql = 'UPDATE ?? SET `order` = `order` ' + selfOperate + ' ?, `audit_order` = `audit_order` ' + selfOperate + ' ? WHERE `cid` = ? AND `cpid` ' + (cpid ? '= ' + cpid : 'is null') + ' AND `order` >= ? AND `times` = ?';
+        async _syncOrderByDelete(transaction, contract, type, order, times, selfOperate = '-') {
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const sql = 'UPDATE ?? SET `order` = `order` ' + selfOperate + ' ?, `audit_order` = `audit_order` ' + selfOperate + ' ? WHERE `cid` = ? AND `cpid` ' + (cpid ? '= ' + cpid : 'is null') + ' AND `csid` ' + (csid ? '= ' + csid : 'is null') + ' AND `order` >= ? AND `times` = ?';
             const sqlParam = [this.tableName, 1, 1, cid, order, times];
             const data = await transaction.query(sql, sqlParam);
             return data;
@@ -456,8 +512,11 @@ module.exports = app => {
          * @param {Number} times - 第几次审批
          * @return {Promise<boolean>}
          */
-        async start(options, shenpi, cid, cpid = null, times = 1) {
-            const audits = await this.getAllDataByCondition({ where: { cid, cpid, times, order: 1 } });
+        async start(options, shenpi, contract, type, times = 1) {
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const audits = await this.getAllDataByCondition({ where: { cid, cpid, csid, times, order: 1 } });
             if (audits.length === 0) {
                 if (shenpi.contract === shenpiConst.sp_status.gdspl) {
                     throw '请联系管理员添加审批人';
@@ -474,6 +533,7 @@ module.exports = app => {
                     tid: options.tid || null,
                     cid,
                     cpid,
+                    csid,
                     aid: this.ctx.session.sessionUser.accountId,
                     times,
                     order: 0,
@@ -489,6 +549,10 @@ module.exports = app => {
                     await transaction.update(this.ctx.service.contractPay.tableName, {
                         id: cpid, status: auditConst.status.checking,
                     });
+                } else if (csid) {
+                    await transaction.update(this.ctx.service.contractSupplement.tableName, {
+                        id: csid, status: auditConst.status.checking,
+                    });
                 } else {
                     await transaction.update(this.ctx.service.contract.tableName, {
                         id: cid, status: auditConst.status.checking,
@@ -589,30 +653,34 @@ module.exports = app => {
          * @param {Number} times - 第几次审批
          * @return {Promise<void>}
          */
-        async check(contract, checkData) {
+        async check(contract, type, checkData) {
             if (!this._.includes([auditConst.status.checked, auditConst.status.checkNo, auditConst.status.checkNoPre], checkData.checkType)) {
                 throw '提交数据错误';
             }
             const pid = this.ctx.session.sessionProject.id;
             switch (checkData.checkType) {
                 case auditConst.status.checked:
-                    await this._checked(pid, contract, checkData);
+                    await this._checked(pid, contract, type, checkData);
                     break;
                 case auditConst.status.checkNo:
-                    await this._checkNo(pid, contract, checkData);
+                    await this._checkNo(pid, contract, type, checkData);
                     break;
                 case auditConst.status.checkNoPre:
-                    await this._checkNoPre(pid, contract, checkData);
+                    await this._checkNoPre(pid, contract, type, checkData);
                     break;
                 default:
                     throw '无效审批操作';
             }
         }
 
-        async _checked(pid, contract, checkData) {
+        async _checked(pid, contract, type, checkData) {
             const accountId = this.ctx.session.sessionUser.accountId;
             const time = new Date();
-            const tableName = contract.cid !== undefined ? this.ctx.service.contractPay.tableName : this.ctx.service.contract.tableName;
+            const tableName = {
+                contract: this.ctx.service.contract.tableName,
+                pay: this.ctx.service.contractPay.tableName,
+                supplement: this.ctx.service.contractSupplement.tableName,
+            }[type];
 
             // 整理当前流程审核人状态更新
             if (contract.curAuditorIds.length === 0) throw '审核数据错误';
@@ -689,18 +757,25 @@ module.exports = app => {
             }
         }
 
-        async _checkNo(pid, contract, checkData) {
+        async _checkNo(pid, contract, type, checkData) {
             const accountId = this.ctx.session.sessionUser.accountId;
             const time = new Date();
-            const tableName = contract.cid !== undefined ? this.ctx.service.contractPay.tableName : this.ctx.service.contract.tableName;
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const tableName = {
+                contract: this.ctx.service.contract.tableName,
+                pay: this.ctx.service.contractPay.tableName,
+                supplement: this.ctx.service.contractSupplement.tableName,
+            }[type];
             const audits = contract.curAuditors;
             if (audits.length === 0) throw '审核数据错误';
             const selfAudit = audits.find(x => { return x.aid === accountId; });
             if (!selfAudit) throw '当前标段您无权审批';
-            const auditors = await this.getUniqAuditor(contract.cid || contract.id, contract.cid ? contract.id : null, contract.times, true); // 全部参与的审批人
+            const auditors = await this.getUniqAuditor(contract, type, contract.times, true); // 全部参与的审批人
             const newAuditors = auditors.map(x => {
                 return {
-                    aid: x.aid, spid: contract.spid || null, tid: contract.tid || null, cid: contract.cid ? contract.cid : contract.id, cpid: contract.cid ? contract.id : null,
+                    aid: x.aid, spid: contract.spid || null, tid: contract.tid || null, cid, cpid, csid,
                     times: contract.times + 1, order: x.audit_order, status: auditConst.status.uncheck,
                     audit_type: x.audit_type, audit_order: x.audit_order,
                 };
@@ -745,10 +820,17 @@ module.exports = app => {
          * @param {int} changeData - 变更令的数据
          * @return {void}
          */
-        async _checkNoPre(pid, contract, checkData) {
+        async _checkNoPre(pid, contract, type, checkData) {
             const accountId = this.ctx.session.sessionUser.accountId;
             const time = new Date();
-            const tableName = contract.cid !== undefined ? this.ctx.service.contractPay.tableName : this.ctx.service.contract.tableName;
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const tableName = {
+                contract: this.ctx.service.contract.tableName,
+                pay: this.ctx.service.contractPay.tableName,
+                supplement: this.ctx.service.contractSupplement.tableName,
+            }[type];
             // 整理当前流程审核人状态更新
             const audits = contract.curAuditors;
             if (audits.length === 0 || audits[0].order <= 1) throw '审核数据错误';
@@ -758,7 +840,7 @@ module.exports = app => {
 
             // 添加重新审批后,不能用order-1,取groupby值里的上一个才对
             // const preAuditor = await this.getDataByCondition({sid: stageId, times: times, order: audit.order - 1});
-            const auditors2 = await this.getAuditGroupByList(contract.cid || contract.id, contract.cid ? contract.id : null, contract.times);
+            const auditors2 = await this.getAuditGroupByList(contract, type, contract.times);
             const preAuditors = auditors2.filter(x => { return x.audit_order === selfAudit.audit_order - 1});
 
             const transaction = await this.db.beginTransaction();
@@ -802,13 +884,13 @@ module.exports = app => {
                 await transaction.updateRows(this.tableName, updateData);
                 // await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, this._.map(updateData, 'id'));
                 // 顺移其后审核人流程顺序
-                const sql = 'UPDATE ' + this.tableName + ' SET `order` = `order` + 2 WHERE cid = ? AND cpid' + (contract.cid !== undefined ? ' = ' + contract.id : ' is null') + ' AND times = ? AND `order` > ?';
-                await transaction.query(sql, [contract.cid ? contract.cid : contract.id, selfAudit.times, selfAudit.order]);
+                const sql = 'UPDATE ' + this.tableName + ' SET `order` = `order` + 2 WHERE cid = ? AND cpid' + (cpid ? ' = ' + cpid : ' is null') + ' AND csid' + (csid ? ' = ' + csid : ' is null') + ' AND times = ? AND `order` > ?';
+                await transaction.query(sql, [cid, selfAudit.times, selfAudit.order]);
                 // 上一审批人,当前审批人 再次添加至流程
                 const newAuditors = [];
                 preAuditors.forEach(x => {
                     newAuditors.push({
-                        spid: contract.spid || null, tid: contract.tid || null, cid: contract.cid ? contract.cid : contract.id, cpid: contract.cid ? contract.id : null, aid: x.aid,
+                        spid: contract.spid || null, tid: contract.tid || null, cid, cpid, csid, aid: x.aid,
                         times: x.times, order: selfAudit.order + 1,
                         status: auditConst.status.checking, begin_time: time,
                         audit_type: x.audit_type, audit_order: x.audit_order,
@@ -823,7 +905,7 @@ module.exports = app => {
                 const newFlowAuditors = [];
                 flowAudits.forEach(x => {
                     newFlowAuditors.push({
-                        spid: contract.spid || null, tid: contract.tid || null, cid: contract.cid ? contract.cid : contract.id, cpid: contract.cid ? contract.id : null, aid: x.aid,
+                        spid: contract.spid || null, tid: contract.tid || null, cid, cpid, csid, aid: x.aid,
                         times: x.times, order: selfAudit.order + 2,
                         status: auditConst.status.uncheck,
                         audit_type: x.audit_type, audit_order: x.audit_order,
@@ -842,13 +924,13 @@ module.exports = app => {
             }
         }
 
-        async getAuditorGroup(cid, cpid, times) {
-            const auditors = await this.getAuditors(cid, cpid, times); // 全部参与的审批人
+        async getAuditorGroup(contract, type, times) {
+            const auditors = await this.getAuditors(contract, type, times); // 全部参与的审批人
             return this.ctx.helper.groupAuditors(auditors, 'order');
         }
 
-        async getUserGroup(cid, cpid, times) {
-            const group = await this.getAuditorGroup(cid, cpid, times);
+        async getUserGroup(contract, type, times) {
+            const group = await this.getAuditorGroup(contract, type, times);
             // const sql =
             //     'SELECT pa.`id` As aid, pa.`name`, pa.`company`, pa.`role`, ? As times, ? As cpid, 0 As `order`, 1 As audit_type, 0 As audit_order' +
             //     '  FROM ' + this.ctx.service.changePlan.tableName + ' As s' +
@@ -862,8 +944,8 @@ module.exports = app => {
             return group;
         }
 
-        async getUniqUserGroup(cid, cpid, times) {
-            const group = await this.getAuditorGroup(cid, cpid, times);
+        async getUniqUserGroup(contract, type, times) {
+            const group = await this.getAuditorGroup(contract, type, times);
             // const sql =
             //     'SELECT pa.`id` As aid, pa.`name`, pa.`company`, pa.`role`, ? As times, ? As cpid, 0 As `order`, 1 As audit_type, 0 As audit_order' +
             //     '  FROM ' + this.ctx.service.changePlan.tableName + ' As s' +
@@ -877,11 +959,11 @@ module.exports = app => {
             return this.ctx.helper.groupAuditorsUniq(group);
         }
 
-        async getAuditorHistory(cid, cpid, times, reverse = false) {
+        async getAuditorHistory(contract, type, times, reverse = false) {
             const history = [];
             if (times >= 1) {
                 for (let i = 1; i <= times; i++) {
-                    const auditors = await this.getAuditors(cid, cpid, i);
+                    const auditors = await this.getAuditors(contract, type, i);
                     const group = this.ctx.helper.groupAuditors(auditors);
                     const historyGroup = [];
                     // 找出group里audit_order最大值
@@ -936,8 +1018,8 @@ module.exports = app => {
             return history;
         }
 
-        async getUniqAuditor(cid, cpid, times, noYb = false) {
-            const auditors = await this.getAuditors(cid, cpid, times, 'asc', noYb); // 全部参与的审批人
+        async getUniqAuditor(contract, type, times, noYb = false) {
+            const auditors = await this.getAuditors(contract, type, times, 'asc', noYb); // 全部参与的审批人
             const result = [];
             auditors.forEach(x => {
                 if (result.findIndex(r => { return x.aid === r.aid && x.audit_order === r.audit_order; }) < 0) {
@@ -947,44 +1029,62 @@ module.exports = app => {
             return result;
         }
 
-        async makeAudits(transaction, options, cid, cpid = null, uid) {
+        async makeAudits(transaction, options, contract, type, uid) {
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
             // 创建审批人列表
-            const lastContractInfo = await this.getHaveAuditLastInfo(options, cid, cpid, uid);
+            const lastContractInfo = await this.getHaveAuditLastInfo(options, contract, type, uid);
+            let auditList = [];
             if (lastContractInfo) {
                 // 再获取非原报审批人
-                const auditList = await this.getUniqAuditor(lastContractInfo.cid ? lastContractInfo.cid : lastContractInfo.id, lastContractInfo.cid ? lastContractInfo.id : null, lastContractInfo.times, true); // 全部参与的审批人
-                if (auditList.length > 0) {
-                    const spAudits = [];
-                    for (const x of auditList) {
-                        if (x.audit_order !== 0) {
-                            spAudits.push({
-                                spid: options.spid || null,
-                                tid: options.tid || null,
-                                cid, cpid, aid: x.aid,
-                                times: 1, order: x.audit_order, status: auditConst.status.uncheck,
-                                audit_type: x.audit_type, audit_order: x.audit_order,
-                            });
-                        }
+                auditList = await this.getUniqAuditor(lastContractInfo, type, lastContractInfo.times, true); // 全部参与的审批人
+            } else if ((type === 'supplement' || type === 'pay') && contract.cid) {
+                // 取该合同的审批人列表
+                const contractInfo = await this.ctx.service.contract.getDataById(contract.cid);
+                auditList = await this.getUniqAuditor(contractInfo, 'contract', contractInfo.times, true); // 全部参与的审批人
+            }
+            if (auditList.length > 0) {
+                const spAudits = [];
+                for (const x of auditList) {
+                    if (x.audit_order !== 0) {
+                        spAudits.push({
+                            spid: options.spid || null,
+                            tid: options.tid || null,
+                            cid, cpid, csid, aid: x.aid,
+                            times: 1, order: x.audit_order, status: auditConst.status.uncheck,
+                            audit_type: x.audit_type, audit_order: x.audit_order,
+                        });
                     }
-                    if (spAudits.length > 0) await transaction.insert(this.ctx.service.contractSpAudit.tableName, spAudits);
                 }
+                if (spAudits.length > 0) await transaction.insert(this.ctx.service.contractSpAudit.tableName, spAudits);
             }
         }
 
-        async getHaveAuditLastInfo(options, cid, cpid, uid) {
+        async getHaveAuditLastInfo(options, contract, type, uid) {
             const optionsSql = options.spid ? 'c.spid = "' + options.spid + '"' : 'c.tid = ' + options.tid;
-            const tableName = cpid ? this.ctx.service.contractPay.tableName : this.ctx.service.contract.tableName;
-            const joinSql = cpid ? 'ca.cpid' : 'ca.cid';
-            const cpidSql = cpid ? 'AND ca.`cpid` is not null' : 'AND ca.`cpid` is null';
-            const sql = 'SELECT c.* FROM ?? as c LEFT JOIN ?? as ca ON c.`id` = ' + joinSql + ' WHERE ' + optionsSql + ' AND c.`contract_type` = ? AND c.`uid` = ? ' + cpidSql + ' AND ca.`audit_order` > 0 ORDER BY c.`create_time` DESC';
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            const tableName = {
+                contract: this.ctx.service.contract.tableName,
+                pay: this.ctx.service.contractPay.tableName,
+                supplement: this.ctx.service.contractSupplement.tableName,
+            }[type];
+            const joinSql = cpid ? 'ca.`cpid`' : (csid ? 'ca.`csid`' : 'ca.`cid`');
+            const cpidSql = cpid ? ' AND ca.`cpid` is not null' : ' AND ca.`cpid` is null';
+            const csidSql = cpid ? ' AND ca.`csid` is not null' : ' AND ca.`csid` is null';
+            const sql = 'SELECT c.* FROM ?? as c LEFT JOIN ?? as ca ON c.`id` = ' + joinSql + ' WHERE ' + optionsSql + ' AND c.`contract_type` = ? AND c.`uid` = ?' + cpidSql + csidSql + ' AND ca.`audit_order` > 0 ORDER BY c.`create_time` DESC';
             const sqlParam = [tableName, this.tableName, options.contract_type, uid];
             return await this.db.queryOne(sql, sqlParam);
         }
 
-        async saveAudit(contract, times, sp_group, data) {
+        async saveAudit(contract, type, times, sp_group, data) {
             const transaction = await this.db.beginTransaction();
             try {
-                const auditors = await this.getAuditGroupByList(contract.cid || contract.id, contract.cid ? contract.id : null, times);
+                const cid = contract.cid ? contract.cid : contract.id;
+                const cpid = type === 'pay' ? contract.id : null;
+                const csid = type === 'supplement' ? contract.id : null;
+                const auditors = await this.getAuditGroupByList(contract, type, times);
                 const now_audit = this._.find(auditors, { aid: data.old_aid });
                 if (data.operate !== 'del') {
                     // const exist = await this.getDataByCondition({ cpid: cpId, times, aid: data.new_aid });
@@ -998,13 +1098,13 @@ module.exports = app => {
                         throw '当前人下无法操作新增';
                     }
                     const newAudit = {
-                        spid: contract.spid || null, tid: contract.tid || null, cid: contract.cid || contract.id, cpid: contract.cid ? contract.id : null, aid: data.new_aid,
+                        spid: contract.spid || null, tid: contract.tid || null, cid, cpid, csid, aid: data.new_aid,
                         order: now_audit.order + 1,
                         audit_order: now_audit.audit_order + 1, audit_type: auditType.key.common,
                         times, status: auditConst.status.uncheck,
                     };
                     // order+1
-                    await this._syncOrderByDelete(transaction, contract.cid || contract.id, contract.cid ? contract.id : null, now_audit.order + 1, times, '+');
+                    await this._syncOrderByDelete(transaction, contract, type, now_audit.order + 1, times, '+');
                     await transaction.insert(this.tableName, newAudit);
                     // 更新审批流程页数据,如果存在
                 } else if (data.operate === 'add-sibling') {
@@ -1012,7 +1112,7 @@ module.exports = app => {
                         throw '当前人下无法操作新增';
                     }
                     const newAudit = {
-                        spid: contract.spid || null, tid: contract.tid || null, cid: contract.cid || contract.id, cpid: contract.cid ? contract.id : null, aid: data.new_aid,
+                        spid: contract.spid || null, tid: contract.tid || null, cid, cpid, csid, aid: data.new_aid,
                         order: now_audit.order,
                         audit_order: now_audit.audit_order, audit_type: now_audit.audit_type,
                         times, status: auditConst.status.uncheck,
@@ -1023,8 +1123,8 @@ module.exports = app => {
                         throw '当前人无法操作删除';
                     }
                     const flowAuditors = auditors.filter(x => { return x.audit_order === now_audit.audit_order; });
-                    await transaction.delete(this.tableName, { cid: contract.cid || contract.id, cpid: contract.cid ? contract.id : null, times, aid: now_audit.aid, order: now_audit.order });
-                    if (flowAuditors.length === 1) await this._syncOrderByDelete(transaction, contract.cid || contract.id, contract.cid ? contract.id : null, now_audit.order, times);
+                    await transaction.delete(this.tableName, { cid, cpid, csid, times, aid: now_audit.aid, order: now_audit.order });
+                    if (flowAuditors.length === 1) await this._syncOrderByDelete(transaction, contract, type, now_audit.order, times);
                     // 旧的更新为is_old为1
                     // await transaction.update(this.tableName, { is_old: 1 }, {
                     //     where: {
@@ -1034,7 +1134,7 @@ module.exports = app => {
                     //     }
                     // });
                 } else if (data.operate === 'change') {
-                    const nowAudit = await this.getDataByCondition({ cid: contract.cid || contract.id, cpid: contract.cid ? contract.id : null, times, aid: now_audit.aid, order: now_audit.order });
+                    const nowAudit = await this.getDataByCondition({ cid, cpid, csid, times, aid: now_audit.aid, order: now_audit.order });
                     if (now_audit.status !== auditConst.status.uncheck || !nowAudit) {
                         throw '当前人无法操作替换';
                     }
@@ -1052,24 +1152,24 @@ module.exports = app => {
                 if (this.ctx.contract_tender) {
                     const tenderInfo = await this.ctx.service.tenderInfo.getTenderInfo(this.ctx.contract.id);
                     if (tenderInfo.shenpi.contract === shenpiConst.sp_status.gdspl) {
-                        const newAuditors = await transaction.select(this.tableName, { where: { cid: contract.cid || contract.id, cpid: contract.cid ? contract.id : null, times }, orders: [['order', 'asc']] });
+                        const newAuditors = await transaction.select(this.tableName, { where: { cid, cpid, csid, times }, orders: [['order', 'asc']] });
                         newAuditors.shift();
                         const newAuditorGroup = this.ctx.helper.groupAuditors(newAuditors, 'order');
                         const uniqNewAuditorGroup = this.ctx.helper.groupAuditorsUniq(newAuditorGroup);
                         await this.ctx.service.shenpiAudit.updateAuditListWithAuditType(transaction, this.ctx.contract.id, tenderInfo.shenpi.contract, shenpiConst.sp_type.contract, uniqNewAuditorGroup, sp_group);
                     } else if (tenderInfo.shenpi.contract === shenpiConst.sp_status.gdzs) {
-                        const newAuditors = await this.getAuditGroupByList(contract.cid || contract.id, contract.cid ? contract.id : null, times, transaction);
+                        const newAuditors = await this.getAuditGroupByList(contract, type, times, transaction);
                         await this.ctx.service.shenpiAudit.updateAuditList(transaction, this.ctx.contract.id, tenderInfo.shenpi.contract, shenpiConst.sp_type.contract, this._.map(newAuditors, 'aid'));
                     }
                 } else {
                     if (this.ctx.subProject.shenpi.contract === shenpiConst.sp_status.gdspl) {
-                        const newAuditors = await transaction.select(this.tableName, { where: { cid: contract.cid || contract.id, cpid: contract.cid ? contract.id : null, times }, orders: [['order', 'asc']] });
+                        const newAuditors = await transaction.select(this.tableName, { where: { cid, cpid, csid, times }, orders: [['order', 'asc']] });
                         newAuditors.shift();
                         const newAuditorGroup = this.ctx.helper.groupAuditors(newAuditors, 'order');
                         const uniqNewAuditorGroup = this.ctx.helper.groupAuditorsUniq(newAuditorGroup);
                         await this.ctx.service.shenpiAudit.updateAuditListWithAuditType(transaction, this.ctx.subProject.id, this.ctx.subProject.shenpi.contract, shenpiConst.sp_type.contract, uniqNewAuditorGroup, sp_group);
                     } else if (this.ctx.subProject.shenpi.contract === shenpiConst.sp_status.gdzs) {
-                        const newAuditors = await this.getAuditGroupByList(contract.cid || contract.id, contract.cid ? contract.id : null, times, transaction);
+                        const newAuditors = await this.getAuditGroupByList(contract, type, times, transaction);
                         await this.ctx.service.shenpiAudit.updateAuditList(transaction, this.ctx.subProject.id, this.ctx.subProject.shenpi.contract, shenpiConst.sp_type.contract, this._.map(newAuditors, 'aid'));
                     }
                 }
@@ -1081,7 +1181,7 @@ module.exports = app => {
             }
         }
 
-        async changeSpGroup(contract, sp_group) {
+        async changeSpGroup(contract, type, sp_group) {
             const transaction = await this.db.beginTransaction();
             try {
                 const group = await this.ctx.service.shenpiGroup.getDataById(sp_group);
@@ -1096,11 +1196,13 @@ module.exports = app => {
                 }
                 const shenpiList = await this.ctx.service.shenpiAudit.getAllDataByCondition({ where: condition });
                 // await this.ctx.service.shenpiAudit.noYbShenpiList(change.uid, shenpiList);
-                await this.updateNewAuditors(contract, shenpiList, transaction);
-                if (contract.cid === undefined) {
+                await this.updateNewAuditors(contract, type, shenpiList, transaction);
+                if (type === 'contract') {
                     await transaction.update(this.ctx.service.contract.tableName, { id: contract.id, sp_group: group.id });
-                } else {
+                } else if (type === 'pay') {
                     await transaction.update(this.ctx.service.contractPay.tableName, { id: contract.id, sp_group: group.id });
+                } else if (type === 'supplement') {
+                    await transaction.update(this.ctx.service.contractSupplement.tableName, { id: contract.id, sp_group: group.id });
                 }
                 await transaction.commit();
             } catch (err) {
@@ -1110,10 +1212,10 @@ module.exports = app => {
             return true;
         }
 
-        async updateNewAuditList(contract, newList) {
+        async updateNewAuditList(contract, type, newList) {
             const transaction = await this.db.beginTransaction();
             try {
-                await this.updateNewAuditors(contract, newList, transaction);
+                await this.updateNewAuditors(contract, type, newList, transaction);
                 await transaction.commit();
             } catch (err) {
                 await transaction.rollback();
@@ -1121,22 +1223,21 @@ module.exports = app => {
             }
         }
 
-        async updateNewAuditors(contract, newList, transaction) {
+        async updateNewAuditors(contract, type, newList, transaction) {
             const condition = { times: contract.times };
-            if (contract.cid !== undefined) {
-                condition.cid = contract.cid;
-                condition.cpid = contract.id;
-            } else {
-                condition.cid = contract.id;
-                condition.cpid = null;
-            }
+            const cid = contract.cid ? contract.cid : contract.id;
+            const cpid = type === 'pay' ? contract.id : null;
+            const csid = type === 'supplement' ? contract.id : null;
+            condition.cid = cid;
+            condition.cpid = cpid;
+            condition.csid = csid;
             // 先删除旧的审批流,再添加新的
             await transaction.delete(this.tableName, condition);
 
             const newAuditors = [];
             for (const auditor of newList) {
                 newAuditors.push({
-                    spid: contract.spid || null, tid: contract.tid || null, cid: contract.cid || contract.id, cpid: contract.cid ? contract.id : null, aid: auditor.audit_id,
+                    spid: contract.spid || null, tid: contract.tid || null, cid, cpid, csid, aid: auditor.audit_id,
                     times: contract.times, order: auditor.audit_order, status: auditConst.status.uncheck,
                     audit_type: auditor.audit_type, audit_order: auditor.audit_order,
                 });
@@ -1156,21 +1257,20 @@ module.exports = app => {
             }
         }
 
-        async updateLastAudit(contract, auditList, lastId) {
+        async updateLastAudit(contract, type, auditList, lastId) {
             const transaction = await this.db.beginTransaction();
             try {
                 // 先判断auditList里的aid是否与lastId相同,相同则删除并重新更新order
                 const existAudit = auditList.find(x => { return x.aid === lastId; });
+                const cid = contract.cid ? contract.cid : contract.id;
+                const cpid = type === 'pay' ? contract.id : null;
+                const csid = type === 'supplement' ? contract.id : null;
                 let order = auditList.length > 0 ? auditList.reduce((rst, a) => { return Math.max(rst, a.order); }, 0) + 1 : 1; // 最大值 + 1
                 if (existAudit) {
                     const condition = { times: contract.times, aid: lastId };
-                    if (contract.cid !== undefined) {
-                        condition.cid = contract.cid;
-                        condition.cpid = contract.id;
-                    } else {
-                        condition.cid = contract.id;
-                        condition.cpid = null;
-                    }
+                    condition.cid = cid;
+                    condition.cpid = cpid;
+                    condition.csid = csid;
                     await transaction.delete(this.tableName, condition);
                     const sameOrder = auditList.filter(x => { return x.order === existAudit.order; });
                     if (sameOrder.length === 1) {
@@ -1187,7 +1287,7 @@ module.exports = app => {
                 }
                 // 添加终审
                 const newAuditor = {
-                    spid: contract.spid || null, tid: contract.tid || null, cid: contract.cid || contract.id, cpid: contract.cid ? contract.id : null, aid: lastId,
+                    spid: contract.spid || null, tid: contract.tid || null, cid, cpid, csid, aid: lastId,
                     times: contract.times, order, status: auditConst.status.uncheck,
                     audit_type: auditType.key.common, audit_order: order,
                 };

+ 10 - 7
app/service/contract_supplement.js

@@ -32,16 +32,17 @@ module.exports = app => {
             const shenpi_status = this.ctx.contract_tender ? this.ctx.subProject.page_show.openContractTenderShenpi : this.ctx.subProject.page_show.openContractSubProjectShenpi;
             if (list.length > 0) {
                 const userList = await this.ctx.service.projectAccount.getAllDataByCondition({ where: { id: list.map(item => item.uid) } });
+                const type = 'supplement';
                 for (const l of list) {
                     const userInfo = userList.find(item => item.id === l.uid);
                     l.username = userInfo ? userInfo.name : '';
                     l.files = await this.ctx.service.contractSupplementAtt.getAtt(l.id);
                     if (shenpi_status) {
-                        await this.ctx.service.contractSpAudit.loadUser(l);
-                        await this.ctx.service.contractSpAudit.loadAuditViewData(l);
-                        await this.ctx.service.contractSpAudit.checkShenpi(l);
+                        await this.ctx.service.contractSpAudit.loadUser(l, type);
+                        await this.ctx.service.contractSpAudit.loadAuditViewData(l, type);
+                        await this.ctx.service.contractSpAudit.checkShenpi(l, type);
                         if (l.status !== auditConst.status.checked || !l.final_auditor_str) {
-                            l.curAuditors2 = await this.ctx.service.contractSpAudit.getAuditorsByStatus(l.cid, l.id, l.status, l.times);
+                            l.curAuditors2 = await this.ctx.service.contractSpAudit.getAuditorsByStatus(l, type, l.status, l.times);
                             if (l.status === auditConst.status.checked && !l.final_auditor_str) {
                                 const final_auditor_str = l.curAuditors2[0].audit_type === auditType.key.common
                                     ? l.curAuditors2[0].name + (l.curAuditors2[0].role ? '-' + l.curAuditors2[0].role : '')
@@ -72,8 +73,8 @@ module.exports = app => {
                     code: data.code,
                     name: data.name,
                     price: data.price || 0,
-                    party_a: data.party_a || 0,
-                    party_b: data.party_b || 0,
+                    party_a: data.party_a,
+                    party_b: data.party_b,
                     sign_time: data.sign_time || null,
                     address: data.address,
                     content: data.content,
@@ -82,7 +83,8 @@ module.exports = app => {
                 };
                 const result = await transaction.insert(this.tableName, insertData);
                 await this.calcContract(transaction, node);
-                await this.ctx.service.contractSpAudit.makeAudits(transaction, options, cid, result.insertId, this.ctx.session.sessionUser.accountId);
+                insertData.id = result.insertId;
+                await this.ctx.service.contractSpAudit.makeAudits(transaction, options, insertData, 'supplement', this.ctx.session.sessionUser.accountId);
                 await transaction.commit();
             } catch (err) {
                 await transaction.rollback();
@@ -151,6 +153,7 @@ module.exports = app => {
                 supplement_price = this.ctx.helper.add(supplement_price, l.price);
             }
             node.supplement_price = supplement_price;
+            node.total_price = this.ctx.helper.add(node.price, supplement_price);
             node.exist_supplement = supplementsList.length === 0 ? 0 : 1;
             await transaction.update(this.ctx.service.contract.tableName, node);
         }

+ 12 - 4
app/service/contract_tree.js

@@ -381,11 +381,13 @@ module.exports = app => {
                     if (select.uid !== this.ctx.session.sessionUser.accountId && !this.ctx.session.sessionUser.is_admin) throw '当前合同无权删除';
                     const contractPays = await this.ctx.service.contractPay.getDataByCondition({ cid: select.id });
                     if (contractPays) throw '还存在合同支付项,无法删除';
+                    const contractSupplements = await this.ctx.service.contractSupplement.getDataByCondition({ cid: select.id });
+                    if (contractSupplements) throw '还存在补充合同,无法删除';
                     await transaction.delete(this.ctx.service.contract.tableName, { id: select.id });
                     const attList = await this.ctx.service.contractAtt.getAllDataByCondition({ where: { cid: select.id } });
                     await this.ctx.helper.delFiles(attList);
                     await transaction.delete(this.ctx.service.contractAtt.tableName, { cid: select.id });
-                    await transaction.delete(this.ctx.service.contractSpAudit.tableName, { cid: select.id, cpid: null });
+                    await transaction.delete(this.ctx.service.contractSpAudit.tableName, { cid: select.id, cpid: null, csid: null });
                 } else {
                     await transaction.delete(this.tableName, { id: select.id });
                     const delOptions = this._.cloneDeep(options);
@@ -399,10 +401,12 @@ module.exports = app => {
                         if (contractUids.length > 1 || !(contractUids[0] === this.ctx.session.sessionUser.accountId || this.ctx.session.sessionUser.is_admin)) throw '存在合同你无权删除';
                         const contractPays = await transaction.select(this.ctx.service.contractPay.tableName, { where: { cid: this.ctx.helper._.map(contracts, 'id') } });
                         if (contractPays.length > 0) throw '还存在合同支付项,无法删除';
+                        const contractSupplements = await this.ctx.service.contractSupplement.getDataByCondition({ cid: this.ctx.helper._.map(contracts, 'id') });
+                        if (contractSupplements) throw '还存在补充合同,无法删除';
                         const attList = await this.ctx.service.contractAtt.getAllDataByCondition({ where: { cid: this.ctx.helper._.map(contracts, 'id') } });
                         await this.ctx.helper.delFiles(attList);
                         await transaction.delete(this.ctx.service.contractAtt.tableName, { cid: this.ctx.helper._.map(contracts, 'id') });
-                        await transaction.delete(this.ctx.service.contractSpAudit.tableName, { cid: this.ctx.helper._.map(contracts, 'id'), cpid: null });
+                        await transaction.delete(this.ctx.service.contractSpAudit.tableName, { cid: this.ctx.helper._.map(contracts, 'id'), cpid: null, csid: null });
                     }
                     const operate = await this._deletePosterity(options, select, transaction);
                 }
@@ -462,11 +466,13 @@ module.exports = app => {
                         if (s.uid !== this.ctx.session.sessionUser.accountId && !this.ctx.session.sessionUser.is_admin) throw '存在合同你无权删除';
                         const contractPays = await this.ctx.service.contractPay.getDataByCondition({ cid: s.id });
                         if (contractPays) throw '部分合同还存在合同支付项,无法删除';
+                        const contractSupplements = await this.ctx.service.contractSupplement.getDataByCondition({ cid: s.id });
+                        if (contractSupplements) throw '部分合同还存在补充合同,无法删除';
                         await transaction.delete(this.ctx.service.contract.tableName, { id: s.id });
                         const attList = await this.ctx.service.contractAtt.getAllDataByCondition({ where: { cid: s.id } });
                         await this.ctx.helper.delFiles(attList);
                         await transaction.delete(this.ctx.service.contractAtt.tableName, { cid: s.id });
-                        await transaction.delete(this.ctx.service.contractSpAudit.tableName, { cid: s.id, cpid: null });
+                        await transaction.delete(this.ctx.service.contractSpAudit.tableName, { cid: s.id, cpid: null, csid: null });
                     } else {
                         await transaction.delete(this.tableName, { id: s.id });
                         const contracts = _.filter(deleteData, function (item) {
@@ -477,10 +483,12 @@ module.exports = app => {
                             if (contractUids.length > 1 || !(contractUids[0] === this.ctx.session.sessionUser.accountId || this.ctx.session.sessionUser.is_admin)) throw '存在合同你无权删除';
                             const contractPays = await transaction.select(this.ctx.service.contractPay.tableName, { where: { cid: _.map(contracts, 'id') } });
                             if (contractPays.length > 0) throw '还存在合同支付项,无法删除';
+                            const contractSupplements = await this.ctx.service.contractSupplement.getDataByCondition({ cid: _.map(contracts, 'id') });
+                            if (contractSupplements) throw '部分合同还存在补充合同,无法删除';
                             const attList = await this.ctx.service.contractAtt.getAllDataByCondition({ where: { cid: _.map(contracts, 'id') } });
                             await this.ctx.helper.delFiles(attList);
                             await transaction.delete(this.ctx.service.contractAtt.tableName, { cid: _.map(contracts, 'id') });
-                            await transaction.delete(this.ctx.service.contractSpAudit.tableName, { cid: _.map(contracts, 'id'), cpid: null });
+                            await transaction.delete(this.ctx.service.contractSpAudit.tableName, { cid: _.map(contracts, 'id'), cpid: null, csid: null });
                         }
                     }
                     const operate = await this._deletePosterity(options, s, transaction);

+ 7 - 7
app/view/contract/detail.ejs

@@ -79,9 +79,9 @@
                             <li class="nav-item">
                                 <a class="nav-link " data-toggle="tab" href="#htfile" role="tab">合同文件</a>
                             </li>
-<!--                            <li class="nav-item">-->
-<!--                                <a class="nav-link " data-toggle="tab" href="#htsupplement" role="tab">补充合同</a>-->
-<!--                            </li>-->
+                            <li class="nav-item">
+                                <a class="nav-link " data-toggle="tab" href="#htsupplement" role="tab">补充合同</a>
+                            </li>
                             <li class="ml-auto">
                                 <!-- 结算合同所有tab可见 ,结算后见解锁合同,2者互斥-->
                                 <a href="#cons-unlock" data-toggle="modal" data-target="#cons-unlock" style="display: none;" class="btn btn-success btn-sm pull-right mr-2">解锁合同</a>
@@ -96,7 +96,7 @@
                                 <a href="javascript:void(0);" id="save_contract_btn" style="display: none" class="btn btn-primary btn-sm pull-right mr-2">确定</a>
                                 <a href="javascript:void(0);" id="edit_contract_btn" style="display: none" class="btn btn-primary btn-sm pull-right mr-2">编辑合同</a>
                                 <a href="javascript:void(0);" id="add_contract_supplement_btn" style="display: none;" class="btn btn-primary btn-sm pull-right mr-2">新增补充合同</a>
-                            <% if (shenpi_status) { %>
+                                <% if (shenpi_status) { %>
                                     <span class="pull-right mr-2" id="shenpi_btn">
                                     <a href="#sub-sp" data-toggle="modal" data-target="#sub-sp" class="btn btn-primary btn-sm">待上报</a>
                                 </span>
@@ -117,8 +117,8 @@
                                         <td width="20%" class="change-input-td" id="htdetail_tax"></td>
                                     </tr>
                                     <tr>
-                                        <th class="text-center align-middle">合同金额</th>
-                                        <td class="change-input-td" id="htdetail_total_price"></td>
+                                        <th class="text-center align-middle">合同金额 <a href="javascript:void(0);" data-toggle="tooltip" data-placement="bottom" id="show-supplement-price" title="" data-original-title="补充合同金额:"><i class="fa fa-question-circle-o"></i></a></th>
+                                        <td class="change-input-td" id="htdetail_price"></td>
                                         <th class="text-center align-middle"><% if (ctx.contract_type === contractConst.type.income) { %>累计回款(P)<% } else if (ctx.contract_type === contractConst.type.expenses) { %>累计付款(P)<% } %></th>
                                         <td id="htdetail_pay_price"></td>
                                         <th class="text-center align-middle">累计扣款(K)</th>
@@ -267,7 +267,7 @@
                                 <table class="table table-sm table-bordered" id="htsupplement-table" style="display: none;">
                                     <thead>
                                     <tr class="text-center" id="supplement-header">
-                                        <th width="3%">序号</th><th width="5%" sort="code">编号</th><th width="10%">名称</th><th width="7%">金额</th><th width="10%">甲方</th><th width="10%">乙方</th><th width="5%">签订时间</th><th width="5%">签订地点</th><th width="5%">创建人</th><th width="9%" sort="create_time">创建时间</th><th width="15%">补充原因及内容</th><th width="4%">附件</th>
+                                        <th width="3%">序号</th><th width="5%" sort="code">编号</th><th width="8%">名称</th><th width="7%">金额</th><th width="8%">甲方</th><th width="8%">乙方</th><th width="5%">签订时间</th><th width="5%">签订地点</th><th width="5%">创建人</th><th width="9%" sort="create_time">创建时间</th><th width="10%">补充原因及内容</th><th width="4%">附件</th>
                                         <% if (shenpi_status) { %>
                                             <th width="15%">审批进度</th>
                                         <% } %>

+ 3 - 1
app/view/contract/detail_modal.ejs

@@ -19,7 +19,7 @@
                 </div>
                 <div class="form-group">
                     <label>合同金额<b class="text-danger">*</b></label>
-                    <input class="form-control form-control-sm" placeholder="请输入合同金额" type="text" name="total_price">
+                    <input class="form-control form-control-sm" placeholder="请输入合同金额" type="text" name="price">
                     <div class="invalid-feedback">合同金额不能为0。</div>
                 </div>
                 <div class="form-group">
@@ -505,6 +505,7 @@
                 <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
                 <input type="hidden" id="start-sp-cid" />
                 <input type="hidden" id="start-sp-cpid" />
+                <input type="hidden" id="start-sp-csid" />
                 <button class="btn btn-primary btn-sm" type="button" id="start-sp-btn">确认上报</button>
             </div>
         </div>
@@ -536,6 +537,7 @@
                 <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
                 <input type="hidden" id="check-sp-cid" />
                 <input type="hidden" id="check-sp-cpid" />
+                <input type="hidden" id="check-sp-csid" />
                 <input type="hidden" id="check-operate" />
                 <span id="check-sp-btn-html">
                 </span>

+ 7 - 1
sql/update.sql

@@ -11,10 +11,16 @@
 -- 表结构
 ------------------------------------
 
+ALTER TABLE `zh_contract`
+ADD COLUMN `price` decimal(30, 8) NULL DEFAULT 0 COMMENT '合同金额(可编辑,和补充合同金额汇总得出总金额)' AFTER `total_price`;
+
+update zh_contract set price = total_price;
+
+
 ALTER TABLE `zh_sub_project`
 ADD COLUMN `cost_ledger_col_set` json NULL COMMENT '成本报审-列设置' AFTER `cost_calc_template`;
 
 
 ------------------------------------
 -- 表数据
-------------------------------------
+------------------------------------