123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- 'use strict';
- ((factory) => {
- if (typeof module !== 'undefined') {
- const scMathUtil = require('./scMathUtil').getUtil();
- const commonConstants = require('./common_constants');
- module.exports = factory(scMathUtil, commonConstants);
- } else {
- window.calculateUtil = factory(scMathUtil, commonConstants);
- }
- })((scMathUtil, commonConstants) => {
- 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 | String} taxType - 项目的计税方式
- * @param {Number} decimal - 精度
- * @param {Object} deficiency - 不足处理映射 @example: {'路线工程监理费': 20000 } // 不足2万按2万
- * @param {Object} beyond - 超出处理映射 @example: {'路线工程监理费': 500000 } // 超过50万按50万
- * @return {Number}
- */
- function getProgressiveFee(baseFee, name, progressiveData, taxType, decimal, deficiency, beyond) {
- 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 => {
- let feeRateField = +taxType === commonConstants.TaxType.NORMAL
- ? 'generalRate'
- : +taxType === commonConstants.TaxType.SIMPLE
- ? 'simpleRate'
- : '';
- if (!feeRateField) {
- throw `计算基数{${name}}累进区间费率数据错误`;
- }
- // 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[feeRateField],
- 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 = scMathUtil.roundForObj(fee + (baseFee - withinData.min) * withinData.feeRate * 0.01, decimal);
- // 不足、超出处理
- const deficiencyFee = deficiency && deficiency[name] || 0;
- const beyondFee = beyond && beyond[name] || 0;
- return deficiencyFee && fee > 0 && fee < deficiencyFee
- ? deficiencyFee
- : beyondFee && fee > beyondFee
- ? beyondFee
- : fee;
- }
- /**
- * 该基数包含的累进基数
- * @param {String} calcBase - 计算基数
- * @param {Array} progression - 累进基数名称数组
- * @return {Array}
- */
- function getProgressive(calcBase, progression) {
- if (typeof calcBase !== 'string' || !progression) {
- return [];
- }
- const reg = /{[^}]+}/g;
- const matched = calcBase.match(reg);
- if (!matched) {
- return [];
- }
- return matched
- .filter(mStr => progression.some(pStr => `{${pStr}}` === mStr))
- .map(mStr => mStr.replace(/[{}]/g, ''));
- }
- /**
- * 该基数是否含有累进基数
- * @param {String} calcBase - 计算基数
- * @param {Array} progression - 累进基数名称数组
- * @return {Boolean}
- */
- function isProgressive(calcBase, progression) {
- const progressiveBase = getProgressive(calcBase, progression);
- return !!progressiveBase.length;
- }
- return {
- getProgressiveFee,
- isProgressive,
- getProgressive,
- };
- });
|