Pārlūkot izejas kodu

1. 起扣金额,扣款限额问题
2. 本期完成计量,第一达起扣金额,计算问题
3. 计提期限,累计完成合同计量、累计完成计量问题

MaiXinRong 5 gadi atpakaļ
vecāks
revīzija
31d468c7ef

+ 5 - 6
app/lib/pay_calc.js

@@ -42,10 +42,10 @@ class PayCalculate {
         }
     }
 
-    calculateTpExpr(pay, first, addRela) {
+    calculateTpExpr(pay, addRela) {
         let formula = pay.expr;
         for (const b of this.bases) {
-            if ((b.code === 'bqwc') && (first && pay.sprice)) {
+            if ((b.code === 'bqwc') && (!pay.pre_used && pay.sprice)) {
                 formula = formula.replace(b.reg, this.ctx.helper.sub(addRela.gather_tp, pay.sprice));
             } else {
                 formula = formula.replace(b.reg, b.value);
@@ -114,7 +114,7 @@ class PayCalculate {
      */
     async getAddCalcRela() {
         // todo 获取截止上期数据
-        const pre = null;
+        const pre = this.stage.order > 1 ? await this.ctx.service.stageBillsFinal.getSumTotalPrice(this.stage.tid, this.stage.order - 1) : null;
         const cur = await this.ctx.service.stageBills.getSumTotalPrice(this.stage);
         const add = {};
         if (pre) {
@@ -151,18 +151,17 @@ class PayCalculate {
      */
     async calculate(pays) {
         await this.getCalcBase();
-        const addRela = await this.getAddCalcRela();
         const yfPay = pays.find(function (p) {
             return p.ptype === payType.yf;
         });
+        const addRela = await this.getAddCalcRela();
         if (!yfPay) return false;
         yfPay.tp = 0;
         for (const p of pays) {
             if (p.ptype === payType.normal || p.ptype === payType.wc) {
                 if (!p.pause && (!p.sprice || addRela.gather_tp > p.sprice)) {
                     if (p.expr && p.expr !== '') {
-                        const first = !(p.pre_tp && !this.ctx.helper.checkZero(p.pre_tp));
-                        const value = this.ctx.helper.round(this.calculateTpExpr(p, first, addRela), this.decimal);
+                        const value = this.ctx.helper.round(this.calculateTpExpr(p, addRela), this.decimal);
                         if (p.rprice) {
                             if (this.checkDeadline(p, addRela)) {
                                 p.tp = this.ctx.helper.sub(p.rprice, p.pre_tp);

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 56 - 0
app/public/js/math.min.js


+ 141 - 18
app/public/js/stage_pay.js

@@ -47,9 +47,62 @@ function makeAttTable(payNode) {
 }
 
 $(document).ready(() => {
+    toastr.options = {
+        "closeButton": false,
+        "debug": false,
+        "newestOnTop": false,
+        "progressBar": false,
+        "positionClass": "toast-top-center",
+        "preventDuplicates": false,
+        "onclick": null,
+        "showDuration": "300",
+        "hideDuration": "1000",
+        "timeOut": "5000",
+        "extendedTimeOut": "1000",
+        "showEasing": "swing",
+        "hideEasing": "linear",
+        "showMethod": "fadeIn",
+        "hideMethod": "fadeOut"
+    };
     autoFlashHeight();
+    const payCalc = (function (b) {
+        class PayCalc {
+            constructor (bases) {
+                this.percentReg = /[0-9]+%/g;
+                this.bases = bases;
+                this.bases.sort(function (a, b) {
+                    return a.sort - b.sort;
+                });
+                for (const b of this.bases) {
+                    b.reg = new RegExp(b.code, 'igm');
+                }
+            }
+
+            calculateExpr(expr) {
+                let formula = expr;
+                for (const b of this.bases) {
+                    formula = formula.replace(b.reg, b.value);
+                }
+                const percent = formula.match(this.percentReg);
+                if (percent) {
+                    for (const p of percent) {
+                        const v = math.eval(p.replace('%', '/100'));
+                        formula = formula.replace(p, v);
+                    }
+                }
+                try {
+                    const value = math.eval(formula);
+                    return value;
+                } catch(err) {
+                    return 0;
+                }
+            }
+        }
 
+        return new PayCalc(b);
+    })(calcBase);
     const paySpread = SpreadJsObj.createNewSpread($('#pay-spread')[0]);
+    const wcPay = dealPay.find(function (x) {return x.ptype === 4});
 
     $.subMenu({
         menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
@@ -169,7 +222,11 @@ $(document).ready(() => {
                 }
             },
             rprice: function (data) {
-                return payCol.readOnly.sprice(data); // 同起扣金额
+                if (payCol.readOnly.isOld(data)) { // 上报或审批后,仅原报,在未开始计量前,可修改
+                    return payCol.readOnly.isYF(data) || !payCol.readOnly.isYB(data);
+                } else { // 新增时,新增人可修改
+                    return payCol.readOnly.isSpecial(data);
+                }
             },
             pause: function (data) {
                 if (payCol.readOnly.isOld(data)) { // 上报或审批后,仅原报,可修改
@@ -185,19 +242,57 @@ $(document).ready(() => {
     SpreadJsObj.loadSheetData(paySpread.getActiveSheet(), SpreadJsObj.DataType.Data, dealPay);
 
     const paySpreadObj = {
-        _checkExpr: function (text, data, priceField, exprField) {
+        _checkSExpr: function (payNode, text, data) {
+            if (!payNode) return [false, '数据错误'];
+            const num = text ? _.toNumber(text) : null;
+            const expr = text ? (num ? null : text) : null;
+            if (payCol.readOnly.isStarted(payNode)) {
+                return [false, '已经开始计量,请勿修改起扣金额'];
+            } else {
+                if (stage.order > 1) {
+                    const value = expr ? payCalc.calculateExpr(expr) : num;
+                    if (wcPay.pre_tp && value < wcPay.pre_tp)
+                        return [false, '已进行到第' + stage.order + '期,起扣金额请勿少于本期完成截止上期计量金额' + wcPay.pre_tp];
+                    data.sprice = num;
+                    data.sexpr = expr;
+                    return [true, ''];
+                } else {
+                    data.sprice = num;
+                    data.sexpr = expr;
+                    return [true, ''];
+                }
+            }
+        },
+        _checkRExpr: function (payNode, text, data) {
+            if (!payNode) return [false, '数据错误'];
+            const num = text ? _.toNumber(text) : null;
+            const expr = text ? (num ? null : text) : null;
+            if (payCol.readOnly.isStarted(payNode)) {
+                if (payNode.pre_finish) return [false, '已达扣款限额,请勿修改'];
+                const value = expr ? payCalc.calculateExpr(expr) : num;
+                if (payNode.pre_tp && value < payNode.pre_tp) return [false, '截止上期已计量' + payNode.pre_tp + ',扣款限额请勿少于改值'];
+                data.rprice = num;
+                data.rexpr = expr;
+                return [true, ''];
+            } else {
+                data.rprice = num;
+                data.rexpr = expr;
+                return [true, ''];
+            }
+        },
+        _checkExpr: function (text, data) {
             if (text) {
                 const num = _.toNumber(text);
                 if (num) {
-                    data[priceField] = num;
-                    data[exprField] = null;
+                    data.tp = num;
+                    data.expr = null;
                 } else {
-                    data[exprField] = text.replace('=', '');
-                    data[priceField] = null;
+                    data.expr = text.replace('=', '');
+                    data.tp = null;
                 }
             } else {
-                data[priceField] = null;
-                data[exprField] = null;
+                data.tp = null;
+                data.expr = null;
             }
         },
         refreshActn: function () {
@@ -340,7 +435,7 @@ $(document).ready(() => {
                 // 获取更新数据
                 if (col.field === 'tp') {
                     data.updateData.pid = select.pid;
-                    paySpreadObj._checkExpr(validText, data.updateData, 'tp', 'expr');
+                    paySpreadObj._checkExpr(validText, data.updateData);
                 } else if (col.field === 'name') {
                     data.updateData.pid = select.pid;
                     data.updateData.name = validText;
@@ -348,9 +443,19 @@ $(document).ready(() => {
                     data.updateData.id = select.pid;
                     if (validText) {
                         if (col.field === 'sprice') {
-                            paySpreadObj._checkExpr(validText, data.updateData, 'sprice', 'sexpr');
+                            const [valid, msg] = paySpreadObj._checkSExpr(select, validText, data.updateData);
+                            if (!valid) {
+                                toastr.warning(msg);
+                                SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                                return;
+                            }
                         } else if (col.field === 'rprice') {
-                            paySpreadObj._checkExpr(validText, data.updateData, 'rprice', 'rexpr');
+                            const [valid, msg] = paySpreadObj._checkRExpr(select, validText, data.updateData);
+                            if (!valid) {
+                                toastr.warning(msg);
+                                SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                                return;
+                            }
                         } else {
                             data.updateData[col.field] = validText;
                         }
@@ -362,6 +467,8 @@ $(document).ready(() => {
                 postData(window.location.pathname + '/save', data, function (result) {
                     loadUpdateDealPays(result, col.field === 'name' ? ['name'] : null);
                     SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                }, function () {
+                    SpreadJsObj.reLoadRowData(info.sheet, info.row);
                 });
             }
         },
@@ -433,11 +540,17 @@ $(document).ready(() => {
                         } else {
                             updateData.id = node.pid;
                             if (col.field === 'sprice') {
-                                updateData.sprice = null;
-                                updateData.sexpr = null;
+                                const [valid, msg] = paySpreadObj._checkSExpr(node, null, updateData);
+                                if (!valid) {
+                                    toastr.warning(msg);
+                                    return;
+                                }
                             } else if (col.field === 'rprice') {
-                                updateData.rprice = null;
-                                updateData.rexpr = null;
+                                const [valid, msg] = paySpreadObj._checkRExpr(node, null, updateData);
+                                if (!valid) {
+                                    toastr.warning(msg);
+                                    return;
+                                }
                             } else {
                                 updateData[col.field] = null;
                             }
@@ -478,14 +591,24 @@ $(document).ready(() => {
                         const updateData = {};
                         if (col.field === 'tp') {
                             updateData.pid = node.pid;
-                            paySpreadObj._checkExpr(validText, updateData, 'tp', 'expr');
+                            paySpreadObj._checkExpr(validText, updateData);
                         } else {
                             updateData.id = node.pid;
                             if (validText) {
                                 if (col.field === 'sprice') {
-                                    paySpreadObj._checkExpr(validText, updateData, 'sprice', 'sexpr');
+                                    const [valid, msg] = paySpreadObj._checkSExpr(node, validText, updateData);
+                                    if (!valid) {
+                                        toastr.warning(msg);
+                                        SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                                        return;
+                                    }
                                 } else if (col.field === 'rprice') {
-                                    paySpreadObj._checkExpr(validText, updateData, 'rprice', 'rexpr');
+                                    const [valid, msg] = paySpreadObj._checkRExpr(node, validText, updateData);
+                                    if (!valid) {
+                                        toastr.warning(msg);
+                                        SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                                        return;
+                                    }
                                 } else {
                                     updateData[col.field] = validText;
                                 }

+ 30 - 0
app/service/stage_bills_final.js

@@ -145,6 +145,36 @@ module.exports = app => {
             }
             await transaction.delete(this.tableName, { tid: tender.id, sid: stage.id });
         }
+
+        async getSumTotalPrice(tenderId, stageOrder) {
+            const sql = 'SELECT Sum(`contract_tp`) As `contract_tp`, Sum(`qc_tp`) As `qc_tp` FROM ' + this.tableName +
+                '  WHERE sorder = ? and tid = ?';
+            const sqlParam = [stageOrder, tenderId];
+            const result = await this.db.queryOne(sql, sqlParam);
+            return result;
+        }
+
+        async getSumTotalPriceFilter(tenderId, stageOrder, operate, filter) {
+            const sql = 'SELECT Sum(`contract_tp`) As `contract_tp`, Sum(`qc_tp`) As `qc_tp`' +
+                '  FROM ' + this.tableName + ' As Bills ' +
+                '  LEFT JOIN ' + this.ctx.service.ledger.tableName + ' As Ledger ' +
+                '  ON Bills.lid = Ledger.id And Bills.sorder = ? And Bills.tid = ? And Ledger.b_code ' + operate + ' ?';
+            const sqlParam = [stageOrder, tenderId, filter];
+            const result = await this.db.queryOne(sql, sqlParam);
+            return result;
+        }
+
+        async getSumTotalPriceGcl(tenderId, stageOrder, regText) {
+            if (regText) {
+                return await this.getSumTotalPriceFilter(tenderId, stageOrder, 'REGEXP', regText);
+            } else {
+                return await this.getSumTotalPriceFilter(tenderId, stageOrder, '<>', this.db.escape(''));
+            }
+        }
+
+        async getSumTotalPriceNotGcl(tenderId, stageOrder) {
+            return await this.getSumTotalPriceFilter(tenderId, stageOrder, '=', this.db.escape(''));
+        }
     }
 
     return StageBillsFinal;

+ 1 - 0
config/web.js

@@ -232,6 +232,7 @@ const JsFiles = {
             pay: {
                 files: [
                     "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                    "/public/js/toastr.min.js",
                 ],
                 mergeFiles: [
                     "/public/js/sub_menu.js",