Просмотр исходного кода

决算对比,汇总合同相关

MaiXinRong 1 месяц назад
Родитель
Сommit
14d3858afe

+ 8 - 2
app/controller/budget_controller.js

@@ -57,7 +57,6 @@ module.exports = app => {
                 renderData.categoryData = await this.ctx.service.category.getAllCategory(ctx.subProject);
                 await this.layout('budget/list.ejs', renderData, 'budget/list_modal.ejs');
             } catch (err) {
-                console.log(err);
                 ctx.log(err);
                 ctx.session.postError = err.toString();
                 ctx.redirect(this.menu.menu.dashboard.url);
@@ -92,6 +91,12 @@ module.exports = app => {
             }
         }
 
+        async _getContractTree(condition) {
+            const data = await this.ctx.service.contractTree.getAllDataByCondition({ where: condition });
+            const contract_data = await this.ctx.service.contract.getAllDataByCondition({ where: condition });
+            return [...data, ...contract_data];
+        }
+
         async compare(ctx) {
             try {
                 const renderData = {
@@ -106,6 +111,7 @@ module.exports = app => {
                     return { id: y.id, name: y.name, lastStageOrder: y.lastStage.order, lastStageStatus: auditConst.stage.statusString[y.lastStage.status], category: y.category };
                 });
                 renderData.categoryData = await this.ctx.service.category.getAllCategory(ctx.subProject);
+                renderData.contract = await this._getContractTree({ spid: this.ctx.subProject.id, contract_type: 1 });
                 await this.layout('budget/compare.ejs', renderData, 'budget/compare_modal.ejs');
             } catch (err) {
                 ctx.log(err);
@@ -145,7 +151,7 @@ module.exports = app => {
                     ctx.body = { err: 0, msg: `决算数据已在${ctx.moment(finalInfo.update_time).format('YYYY-DD-MM HH:mm:ss')}更新,请先查看后再决定是否生成`, data: { final, finalInfo } };
                 } else {
                     const finalInfo = await ctx.service.budgetFinalList.addFinal(ctx.budget, data.id);
-                    const final = await ctx.service.budget.doFinal(ctx.budget, finalInfo, data.stage);
+                    const final = await ctx.service.budget.doFinal(ctx.budget, finalInfo, data.stage, data.contracts);
                     ctx.body = { err: 0, msg: '', data: { final, finalInfo } };
                 }
             } catch (err) {

+ 37 - 4
app/lib/budget_final.js

@@ -303,8 +303,41 @@ class BudgetFinal {
         });
     }
 
