Selaa lähdekoodia

抽离计算累进数值方法,打包测试

vian 5 vuotta sitten
vanhempi
commit
ffc69c4f98

+ 1 - 0
config/gulpConfig.js

@@ -84,6 +84,7 @@ module.exports = {
         'public/web/socket/connection.js',
         'public/web/uuid.js',
         'public/web/sheet/sheet_common.js',
+        'public/calculate_util.js',
         'web/building_saas/main/js/models/calc_program.js',
         'web/building_saas/main/js/models/calc_base.js',
         'web/building_saas/main/js/views/calc_program_manage.js',

+ 3 - 0
modules/main/routes/main_route.js

@@ -8,6 +8,7 @@ const projectModel = require("../../pm/models/project_model");
 import OptionsDao from '../../options/models/optionsModel';
 import optionSetting from '../../options/models/optionTypes';
 let config = require("../../../config/config.js");
+const calculateUtil = require('../../../public/calculate_util');
 module.exports =function (app) {
     const baseController = new BaseController();
     app.get('/main', baseController.init, function(req, res) {
@@ -29,8 +30,10 @@ module.exports =function (app) {
                 if(options){
                     options = await optionsDao.saveOptions(req.session.sessionUser.id, req.session.sessionCompilation._id, optionSetting);
                 }
+                const testNumber = calculateUtil.getProgressiveFee(9741, '养护单位(业主)管理费', projectData.property.progressiveInterval, 2);
                 res.render('building_saas/main/html/main.html',
                     {
+                        testNumber: testNumber,
                         userAccount: req.session.userAccount,
                         userID: req.session.sessionUser.id,
                         projectData: projectData,

+ 111 - 0
public/calculate_util.js

@@ -0,0 +1,111 @@
+'use strict';
+
+((factory) => {
+    if (typeof module !== 'undefined') {
+        const scMathUtil = require('./scMathUtil').getUtil();
+        module.exports = factory(scMathUtil);
+    } else {
+        window.calculateUtil = factory(scMathUtil);
+    }
+})((scMathUtil) => {
+    function standar(exp) {
+        //去空格
+        exp = exp.replace(/\s/g, '');
+        //( to (
+        exp = exp.replace(/(/g, '(');
+        //)to )
+        exp = exp.replace(/)/g, ')');
+        //,to ,
+        exp = exp.replace(/,/g, ',');
+        //f to F
+        exp = exp.replace(new RegExp('f', 'g'), 'F');
+        return exp;
+    }
+    /**
+     * 获取累进办法计算的金额
+     * @param {Number} baseFee - 基准金额
+     * @param {String} name - 使用累进计算的基数名称(需要与累进库中的名称匹配)
+     * @param {Array} progressiveData - 项目的累进数据(property.progressiveInterval)
+     * @param {Number} decimal - 精度
+     * @return {Number}
+     */
+    function getProgressiveFee(baseFee, name, progressiveData, decimal) {
+        if (!progressiveData) {
+            throw '该项目不存在累进区间数据';
+        }
+        //根据基数名称匹配累进库数据,标准化以免(())等不同导致不匹配
+        const matchProgressiveData = progressiveData.find(item => standar(item.name) === standar(name));
+        if (!matchProgressiveData) {
+            throw `计算基数{${name}}不存在累进区间数据`;
+        }
+        // 将原始数据转换成方便处理的数据:[{feeRate: xx, min: 0, max: 200, minOpr: '(', maxOpr: ']'}]
+        const progression = matchProgressiveData.progression.map(item => {
+            // item.interval内容: eg (0,200]、[300,500) [1000,+)....
+            const interval = standar(item.interval);
+            // ( => 大于 [ => 大于等于 ) => 小于 ] => 小于等于
+            const minReg = /([\(\[])(\d+)/;
+            const minMatch = minReg.exec(interval);
+            if (!minMatch || !minMatch[1] || !minMatch[2]) {
+                throw `计算基数{${name}}累进区间数据错误`;
+            }
+            const minOpr = minMatch[1];
+            // 后台数据单位为万元,这里转为为元
+            const min = parseFloat(minMatch[2]) * 10000;
+            const maxReg = /[\,,]([\d\+]+)([\)\]])/;
+            const maxMatch = maxReg.exec(interval);
+            if (!maxMatch || !maxMatch[1] || !maxMatch[2]) {
+                throw `计算基数{${name}}累进区间数据错误`;
+            }
+            const max = maxMatch[1] === '+' ? 'infinity' : parseFloat(maxMatch[1]) * 10000;
+            const maxOpr = maxMatch[2];
+            return {
+                feeRate: item.feeRate,
+                min,
+                minOpr,
+                max,
+                maxOpr
+            }
+        });
+        progression.sort((a, b) => a.min - b.min);
+        // 基数所在区间
+        const withinData = progression.find(item => {
+            const oprMiddle = item.max === 'infinity' ? '+' : '';
+            const oprLink = item.minOpr + oprMiddle + item.maxOpr;
+            switch (oprLink) {
+                case '()':
+                    return baseFee > item.min && baseFee < item.max;
+                case '(]':
+                    return baseFee > item.min && baseFee <= item.max;
+                case '[)':
+                    return baseFee >= item.min && baseFee < item.max;
+                case '[]':
+                    return baseFee >= item.min && baseFee <= item.max;
+                case '(+)':
+                case '(+]':
+                    return baseFee > item.min;
+                case '[+)':
+                case '[+]':
+                    return baseFee >= item.min;
+                default:
+                    return false;
+            }
+        });
+        if (!withinData) {
+            return 0;
+        }
+        // 累进计算
+        let fee = 0;
+        //累进之前的区间
+        for (let i = 0; i < progression.indexOf(withinData); i++) {
+            const perData = progression[i];
+            fee += (perData.max - perData.min) * perData.feeRate * 0.01;
+        }
+        //累进所在区间
+        fee += (baseFee - withinData.min) * withinData.feeRate * 0.01;
+        return scMathUtil.roundForObj(fee, decimal);
+    }
+
+    return {
+        getProgressiveFee,
+    };
+});

+ 99 - 0
public/common_util.js

@@ -43,6 +43,105 @@
             return sorted;
         }
     }
+    function standar(exp) {
+        //去空格
+        exp = exp.replace(/\s/g, '');
+        //( to (
+        exp = exp.replace(/(/g, '(');
+        //)to )
+        exp = exp.replace(/)/g, ')');
+        //,to ,
+        exp = exp.replace(/,/g, ',');
+        //f to F
+        exp = exp.replace(new RegExp('f', 'g'), 'F');
+        return exp;
+    }
+    /**
+     * 获取累进办法计算的金额
+     * @param {Number} baseFee - 基准金额
+     * @param {String} name - 使用累进计算的基数名称(需要与累进库中的名称匹配)
+     * @param {Array} progressiveData - 项目的累进数据(property.progressiveInterval)
+     * @param {Function} decimalFunc - scMath中的精度方法
+     * @param {Number} decimal - 精度
+     * @return {Number}
+     */
+    function getProgressiveFee(baseFee, name, progressiveData, decimalFunc, decimal) {
+        if (!progressiveData) {
+            throw '该项目不存在累进区间数据';
+        }
+        //根据基数名称匹配累进库数据,标准化以免(())等不同导致不匹配
+        const matchProgressiveData = progressiveData.find(item => standar(item.name) === standar(name));
+        if (!matchProgressiveData) {
+            throw `计算基数{${name}}不存在累进区间数据`;
+        }
+        // 将原始数据转换成方便处理的数据:[{feeRate: xx, min: 0, max: 200, minOpr: '(', maxOpr: ']'}]
+        const progression = matchProgressiveData.progression.map(item => {
+            // item.interval内容: eg (0,200]、[300,500) [1000,+)....
+            const interval = standar(item.interval);
+            // ( => 大于 [ => 大于等于 ) => 小于 ] => 小于等于
+            const minReg = /([\(\[])(\d+)/;
+            const minMatch = minReg.exec(interval);
+            if (!minMatch || !minMatch[1] || !minMatch[2]) {
+                throw `计算基数{${name}}累进区间数据错误`;
+            }
+            const minOpr = minMatch[1];
+            // 后台数据单位为万元,这里转为为元
+            const min = parseFloat(minMatch[2]) * 10000;
+            const maxReg = /[\,,]([\d\+]+)([\)\]])/;
+            const maxMatch = maxReg.exec(interval);
+            if (!maxMatch || !maxMatch[1] || !maxMatch[2]) {
+                throw `计算基数{${name}}累进区间数据错误`;
+            }
+            const max = maxMatch[1] === '+' ? 'infinity' : parseFloat(maxMatch[1]) * 10000;
+            const maxOpr = maxMatch[2];
+            return {
+                feeRate: item.feeRate,
+                min,
+                minOpr,
+                max,
+                maxOpr
+            }
+        });
+        progression.sort((a, b) => a.min - b.min);
+        // 基数所在区间
+        const withinData = progression.find(item => {
+            const oprMiddle = item.max === 'infinity' ? '+' : '';
+            const oprLink = item.minOpr + oprMiddle + item.maxOpr;
+            switch (oprLink) {
+                case '()':
+                    return baseFee > item.min && baseFee < item.max;
+                case '(]':
+                    return baseFee > item.min && baseFee <= item.max;
+                case '[)':
+                    return baseFee >= item.min && baseFee < item.max;
+                case '[]':
+                    return baseFee >= item.min && baseFee <= item.max;
+                case '(+)':
+                case '(+]':
+                    return baseFee > item.min;
+                case '[+)':
+                case '[+]':
+                    return baseFee >= item.min;
+                default:
+                    return false;
+            }
+        });
+        if (!withinData) {
+            return 0;
+        }
+        // 累进计算
+        let fee = 0;
+        //累进之前的区间
+        for (let i = 0; i < progression.indexOf(withinData); i++) {
+            const perData = progression[i];
+            fee += (perData.max - perData.min) * perData.feeRate * 0.01;
+        }
+        //累进所在区间
+        fee += (baseFee - withinData.min) * withinData.feeRate * 0.01;
+        return decimalFunc(fee, decimal);
+        //return fee.toDecimal(decimalObj.bills.totalPrice);
+    }
+
     return {
         isDef,
         isEmptyVal,

+ 3 - 0
web/building_saas/main/html/main.html

@@ -42,6 +42,8 @@
         let projectReadOnly = JSON.parse('<%- projectReadOnly %>');
         let projectCooperate = JSON.parse('<%- projectCooperate %>');
         let projectOptins =  JSON.parse('<%- options %>');
+        console.log(`'<%- testNumber %>'`);
+        console.log('<%- testNumber %>');
         const G_SHOW_BLOCK_LIB = false;
 //        const G_SHOW_BLOCK_LIB = false;
     </script>
@@ -1977,6 +1979,7 @@
     <script type="text/javascript" src="/web/building_saas/main/js/models/ration_template.js"></script>
     <!--<script type="text/javascript" src="/web/building_saas/main/js/models/volume_price.js"></script>-->
     <script type="text/javascript" src="/web/building_saas/main/js/models/labour_coe.js"></script>
+    <script type="text/javascript" src="/public/calculate_util.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/calc_program.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/calc_base.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/installation_fee.js"></script>

+ 3 - 1
web/building_saas/main/js/models/calc_base.js

@@ -606,8 +606,10 @@ let baseFigureTemplate = {
         //{养护单位(业主)管理费}
         // 使用累进办法计算,计算基数为{定额建筑安装工程(其中定额设备购置费按 40%计)}
         'YHDWYZGLF': function (tender) {
+            debugger;
             let baseFee = this['DEJZAZGCSBSS'](tender);
-            return cbTools.getProgressiveFee(baseFee, '养护单位(业主)管理费');
+            return calculateUtil.getProgressiveFee(baseFee, '养护单位(业主)管理费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice);
+            //return cbTools.getProgressiveFee(baseFee, '养护单位(业主)管理费');
         },
         //{信息化费}
         // 使用累进办法计算,计算基数为{定额建筑安装工程(其中定额设备购置费按 40%计)}