瀏覽代碼

Merge branch 'dev' of http://192.168.1.41:3000/maixinrong/Calculation into dev

TonyKang 4 年之前
父節點
當前提交
54fb570138

+ 1 - 1
app/const/change.js

@@ -106,4 +106,4 @@ module.exports = {
         souban: { unit: '艘班' },
         mu: { unit: '亩' },
     },
-}
+};

+ 3 - 0
app/const/deal_pay.js

@@ -32,6 +32,9 @@ const calcBase = [
     {name: '本期完成计量', code: 'bqwc', limit: true, sort: 10},
     {name: '本期合同计量', code: 'bqht', limit: true, sort: 10},
     {name: '本期变更计量', code: 'bqbg', limit: true, sort: 10},
+    {name: '本期一般变更计量', code: 'ybbqbg', limit: true, sort: 15},
+    {name: '本期较大变更计量', code: 'jdbqbg', limit: true, sort: 15},
+    {name: '本期重大变更计量', code: 'zdbqbg', limit: true, sort: 15},
     {name: '100章本期完成计量', code: 'ybbqwc', limit: true, sort: 1},
     {name: '本期应付', code: 'bqyf', limit: true, ptNormalLimit: true, sort: 20},
 ];

+ 5 - 2
app/controller/tender_controller.js

@@ -21,8 +21,8 @@ const billsPosConvert = require('../lib/bills_pos_convert');
 const path = require('path');
 const sendToWormhole = require('stream-wormhole');
 const scheduleConst = require('../const/schedule');
-const SumLoad = require('../lib/sum_load');
 const changeConst = require('../const/change');
+const tenderInfoModel = require('../lib/tender_info');
 
 module.exports = app => {
 
@@ -442,6 +442,9 @@ module.exports = app => {
                         tender.status_users = status_name ? status_name.name : '';
                     }
                 }