-    async _loadDeal(deal) {
-        // todo
+    async _loadDeal(deal, stage) {
+        const helper = this.ctx.helper;
+        const treeData = await this.ctx.service.contractTree.getAllDataByCondition({ where: { id: deal, spid: this.ctx.subProject.id, contract_type: 1 } });
+        const contractData = await this.ctx.service.contract.getAllDataByCondition({ where: { id: deal, spid: this.ctx.subProject.id, contract_type: 1 } });
+
+        const paySqlParam = [];
+        const timeFilter = stage.type === 'month' ? `AND pay_time <= ? ` : '';
+        if (stage.type === 'month') {
+            paySqlParam.push(this.ctx.moment(stage.month, 'YYYY-MM').endOf('month').format('YYYY-MM-DD HH:mm:ss'));
+        }
+        const checkedFilter = stage.checked && this.ctx.subProject.page_show.openContractPaySubProjectShenpi ? ' AND status = 3 ' : '';
+        const paySql = `SELECT cid, SUM(yf_price) AS yf_tp FROM ${this.ctx.service.contractPay.tableName}` +
+            `    WHERE cid IN(${contractData.map(x => { return `'${x.id}'`}).join(', ')}) ` + timeFilter + checkedFilter +
+            '    GROUP BY cid';
+        const contractPayData = await this.ctx.service.contractPay.db.query(paySql, paySqlParam);
+        for (const c of contractData) {
+            const cp = contractPayData.find(x => { return x.cid === c.id; });
+            c.yf_tp = cp ? cp.yf_tp || 0 : 0;
+        }
+
+        const tree = new BillsTree(this.ctx, {
+            id: 'contract_id',
+            pid: 'contract_pid',
+            order: 'order',
+            level: 'level',
+            rootId: -1,
+            calcFields: ['total_price', 'yf_tp'],
+            calc: function (node, helper, decimal) {},
+        });
+        tree.loadDatas([...treeData, ...contractData]);
+        this.finalTree.loadTree(tree, function (cur, source) {
+            cur.total_price = helper.add(cur.total_price, source.total_price);
+            cur.final_contract_tp = helper.add(cur.final_contract_tp, source.yf_tp);
+            cur.final_tp = helper.add(cur.final_tp, source.yf_tp);
+        });
     }
 
     async _afterLoad() {
@@ -394,7 +427,7 @@ class BudgetFinal {
         return data;
     }
 
-    async doFinal(budget, final, stage) {
+    async doFinal(budget, final, stage, contract) {
         this.budget = budget;
         this.final = final;
         this.finalTree.checkField = budget.final_type.split('_');
@@ -407,7 +440,7 @@ class BudgetFinal {
         await this._loadYu(budget);
         await this._loadGai(budget);
         await this._loadGu(budget);
-        await this._loadDeal(final.deal);
+        await this._loadDeal(contract, stage);
         this._afterLoad();
         return this.getFinalData();
     }

+ 59 - 3
app/public/js/budget_compare.js

@@ -467,7 +467,7 @@ $(document).ready(() => {
             if (compareObj.finalInfo) {
                 this.selectTree.datas.forEach(x => {
                     x.selected = compareObj.finalInfo.tender.indexOf(x.tid + '') >= 0;
-                })
+                });
             }
             const sfSpreadSetting = {
                 cols: [
@@ -486,11 +486,31 @@ $(document).ready(() => {
                 selectedBackColor: '#fffacd',
                 readOnly: true,
             };
-            this.spread = SpreadJsObj.createNewSpread($('#sf-spread')[0]);
+            this.spread = SpreadJsObj.createNewSpread($('#sf-tender-spread')[0]);
             this.sheet = this.spread.getActiveSheet();
             SpreadJsObj.initSheet(this.sheet, sfSpreadSetting);
             SpreadJsObj.loadSheetData(this.sheet, SpreadJsObj.DataType.Tree, this.selectTree);
 
+            this.contractTree = createNewPathTree('base', { id: 'contract_id', pid: 'contract_pid', order: 'order', level: 'level', fullPath: 'full_path', rootId: -1 });
+            this.contractTree.loadDatas(contract);
+            this.contractSpread = SpreadJsObj.createNewSpread($('#sf-contract-spread')[0]);
+            this.contractSheet = this.contractSpread.getActiveSheet();
+            SpreadJsObj.initSheet(this.contractSheet, {
+                cols: [
+                    {title: '选择', colSpan: '1', rowSpan: '1', field: 'selected', hAlign: 1, width: 40, formatter: '@', cellType: 'checkbox'},
+                    {title: '编号', colSpan: '1', rowSpan: '1', field: 'code', hAlign: 0, width: 120, formatter: '@', cellType: 'tree'},
+                    {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 200, formatter: '@'},
+                ],
+                emptyRows: 0,
+                headRows: 1,
+                headRowHeight: [32],
+                defaultRowHeight: 21,
+                headerFont: '12px 微软雅黑',
+                font: '12px 微软雅黑',
+                readOnly: true,
+            });
+            SpreadJsObj.loadSheetData(this.contractSheet, SpreadJsObj.DataType.Tree, this.contractTree);
+
             this.spread.bind(spreadNS.Events.ButtonClicked, function (e, info) {
                 if (!info.sheet.zh_setting) return;
 
@@ -502,6 +522,24 @@ $(document).ready(() => {
                 SpreadJsObj.reloadColData(info.sheet, 0);
             });
 
+            this.contractSpread.bind(spreadNS.Events.ButtonClicked, function (e, info) {
+                if (!info.sheet.zh_setting) return;
+
+                const col = info.sheet.zh_setting.cols[info.col];
+                if (col.field !== 'selected') return;
+
+                const node = SpreadJsObj.getSelectObject(info.sheet);
+                self.selectContract(node, !node[col.field]);
+                SpreadJsObj.reloadColData(info.sheet, 0);
+            });
+
+            $('[name=sf-tab]').click(function() {
+                const content = this.getAttribute('href');
+                if (content === '#sf-contract') {
+                    self.contractSpread.refresh();
+                }
+                if (content === '#sf-tender') self.spread.refresh();
+            });
 
             $('#sf-select-all').click(function() {
                 for (const n of self.selectTree.nodes) {
@@ -527,7 +565,8 @@ $(document).ready(() => {
                         return;
                     }
                 }
-                const data = { final_id: compareObj.curFinalId(), id: rela, final_type: $('[name=final_type]:checked').val(), stage };
+                const contracts = self.getSelectContracts();
+                const data = { final_id: compareObj.curFinalId(), id: rela, final_type: $('[name=final_type]:checked').val(), stage, contracts };
                 postData(window.location.pathname + '/final', data, function(result, msg) {
                     compareObj.loadFinalData(result, msg);
                     $('#select-final').modal('hide');
@@ -549,6 +588,19 @@ $(document).ready(() => {
                 p.selected = select;
             }
         }
+        selectContract(node, select) {
+            const posterity = this.contractTree.getPosterity(node);
+            posterity.unshift(node);
+            for (const p of posterity) {
+                if (p) p.selected = select;
+            }
+            if (select) {
+                const parents = this.contractTree.getAllParents(node);
+                for(const p of parents) {
+                    if (p) p.selected = select;
+                }
+            }
+        }
         getSelects() {
             const select = [];
             for (const n of this.selectTree.nodes) {
@@ -556,6 +608,10 @@ $(document).ready(() => {
             }
             return select;
         }
+        getSelectContracts() {
+            const select = this.contractTree.nodes.filter(x => { return !!x.selected; }).map(x => { return x.id; });
+            return select;
+        }
     }
 
     $('#select-final').on('shown.bs.modal', () => {

+ 2 - 2
app/service/budget.js

@@ -263,11 +263,11 @@ module.exports = app => {
             }
         }
 
-        async doFinal(budget, final, stage) {
+        async doFinal(budget, final, stage, contract) {
             const finalObj = new FinalObj(this.ctx);
             let finalData;
             try {
-                finalData = await finalObj.doFinal(budget, final, stage);
+                finalData = await finalObj.doFinal(budget, final, stage, contract);
             } catch (err) {
                 this.db.update(this.ctx.service.budgetFinalList.tableName, { id: final.id, status: 4});
                 this.ctx.log(err);

+ 1 - 0
app/view/budget/compare.ejs

@@ -117,4 +117,5 @@
     const category = JSON.parse(unescape('<%- escape(JSON.stringify(categoryData)) %>'));
     const tenderList = JSON.parse(unescape('<%- escape(JSON.stringify(tenderList)) %>'));
     const ckColSetting = 'budget-col-visible-1.0.0';
+    const contract = JSON.parse(unescape('<%- escape(JSON.stringify(contract)) %>'));
 </script>

+ 18 - 2
app/view/budget/compare_modal.ejs

@@ -41,8 +41,24 @@
                         </div>
                     </div>
                 </div>
-                <h5>可选标段</h5>
-                <div id="sf-spread" style="height: 300px"></div>
+                <div>
+                    <ul class="nav nav-tabs">
+                        <li class="nav-item">
+                            <a class="nav-link active" data-toggle="tab" href="#sf-tender" role="tab" name="sf-tab">可选标段</a>
+                        </li>
+                        <li class="nav-item">
+                            <a class="nav-link" data-toggle="tab" href="#sf-contract" role="tab" name="sf-tab">可选合同</a>
+                        </li>
+                    </ul>
+                </div>
+                <div class="tab-content">
+                    <div id="sf-tender" class="tab-pane active">
+                        <div id="sf-tender-spread" style="height: 300px"></div>
+                    </div>
+                    <div id="sf-contract" class="tab-pane">
+                        <div id="sf-contract-spread" style="height: 300px"></div>
+                    </div>
+                </div>
             </div>
             <div class="modal-footer" style="justify-content: space-between">
                 <div class="d-flex">