Browse Source

总额计量

MaiXinRong 5 years ago
parent
commit
7ee5964479

+ 7 - 4
app/const/spread.js

@@ -112,8 +112,8 @@ const stageTz = {
             {title: '台账|数量', colSpan: '2|1', rowSpan: '1|1', field: 'quantity', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '本期合同计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
-            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
-            {title: '本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number',},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number'},
+            {title: '本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'qc_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'gather_tp', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
@@ -133,6 +133,7 @@ const stageTz = {
             {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@', readOnly: true},
             //{title: '累计完成率(%)', colSpan: '1', rowSpan: '2', field: 'percent', hAlign: 0, width: 100, readOnly: true, type: 'Number'},
             {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
+            {title: '总额计量', colSpan: '1', rowSpan: '2', field: 'is_tp', hAlign: 1, width: 60, cellType: 'checkbox'},
         ],
         emptyRows: 0,
         headRows: 2,
@@ -175,7 +176,7 @@ const stageCl = {
             {title: '台账|数量', colSpan: '2|1', rowSpan: '1|1', field: 'quantity', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '本期合同计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
-            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number'},
             {title: '本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number',},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'qc_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
@@ -196,6 +197,7 @@ const stageCl = {
             {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@', readOnly: true},
             //{title: '累计完成率(%)', colSpan: '1', rowSpan: '2', field: 'percent', hAlign: 0, width: 100, readOnly: true, type: 'Number'},
             {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
+            {title: '总额计量', colSpan: '1', rowSpan: '2', field: 'is_tp', hAlign: 1, width: 60, cellType: 'checkbox'},
         ],
         emptyRows: 0,
         headRows: 2,
@@ -242,7 +244,7 @@ const stageNoCl = {
             {title: '台账|数量', colSpan: '2|1', rowSpan: '1|1', field: 'quantity', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
             {title: '本期合同计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
-            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number'},
             {title: '本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number',},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'qc_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'gather_qty', hAlign: 2, width: 60, readOnly: true, type: 'Number'},
@@ -262,6 +264,7 @@ const stageNoCl = {
             {title: '本期批注', colSpan: '1', rowSpan: '2', field: 'postil', hAlign: 0, width: 100, formatter: '@', cellType: 'autoTip'},
             {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@', readOnly: true},
             {title: '备注', colSpan: '1', rowSpan: '2', field: 'memo', hAlign: 0, width: 100, formatter: '@', cellType: 'ellipsisAutoTip'},
+            {title: '总额计量', colSpan: '1', rowSpan: '2', field: 'is_tp', hAlign: 1, width: 60, cellType: 'checkbox'},
         ],
         emptyRows: 0,
         headRows: 2,

+ 2 - 0
app/controller/stage_controller.js

@@ -347,6 +347,8 @@ module.exports = app => {
                     if (data.bills.stage) {
                         responseData.data.curStageData = await ctx.service.stageBills.updateStageData(data.bills.stage);
                     }
+                    if (data.bills.calcType) {
+                        responseData.data = await ctx.service.stageBills.updateStageBillsCalcType(data.bills.calcType);                    }
                 }
                 await ctx.service.stage.updateCheckCalcFlag(ctx.stage.id, true);
                 ctx.body = responseData;

+ 7 - 0
app/lib/pay_calc.js

@@ -163,6 +163,9 @@ class PayCalculate {
         this.yf = pays.find(function (p) {
             return p.ptype === payType.yf;
         });
+        this.sf = pays.find(function (p) {
+            return p.ptype === payType.sf;
+        });
         if (!this.yf) return false;
         await this._getAddCalcRela();
         this.yf.tp = 0;
@@ -212,6 +215,10 @@ class PayCalculate {
             p.end_tp = this.ctx.helper.round(this.ctx.helper.add(p.tp, p.pre_tp), this.decimal);
         }
         this.yf.end_tp = this.ctx.helper.add(this.yf.tp, this.yf.pre_tp);
+        if (this.sf.tp === null) {
+            this.sf.tp = this.yf.tp;
+        }
+        this.sf.end_tp = this.ctx.helper.add(this.sf.tp, this.sf.pre_tp);
     }
 
     async calculateAll(pays) {

+ 1 - 1
app/public/js/global.js

@@ -275,7 +275,7 @@ function getQueryVariable(variable) {
 
 const zeroRange = 0.00000001;
 function checkZero(value) {
-    return _.isNumber(value) && Math.abs(value) < zeroRange;
+    return value === null || value === undefined || (_.isNumber(value) && Math.abs(value) < zeroRange);
 }
 function checkFieldChange(o, n) {
     return o == n || ((!o || o === '') && (n === ''));

+ 68 - 0
app/public/js/msg_box.js

@@ -0,0 +1,68 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+(function($){
+    // setting = {
+    //     id: 'calc-type',
+    //     title: '提示',
+    //     message: '切换计量模式,已计量数据会被清空。',
+    //     ok: {
+    //         caption: '确定',
+    //         //callback
+    //     },
+    //     cancel: {
+    //         caption: '取消',
+    //         //callback
+    //     }
+    // };
+    $.msgBox = function(setting) {
+        const html = [];
+        html.push('<div class="modal fade" data-backdrop="static" id="' + setting.id + '">');
+        html.push('<div class="modal-dialog " role="document" >');
+        html.push('<div class="modal-content">');
+        html.push('<div class="modal-header">', '<h5 class="modal-title">', setting.title, '</h5>','</div>');
+        html.push('<div class="modal-body">', '<h5>', setting.message, '</h5>', '</div>');
+        html.push('<div class="modal-footer">');
+        if (setting.cancel) {
+            html.push('<button type="button" class="btn btn-secondary btn-sm" id="' + setting.id + '-cancel">', setting.cancel.caption, '</button>');
+        }
+        html.push('<button type="button" class="btn btn-primary btn-sm" id="' + setting.id + '-ok">', setting.ok.caption, '</button>');
+        html.push('</div>');
+        html.push('</div>');
+        html.push('</div>');
+        html.push('</div>');
+        $('body').append(html.join(''));
+
+        const obj = $('#' + setting.id);
+        if (!obj) return;
+
+        const btnOk = $('#' + setting.id + '-ok'), btnCancel =  $('#' + setting.id + '-cancel');
+        if (btnOk) {
+            btnOk.on('click', function () {
+                if (setting.ok.callback) {
+                    setting.ok.callback();
+                }
+                obj.modal('hide');
+            });
+        }
+        if (btnCancel) {
+            btnCancel.on('click', function () {
+                if (setting.cancel.callback) {
+                    setting.cancel.callback();
+                }
+                obj.modal('hide');
+            });
+        }
+        obj.on('hidden.bs.modal', function () {
+            setTimeout(() => { obj.remove(); }, 1000);
+        });
+        obj.modal('show');
+    }
+})(jQuery);

+ 76 - 5
app/public/js/stage.js

@@ -32,6 +32,7 @@ function customColDisplay () {
         { title: '本期批注', fields: ['postil'], visible: true },
         { title: '图册号', fields: ['drawing_code'], visible: true },
         { title: '备注', fields: ['memo'], visible: true },
+        { title: '总额计量', fields: ['is_tp'], visible: true},
     ];
     if (checkTzMeasureType()) {
         defaultSetting.splice(0, 1);
@@ -135,7 +136,7 @@ $(document).ready(() => {
         stageId: 'id',
     };
     // 台账树结构计算相关设置
-    stageTreeSetting.updateFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil'];
+    stageTreeSetting.updateFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil', 'used'];
     stageTreeSetting.calcFields = ['deal_tp', 'total_price', 'contract_tp', 'qc_tp', 'gather_tp',
         'pre_contract_tp', 'pre_qc_tp', 'pre_gather_tp', 'end_contract_tp', 'end_qc_tp', 'end_gather_tp'];
     stageTreeSetting.calcFun = function (node) {
@@ -590,7 +591,7 @@ $(document).ready(() => {
             }
         },
         selectionChanged: function (e, info) {
-            if (!info.oldSelections[0] || info.newSelections[0].row !== info.oldSelections[0].row) {
+            if (!info.oldSelections || !info.oldSelections[0] || info.newSelections[0].row !== info.oldSelections[0].row) {
                 stagePosSpreadObj.loadCurPosData();
                 SpreadJsObj.resetTopAndSelect(spSpread.getActiveSheet());
                 if (posSearch) {
@@ -830,12 +831,84 @@ $(document).ready(() => {
         topRowChanged(e, info) {
             SpreadJsObj.saveTopAndSelect(info.sheet, ckBillsSpread);
         },
+        editStarting(e, info) {
+            if (!info.sheet.zh_setting || !info.sheet.zh_tree) return;
+            const col = info.sheet.zh_setting.cols[info.col];
+            const node = info.sheet.zh_tree.nodes[info.row];
+            switch (col.field) {
+                case 'contract_qty':
+                case 'qc_qty':
+                    info.cancel = node.is_tp;
+                    break;
+                case 'contract_tp':
+                    info.cancel = !node.is_tp;
+                    break;
+                case 'is_tp':
+                    const posRange = stagePos.getLedgerPos(node.id);
+                    info.cancel = node.pre_used || node.unit !== '总额' || (posRange && posRange.length > 0);
+                    break;
+            }
+        },
+        buttonClicked: function (e, info) {
+            if (info.sheet.zh_setting) {
+                const node = SpreadJsObj.getSelectObject(info.sheet);
+                const col = info.sheet.zh_setting.cols[info.col];
+                const posRange = stagePos.getLedgerPos(node.id);
+                if (node.pre_used || node.unit !== '总额' || (posRange && posRange.length > 0) /*|| !checkZero(node.qc_qty)*/) {
+                    SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                    return;
+                }
+
+                const postIsTp = function () {
+                    const data = { calcType: {id: node.id} };
+                    data.calcType.is_tp = info.sheet.getValue(info.row, info.col) || false;
+                    // 更新至服务器
+                    postData(window.location.pathname + '/update', {bills: data}, function (result) {
+                        const nodes = stageTree.loadPostStageData(result);
+                        stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
+                        if (detail) {
+                            detail.loadStageLedgerUpdateData(result);
+                        } else {
+                            stageIm.loadUpdateLedgerData(result);
+                        }
+                    });
+                };
+
+                if (col.field === 'is_tp') {
+                    if (info.sheet.isEditing) {
+                        info.sheet.endEdit(true);
+                    }
+
+                    if (!checkZero(node.contract_qty) || !checkZero(node.contract_tp)) {
+                        $.msgBox({
+                            id: 'calc-type',
+                            title: '提示',
+                            message: '切换计量模式,已计量数据会被清空。',
+                            ok: {
+                                caption: '确定',
+                                callback: postIsTp,
+                            },
+                            cancel: {
+                                caption: '取消',
+                                callback: function () {
+                                    SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                                }
+                            }
+                        });
+                    } else {
+                        postIsTp();
+                    }
+                }
+            }
+        },
     };
     slSpread.bind(spreadNS.Events.EditEnded, stageTreeSpreadObj.editEnded);
     slSpread.bind(spreadNS.Events.SelectionChanged, stageTreeSpreadObj.selectionChanged);
     slSpread.bind(spreadNS.Events.ClipboardPasting, stageTreeSpreadObj.clipboardPasting);
     slSpread.bind(spreadNS.Events.ClipboardPasted, stageTreeSpreadObj.clipboardPasted);
     slSpread.bind(spreadNS.Events.TopRowChanged, stageTreeSpreadObj.topRowChanged);
+    slSpread.bind(spreadNS.Events.EditStarting, stageTreeSpreadObj.editStarting);
+    slSpread.bind(spreadNS.Events.ButtonClicked, stageTreeSpreadObj.buttonClicked);
     SpreadJsObj.addDeleteBind(slSpread, stageTreeSpreadObj.deletePress);
     if (!readOnly) {
         $('#bills-expr').bind('change mouseleave', function () {
@@ -1221,9 +1294,7 @@ $(document).ready(() => {
     });
 
     // 加载计量单元数据 - 暂时统一加载,如有需要,切换成动态加载并缓存
-    console.time('loadPosFromServer');
     postData(window.location.pathname + '/load', null, function (result) {
-        console.timeEnd('loadPosFromServer');
         // 加载树结构
         stageTree.loadDatas(result.ledgerData);
         // stageTree.loadCurStageData(curStageData);
@@ -1962,7 +2033,7 @@ $(document).ready(() => {
                         $('#type-title-qc').text('本期变更计量金额');
                     } else {
                         const jlCol = self.spreadSetting.cols.find(function (x) {return x.field === 'jl'});
-                        jlCol.title = '本期计量金额';
+                        jlCol.title = '本期计量数量';
                         SpreadJsObj.reLoadSheetHeader(self.sheet);
                         $('#type-title-contract').text('本期合同计量数量');
                         $('#type-title-qc').text('本期变更计量数量');

+ 2 - 0
app/service/pos.js

@@ -150,7 +150,9 @@ module.exports = app => {
 
                 const transaction = await this.db.beginTransaction();
                 try {
+                    console.log(data);
                     transaction.update(this.tableName, data);
+                    console.log(updateBills);
                     transaction.update(this.ctx.service.ledger.tableName, updateBills);
                     await transaction.commit();
                     updateBills.ledger_id = bills.ledger_id;

+ 25 - 0
app/service/stage_bills.js

@@ -328,6 +328,31 @@ module.exports = app => {
             }
         }
 
+        async updateStageBillsCalcType(data) {
+            const stageBills = await this.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, data.id);
+            const updateData = {contract_qty: null, contract_tp: null};
+
+            const transaction = await this.db.beginTransaction();
+            try {
+                await transaction.update(this.ctx.service.ledger.tableName, data);
+                if (!stageBills || stageBills.times !== this.ctx.stage.curTimes || stageBills.order !== this.ctx.stage.curOrder) {
+                    await this._insertStageBillsData(transaction, updateData, stageBills, ledgerBills);
+                } else {
+                    updateData.id = stageBills.id;
+                    await transaction.update(this.tableName, updateData);
+                }
+                await transaction.update(this.tableName, updateData);
+                await transaction.commit();
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+
+            const bills = await this.ctx.service.ledger.getDataById(data.id);
+            const curStageData = await this.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, [data.id]);
+            return {bills: [bills], curStageData: curStageData};
+        }
+
         async getSumTotalPrice(stage) {
             const sql = 'SELECT Sum(`contract_tp`) As `contract_tp`, Sum(`qc_tp`) As `qc_tp` FROM ' + this.tableName + ' As Bills ' +
                 '  INNER JOIN ( ' +

+ 1 - 1
app/view/stage/index.ejs

@@ -524,7 +524,7 @@
     const whiteList = JSON.parse('<%- JSON.stringify(whiteList) %>');
     let attData = JSON.parse('<%- JSON.stringify(attData) %>');
     const userID = '<%- ctx.session.sessionUser.accountId %>';
-    const ckColSetting = 'stage-col-visible-1.0.2-<%- tender.id %>';
+    const ckColSetting = 'stage-col-visible-1.0.3-<%- tender.id %>';
 </script>
 <% if (ctx.stage.status === auditConst.status.uncheck && ctx.session.sessionUser.accountId === ctx.stage.user_id) {%>
 <script>

+ 1 - 0
config/web.js

@@ -216,6 +216,7 @@ const JsFiles = {
                 mergeFiles: [
                     "/public/js/sub_menu.js",
                     "/public/js/div_resizer.js",
+                    "/public/js/msg_box.js",
                     "/public/js/spreadjs_rela/spreadjs_zh.js",
                     "/public/js/zh_calc.js",
                     "/public/js/path_tree.js",