+                const tiModel = new tenderInfoModel(ctx);
+                const gclChapter = await tiModel.gatherChapter();
+
                 const monthProgress = [];
                 for (const s of stages) {
                     if (s.s_time) {
@@ -526,6 +529,7 @@ module.exports = app => {
                     stage_total,
                     hadMap,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.tender.tenderInfo),
+                    gclChapter,
                 };
                 if (ctx.session.sessionUser.is_admin) {
                     renderData.tourists = await ctx.service.tenderTourist.getTourists(tender.id);
@@ -1202,7 +1206,6 @@ module.exports = app => {
                         throw '数据错误';
                 }
             } catch (err) {
-                console.log(err);
                 this.log(err);
                 this.ajaxErrorBody(err, '导入数据失败');
             }

+ 0 - 2
app/lib/pay_calc.js

@@ -105,7 +105,6 @@ class PayCalculate {
      * @param {Array} pays - (标段)合同支付数据
      */
     async calculateStartRangePrice (pays) {
-        await this.getCalcBase();
         const order = this.stage.curOrder;
         for (const p of pays) {
             // 非本期,本次添加的合同支付项,不允许计算,其中默认添加的合同支付项,归属于第一期原报
@@ -167,7 +166,6 @@ class PayCalculate {
      * @param {Array} pays - (标段&期)合同支付数据
      */
     async calculate(pays) {
-        await this.getCalcBase();
         this.yf = pays.find(function (p) {
             return p.ptype === payType.yf;
         });

+ 4 - 2
app/lib/sum_load.js

@@ -124,7 +124,7 @@ class loadLedgerGclTree extends loadGclBaseTree {
     }
 
     getUpdateData() {
-        const update = {id: this.parent.id, is_leaf: false};
+        const update = [{id: this.parent.id, ledger_id: this.parent.ledger_id, is_leaf: 0}];
         const create = [];
         for (const i of this.items) {
             create.push({
@@ -196,12 +196,13 @@ class updateReviseGclTree extends loadGclBaseTree {
 
                 if (bn.sjcl_qty < bn.org_sjcl_qty || bn.qtcl_qty < bn.org_qtcl_qty || bn.sgfh_qty < bn.org_sgfh_qty) {
                     result.errors.push({
+                        ledger_id: bn.ledger_id,
                         b_code: bn.b_code, name: bn.name, unit: bn.unit,
                         sgfh_qty: bn.sgfh_qty, sjcl_qty: bn.sjcl_qty, qtcl_qty: bn.qtcl_qty, qty: bn.quantity, type: 'less',
                     });
                 } else if (bn.sjcl_qty !== bn.org_sjcl_qty || bn.qtcl_qty !== bn.org_qtcl_qty || bn.sgfh_qty !== bn.org_sgfh_qty) {
                     result.update.push({
-                        id: bn.id, sgfh_qty: bn.sgfh_qty, sjcl_qty: bn.sjcl_qty, qtcl_qty: bn.qtcl_qty, qty: bn.quantity
+                        id: bn.id, sgfh_qty: bn.sgfh_qty, sjcl_qty: bn.sjcl_qty, qtcl_qty: bn.qtcl_qty, quantity: bn.quantity
                     })
                 }
             }
@@ -290,6 +291,7 @@ class gatherStageGclTree extends loadGclBaseTree {
             if (bn.change_detail && bn.change_detail.length > 0) {
                 for (const cd of bn.change_detail) {
                     result.errors.push({
+                        ledger_id: bn.ledger_id,
                         b_code: bn.b_code, name: bn.name, unit: bn.unit,
                         c_code: cd.c_code, qty: cd.qty, type: 'qc',
                     });

+ 106 - 0
app/lib/tender_info.js

@@ -0,0 +1,106 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+const auditConst = require('../const/audit');
+
+class TenderInfo {
+    constructor (ctx) {
+        if (!ctx.tender) throw '汇总标段信息错误';
+        this.ctx = ctx;
+        this.tender = this.ctx.tender;
+    }
+
+    async _getValidStages(tenderId) {
+        const stages = await this.ctx.service.stage.db.select(this.ctx.service.stage.tableName, {
+            where: { tid: tenderId },
+            orders: [['order', 'desc']],
+        });
+        if (stages.length !== 0) {
+            const lastStage = stages[0];
+            if (lastStage.status === auditConst.stage.status.uncheck && lastStage.user_id !== this.ctx.session.sessionUser.accountId) {
+                stages.splice(0, 1);
+            }
+        }
+        return stages;
+    }
+
+    async _checkStage() {
+        if (this.stage) return;
+        this.stages = await this._getValidStages(this.tender.id);
+        this.stage = this.stages[0];
+        if (this.stage) await this.ctx.service.stage.doCheckStage(this.stage);
+    }
+
+    async _getStageBillsData () {
+        const billsData = await this.ctx.service.ledger.getData(this.tender.id);
+        if (this.stage) {
+            const curStage = this.stage.readOnly
+                ? await this.ctx.service.stageBills.getAuditorStageData(this.tender.id, this.stage.id, this.stage.curTimes, this.stage.curOrder)
+                : await this.ctx.service.stageBills.getLastestStageData(this.tender.id, this.stage.id);
+
+            const preStage = this.stage.order > 1 ? await this.ctx.service.stageBillsFinal.getFinalData(this.tender, this.stage.order - 1) : [];
+            this.ctx.helper.assignRelaData(billsData, [
+                { data: curStage, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: '', relaId: 'lid' },
+                { data: preStage, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: 'pre_', relaId: 'lid' },
+            ]);
+        }
+        return billsData;
+    }
+
+    _getGclChapter() {
+        const gclChapter = [];
+        for (const c of this.ctx.tender.info.chapter) {
+            const cc = { code: c.code, name: c.name, cType: 1 };
+            const filter = '^[\\D]*' + c.code.substr(0, c.code.length - 2) + '[0-9]{2}(-|$)';
+            cc.reg = new RegExp(filter);
+            gclChapter.push(cc);
+        }
+        return gclChapter;
+    }
+
+    _findGclChapter(chapters, data, field) {
+        for (const c of chapters) {
+            if (c.reg && c.reg.test(data[field])) {
+                return c;
+            }
+        }
+        return null;
+    }
+
+    async gatherChapter() {
+        await this._checkStage();
+        const billsData = await this._getStageBillsData();
+        const gclChapter = this._getGclChapter();
+        for (const b of billsData) {
+            if (!b.b_code || !b.is_leaf) continue;
+            const chapter = this._findGclChapter(gclChapter, b, 'b_code');
+            if (!chapter) continue;
+            chapter.total_price = this.ctx.helper.add(chapter.total_price, b.total_price);
+            chapter.contract_tp = this.ctx.helper.add(chapter.contract_tp, b.contract_tp);
+            chapter.qc_tp = this.ctx.helper.add(chapter.qc_tp, b.qc_tp);
+            chapter.pre_contract_tp = this.ctx.helper.add(chapter.pre_contract_tp, b.pre_contract_tp);
+            chapter.pre_qc_tp = this.ctx.helper.add(chapter.pre_qc_tp, b.pre_qc_tp);
+        }
+        for (const c of gclChapter) {
+            if (!c.total_price) c.total_price = 0;
+            if (!c.contract_tp) c.contract_tp = 0;
+            if (!c.qc_tp) c.qc_tp = 0;
+            if (!c.pre_contract_tp) c.pre_contract_tp = 0;
+            if (!c.pre_qc_tp) c.pre_qc_tp = 0;
+            c.end_contract_tp = this.ctx.helper.add(c.pre_contract_tp, c.contract_tp);
+            c.end_qc_tp = this.ctx.helper.add(c.pre_qc_tp, c.qc_tp);
+            c.end_gather_tp = this.ctx.helper.add(c.end_qc_tp, c.end_contract_tp);
+            delete c.reg;
+        }
+        return gclChapter;
+    }
+}
+
+module.exports = TenderInfo;

+ 39 - 54
app/public/js/revise.js

@@ -93,6 +93,17 @@ $(document).ready(() => {
             if (posSpread) posSpread.refresh();
         },
     });
+    const sumLoadMiss = $.sumLoadMiss({
+        tabSelector: '#sum-load-miss-tab',
+        selector: '#sum-load-miss',
+        relaSpread: billsSpread,
+        storeKey: 'revise-slm-' + window.location.pathname.split('/')[2] + '-' + window.location.pathname.split('/')[4],
+        id: 'revise-slm',
+        afterShow: function () {
+            billsSpread.refresh();
+            if (posSpread) posSpread.refresh();
+        },
+    });
 
     // 初始化 节点树结构
     const treeSetting = {
@@ -1264,6 +1275,12 @@ $(document).ready(() => {
                 const refreshNode = billsTree.loadPostData(result);
                 billsTreeSpreadObj.refreshTree(billsSheet, refreshNode);
                 billsTreeSpreadObj.refreshOperationValid(billsSheet);
+                if (result.sumLoadHis.errors.length > 0) {
+                    sumLoadMiss.loadMissData(result.sumLoadHis.errors);
+                    sumLoadMiss.show();
+                } else {
+                    sumLoadMiss.clearMissData();
+                }
             }
         });
         billsContextMenuOptions.items.importGclBills2Xmj = {
@@ -2305,30 +2322,15 @@ $(document).ready(() => {
         select: '#revise-right-spr',
         callback: function () {
             billsSpread.refresh();
-            if (posSpread) {
-                posSpread.refresh();
-            }
-            if (stdXmj) {
-                stdXmj.spread.refresh();
-            }
-            if (stdGcl) {
-                stdGcl.spread.refresh();
-            }
-            if (dealBills) {
-                dealBills.spread.refresh();
-            }
-            if (bgBills) {
-                bgBills.spread.refresh();
-            }
-            if (searchLedger) {
-                searchLedger.spread.refresh();
-            }
-            if (errorList) {
-                errorList.spread.refresh();
-            }
-            if (checkList) {
-                checkList.spread.refresh();
-            }
+            if (posSpread) posSpread.refresh();
+            if (stdXmj) stdXmj.spread.refresh();
+            if (stdGcl) stdGcl.spread.refresh();
+            if (dealBills) dealBills.spread.refresh();
+            if (bgBills) bgBills.spread.refresh();
+            if (searchLedger) searchLedger.spread.refresh();
+            if (errorList) errorList.spread.refresh();
+            if (checkList) checkList.spread.refresh();
+            if (sumLoadMiss) sumLoadMiss.spread.refresh();
         }
     });
     $.subMenu({
@@ -2346,30 +2348,15 @@ $(document).ready(() => {
             }
             autoFlashHeight();
             billsSpread.refresh();
-            if (posSpread) {
-                posSpread.refresh();
-            }
-            if (stdXmj) {
-                stdXmj.spread.refresh();
-            }
-            if (stdGcl) {
-                stdGcl.spread.refresh();
-            }
-            if (dealBills) {
-                dealBills.spread.refresh();
-            }
-            if (bgBills) {
-                bgBills.spread.refresh();
-            }
-            if (searchLedger) {
-                searchLedger.spread.refresh();
-            }
-            if (errorList) {
-                errorList.spread.refresh();
-            }
-            if (checkList) {
-                checkList.spread.refresh();
-            }
+            if (posSpread) posSpread.refresh();
+            if (stdXmj) stdXmj.spread.refresh();
+            if (stdGcl) stdGcl.spread.refresh();
+            if (dealBills) dealBills.spread.refresh();
+            if (bgBills) bgBills.spread.refresh();
+            if (searchLedger) searchLedger.spread.refresh();
+            if (errorList) errorList.spread.refresh();
+            if (checkList) checkList.spread.refresh();
+            if (sumLoadMiss) sumLoadMiss.spread.refresh();
         }
     });
 
@@ -2377,9 +2364,7 @@ $(document).ready(() => {
     $('#xd-content').addClass('active');
     showSideTools(true);
     billsSpread.refresh();
-    if (posSpread) {
-        posSpread.refresh();
-    }
+    if (posSpread) posSpread.refresh();
 
     const stdLibCellDoubleClick = function (e, info) {
         const stdSheet = info.sheet;
@@ -2552,6 +2537,8 @@ $(document).ready(() => {
                 errorList.spread.refresh();
             } else if (tab.attr('content') === '#check-list') {
                 checkList.spread.refresh();
+            } else if (tab.attr('content') === '#sum-load-miss') {
+                sumLoadMiss.spread.refresh();
             }
         }
         else {// 收起工具栏
@@ -2560,9 +2547,7 @@ $(document).ready(() => {
             showSideTools(tab.hasClass('active'));
         }
         billsSpread.refresh();
-        if (posSpread) {
-            posSpread.refresh();
-        }
+        if (posSpread) posSpread.refresh();
     });
 
     if (!readOnly) {

+ 1 - 1
app/public/js/shares/cs_tools.js

@@ -944,7 +944,7 @@ const showSelectTab = function(select, spread, afterShow) {
                     {
                         title: '类型', field: 'type', width: 100, getValue: function (x) {
                             switch (x.type) {
-                                case 'less': return '数量变';
+                                case 'less': return '数量变';
                                 case 'miss': return '找不到清单';
                                 case 'qc': return '变更';
                                 case 'miss-qc': return '变更(找不到清单)';

+ 1 - 1
app/public/js/shares/export_excel.js

@@ -35,7 +35,7 @@ const SpreadExcelObj = (function() {
     const exportSimpleXlsxSheet = function (setting, data, file) {
         const div = _createHideSpread();
 
-        const spread = SpreadJsObj.createNewSpread(div);
+        const spread = SpreadJsObj.createNewSpread(div, true);
         const sheet = spread.getActiveSheet();
 
         SpreadJsObj.beginMassOperation(sheet);

+ 2 - 1
app/public/js/spreadjs_rela/spreadjs_zh.js

@@ -74,8 +74,9 @@ const SpreadJsObj = {
      * @param obj 用于创建spreadjs的Dom元素
      * @returns {GC.Spread.Sheets.Workbook}
      */
-    createNewSpread: function (obj) {
+    createNewSpread: function (obj, hidden) {
         const spread = new spreadNS.Workbook(obj, {sheetCount: 1});
+        if (hidden) return spread;
         spread.options.tabStripVisible = false;
         spread.options.scrollbarMaxAlign = true;
         spread.options.cutCopyIndicatorVisible = false;

+ 2 - 2
app/service/ledger.js

@@ -778,8 +778,8 @@ module.exports = app => {
             try {
                 this._cacheMaxLid(this.ctx.tender.id, loadTree.keyNodeId);
                 await this.ctx.service.sumLoadHistory.saveLedgerHistory(this.ctx.tender.id, lid, tenders);
-                await conn.update(this.tableName, result.update);
-                await conn.insert(this.tableName, result.create);
+                if (result.update.length > 0) await conn.updateRows(this.tableName, result.update);
+                if (result.create.length > 0) await conn.insert(this.tableName, result.create);
                 await conn.commit();
                 return result;
             } catch (err) {

+ 10 - 0
app/service/stage.js

@@ -453,6 +453,7 @@ module.exports = app => {
             const param = tenderInfo.deal_param;
             for (const cb of calcBase) {
                 const sum = await this.ctx.service.stageBills.getSumTotalPrice(stage);
+                const bg = await this.ctx.service.stageChange.getQualityTotalPrice(stage.id);
                 switch (cb.code) {
                     case 'htj':
                         cb.value = param.contractPrice;
@@ -482,6 +483,15 @@ module.exports = app => {
                         const sumGcl = await this.ctx.service.stageBills.getSumTotalPriceGcl(stage, '^[^0-9]*1[0-9]{2}(-|$)');
                         cb.value = this.ctx.helper.add(sumGcl.contract_tp, sumGcl.qc_tp);
                         break;
+                    case 'ybbqbg':
+                        cb.value = bg.common;
+                        break;
+                    case 'jdbqbg':
+                        cb.value = bg.more;
+                        break;
+                    case 'zdbqbg':
+                        cb.value = bg.great;
+                        break;
                     default:
                         cb.value = 0;
                 }

+ 27 - 0
app/service/stage_change.js

@@ -11,6 +11,7 @@
 const defaultPid = -1; // 非pid
 const audit = require('../const/audit');
 const timesLen = audit.stage.timesLen;
+const changeConst = require('../const/change');
 
 module.exports = app => {
 
@@ -393,6 +394,32 @@ module.exports = app => {
             const data = await this.getAllDataByCondition({ where: { tid, sid } });
             return this.ctx.helper.filterLastestData(data, ['lid', 'pid', 'cid', 'cbid']);
         }
+
+        async getQualityTotalPrice(sid) {
+            const helper = this.ctx.helper;
+            const sql = 'SELECT sc.*, c.quality FROM ' + this.tableName + ' sc' +
+                '  LEFT JOIN ' + this.ctx.service.change.tableName + ' c ON sc.cid = c.cid' +
+                '  WHERE sid = ?';
+            const data = await this.db.query(sql, [sid]);
+            const bqData = [];
+            for (const d of data) {
+                if (!d.qty) continue;
+                let bd = bqData.find(x => { return x.lid === d.lid && x.quality === d.quality; });
+                if (!bd) {
+                    const bills = await this.ctx.service.ledger.getDataById(d.lid);
+                    if (!bills) continue;
+                    bd = { lid: d.lid, quality: d.quality, unit_price: bills.unit_price };
+                    bqData.push(bd);
+                }
+                const tp = this.ctx.helper.mul(d.qty, bd.unit_price, this.ctx.tender.info.decimal.tp);
+                bd.tp = this.ctx.helper.add(bd.tp, tp);
+            }
+            const result = {};
+            result.common = helper.sum(helper._.map(bqData.filter(x => {return x.quality === changeConst.quality.common.value; }), 'tp'));
+            result.more = helper.sum(helper._.map(bqData.filter(x => {return x.quality === changeConst.quality.more.value; }), 'tp'));
+            result.great = helper.sum(helper._.map(bqData.filter(x => {return x.quality === changeConst.quality.great.value; }), 'tp'));
+            return result;
+        }
     }
 
     return StageChange;

+ 1 - 1
app/service/sum_load_history.js

@@ -67,7 +67,7 @@ module.exports = app => {
                 tenders: JSON.stringify(tenders), errors: errors ? JSON.stringify(errors) : '',
             };
             await this.db.insert(this.tableName, data);
-            data.tenders = tender;
+            data.tenders = tenders;
             data.errors = errors;
             return data;
         }

+ 5 - 0
app/view/revise/info.ejs

@@ -183,6 +183,8 @@
                     </div>
                     <div id="check-list" class="tab-pane">
                     </div>
+                    <div id="sum-load-miss" class="tab-pane tab-select-show">
+                    </div>
                 </div>
             </div>
         </div>
@@ -214,6 +216,9 @@
                 <li class="nav-item">
                     <a class="nav-link" content="#check-list" id="check-list-tab" href="javascript: void(0);" style="display: none;">数据检查</a>
                 </li>
+                <li class="nav-item">
+                    <a class="nav-link" content="#sum-load-miss" id="sum-load-miss-tab" href="javascript: void(0);" style="display: none;">导入信息</a>
+                </li>
             </ul>
         </div>
     </div>

+ 4 - 4
app/view/tender/detail.ejs

@@ -41,24 +41,24 @@
                                                 <a href="#bd-set-5" data-toggle="modal" data-target="#bd-set-5" class="dropdown-item" >显示设置</a>
                                                 <a href="#bd-set-6" data-toggle="modal" data-target="#bd-set-6" class="dropdown-item" >章节设置</a>
                                                 <a href="#bd-set-7" data-toggle="modal" data-target="#bd-set-7" class="dropdown-item" >付款账号</a>
+                                                <a class="dropdown-item" href="javascript: void(0);" id="copyBtn">拷贝设置</a>
                                             </div>
                                         </div>
+                                        <% if (ctx.session.sessionUser.is_admin) { %>
                                         <div class="dropdown mt-1">
                                             <a class="btn btn-sm btn-outline-light dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                                 管理员
                                             </a>
                                             <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
-                                                <% if (ctx.session.sessionProject.page_show !== null && parseInt(ctx.session.sessionProject.page_show.xxjd) === 1 && ctx.session.sessionUser.is_admin) { %>
+                                                <% if (ctx.session.sessionProject.page_show !== null && parseInt(ctx.session.sessionProject.page_show.xxjd) === 1) { %>
                                                 <a href="#xxjd-set" data-toggle="modal" data-target="#xxjd-set" class="dropdown-item">投资进度</a>
                                                 <% } %>
-                                                <a class="dropdown-item" href="javascript: void(0);" id="copyBtn">拷贝设置</a>
-                                                    <% if (ctx.session.sessionUser.is_admin) { %>
                                                 <a href="/tender/<%- tender.id %>/shenpi" class="dropdown-item">审批流程</a>
                                                 <a href="#bd-set-9" data-toggle="modal" data-target="#bd-set-9" class="dropdown-item">游客账号 <span id="tourist-num" <% if (tourists.length !== 0) { %>class="badge badge-secondary"<% } %>><% if (tourists.length !== 0) { %><%- tourists.length %><% } %></span></a>
                                                 <a href="#bd-set-10" data-toggle="modal" data-target="#bd-set-10" class="dropdown-item">上报限制</a>
-                                                <% } %>
                                             </div>
                                         </div>
+                                        <% } %>
                                     </h5>
                                 </div>
                             </div>