|
@@ -427,62 +427,79 @@ let cbTools = {
|
|
|
//@param {Number}baseFee(相关基数金额) {String}name(使用累进计算的基数名称)
|
|
//@param {Number}baseFee(相关基数金额) {String}name(使用累进计算的基数名称)
|
|
|
//@return {Number}
|
|
//@return {Number}
|
|
|
getProgressiveFee: function (baseFee, name) {
|
|
getProgressiveFee: function (baseFee, name) {
|
|
|
- let progressiveData = calcBase.project.property.progressiveInterval;
|
|
|
|
|
|
|
+ const progressiveData = calcBase.project.property.progressiveInterval;
|
|
|
if (!progressiveData) {
|
|
if (!progressiveData) {
|
|
|
throw '该项目不存在累进区间数据';
|
|
throw '该项目不存在累进区间数据';
|
|
|
}
|
|
}
|
|
|
- let matchData = _.find(progressiveData, function (data) {
|
|
|
|
|
- //根据基数名称匹配累进库数据,标准化以免(())等不同导致不匹配
|
|
|
|
|
- return cbAnalyzer.standar(data.name) === cbAnalyzer.standar(name);
|
|
|
|
|
- });
|
|
|
|
|
- if (!matchData) {
|
|
|
|
|
- //return 0;
|
|
|
|
|
|
|
+ //根据基数名称匹配累进库数据,标准化以免(())等不同导致不匹配
|
|
|
|
|
+ const matchProgressiveData = progressiveData.find(item => cbAnalyzer.standar(item.name) === cbAnalyzer.standar(name));
|
|
|
|
|
+ if (!matchProgressiveData) {
|
|
|
throw `计算基数{${name}}不存在累进区间数据`;
|
|
throw `计算基数{${name}}不存在累进区间数据`;
|
|
|
}
|
|
}
|
|
|
- let progression = matchData.progression;
|
|
|
|
|
- //获取区间中的最小值(0, 10] = 0
|
|
|
|
|
- function getMin(intervalStr) {
|
|
|
|
|
- let str = cbAnalyzer.standar(intervalStr);
|
|
|
|
|
- let match = /\((\d+)?/g.exec(str);
|
|
|
|
|
- return typeof match[1] !== 'undefined' ? parseFloat(match[1]) * 10000 : null; //后台数据单位为万元,这里转为为元
|
|
|
|
|
- }
|
|
|
|
|
- //获取区间中的最大值(0, 10] = 10
|
|
|
|
|
- function getMax(intervalStr) {
|
|
|
|
|
- let str = cbAnalyzer.standar(intervalStr);
|
|
|
|
|
- let match = /[\,,,](\d+)?/g.exec(str);
|
|
|
|
|
- return typeof match[1] !== 'undefined' ? parseFloat(match[1]) * 10000 : null
|
|
|
|
|
- }
|
|
|
|
|
- //将累进区间进行排序
|
|
|
|
|
- progression.sort(function (a, b) {
|
|
|
|
|
- let aV = getMin(a.interval),
|
|
|
|
|
- bV = getMin(b.interval);
|
|
|
|
|
- return aV - bV;
|
|
|
|
|
|
|
+ // 将原始数据转换成方便处理的数据:[{feeRate: xx, min: 0, max: 200, minOpr: '(', maxOpr: ']'}]
|
|
|
|
|
+ const progression = matchProgressiveData.progression.map(item => {
|
|
|
|
|
+ // item.interval内容: eg (0,200]、[300,500) [1000,+)....
|
|
|
|
|
+ const interval = cbAnalyzer.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
|
|
|
|
|
+ }
|
|
|
});
|
|
});
|
|
|
- //累进计算
|
|
|
|
|
- let fee = 0;
|
|
|
|
|
- //找到所在区间
|
|
|
|
|
- let within = _.find(progression, function (data) {
|
|
|
|
|
- let min = getMin(data.interval),
|
|
|
|
|
- max = getMax(data.interval);
|
|
|
|
|
- return min !== null && baseFee > min && (max !== null && baseFee <= max || max === null);
|
|
|
|
|
|
|
+ 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 (!within) {
|
|
|
|
|
|
|
+ if (!withinData) {
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
+ // 累进计算
|
|
|
|
|
+ let fee = 0;
|
|
|
//累进之前的区间
|
|
//累进之前的区间
|
|
|
- for (let i = 0; i < progression.indexOf(within); i++) {
|
|
|
|
|
- let perData = progression[i],
|
|
|
|
|
- min = getMin(perData.interval),
|
|
|
|
|
- max = getMax(perData.interval);
|
|
|
|
|
- if (min !== null && max !== null) {
|
|
|
|
|
- fee += (max - min) * perData.feeRate * 0.01;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ for (let i = 0; i < progression.indexOf(withinData); i++) {
|
|
|
|
|
+ const perData = progression[i];
|
|
|
|
|
+ fee += (perData.max - perData.min) * perData.feeRate * 0.01;
|
|
|
}
|
|
}
|
|
|
//累进所在区间
|
|
//累进所在区间
|
|
|
- let min = getMin(within.interval);
|
|
|
|
|
- if (min !== null) {
|
|
|
|
|
- fee += (baseFee - min) * within.feeRate * 0.01;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ fee += (baseFee - withinData.min) * withinData.feeRate * 0.01;
|
|
|
return fee.toDecimal(decimalObj.bills.totalPrice);
|
|
return fee.toDecimal(decimalObj.bills.totalPrice);
|
|
|
},
|
|
},
|
|
|
//获取清单100章下的节点(只需要找最底层的,排除了底层,父项金额即排除了子项)
|
|
//获取清单100章下的节点(只需要找最底层的,排除了底层,父项金额即排除了子项)
|