|
@@ -4,14 +4,6 @@
|
|
|
* added by CSL, 2017-09-01 增加公式解析对象analyzer,用于解析用户修改公式、自定义表达式。
|
|
|
*/
|
|
|
|
|
|
-// 需求说小数位数固定为2位,这里预留缓冲接口,防止以后需求变卦。
|
|
|
-const Digit_Calc_Program = -2; // 需求指定计算程序用到的小数位数。
|
|
|
-const Digit_Calc_Program_Default = -6; // 需求末指定时默认用到的小数位数。
|
|
|
-function round(value, useDef = false) {
|
|
|
- let digit = useDef ? Digit_Calc_Program_Default : Digit_Calc_Program;
|
|
|
- return scMathUtil.roundTo(value, digit);
|
|
|
-};
|
|
|
-
|
|
|
let executeObj = {
|
|
|
treeNode: null,
|
|
|
template: null,
|
|
@@ -52,12 +44,12 @@ let executeObj = {
|
|
|
if (base.gljTypes.indexOf(md.glj_type) >= 0) {
|
|
|
price = md["base_price"];
|
|
|
if (!price) price = 0;
|
|
|
- mdSum = mdSum + round(md["consumption"] * price);
|
|
|
- mdSum = round(mdSum, true);
|
|
|
+ mdSum = mdSum + (md["consumption"] * price).toDecimal(me.digit);
|
|
|
+ mdSum = (mdSum).toDecimal(me.digitDefault);
|
|
|
}
|
|
|
};
|
|
|
- tmpSum = tmpSum + round(glj["quantity"] * mdSum, true);
|
|
|
- tmpSum = round(tmpSum, true);
|
|
|
+ tmpSum = tmpSum + (glj["quantity"] * mdSum).toDecimal(me.digitDefault);
|
|
|
+ tmpSum = (tmpSum).toDecimal(me.digitDefault);
|
|
|
}
|
|
|
};
|
|
|
}else{
|
|
@@ -74,12 +66,13 @@ let executeObj = {
|
|
|
price = mprice - aprice;
|
|
|
};
|
|
|
if (!price) price = 0;
|
|
|
- tmpSum = round(tmpSum + round(glj["quantity"] * price, true), true);
|
|
|
+ tmpSum = tmpSum + (glj["quantity"] * price).toDecimal(me.digitDefault);
|
|
|
+ tmpSum = (tmpSum).toDecimal(me.digitDefault);
|
|
|
};
|
|
|
};
|
|
|
};
|
|
|
|
|
|
- rst = round(tmpSum);
|
|
|
+ rst = (tmpSum).toDecimal(me.digitDefault);
|
|
|
};
|
|
|
|
|
|
return rst;
|
|
@@ -242,6 +235,8 @@ class Calculation {
|
|
|
me.compiledFeeTypeNames = [];
|
|
|
me.compiledCalcBases = {};
|
|
|
me.saveForReports = [];
|
|
|
+ me.digit = 2;
|
|
|
+ me.digitDefault = 6;
|
|
|
|
|
|
let private_compile_feeRateFile = function() {
|
|
|
if (feeRates) {
|
|
@@ -392,81 +387,130 @@ class Calculation {
|
|
|
};
|
|
|
};
|
|
|
|
|
|
- calculate(treeNode){
|
|
|
- let me = this;
|
|
|
- let templateID = treeNode.data.programID;
|
|
|
- if (!templateID) templateID = 1;
|
|
|
- let template = me.compiledTemplates[templateID];
|
|
|
- treeNode.data.calcTemplate = template;
|
|
|
+ initFees(treeNode){
|
|
|
+ if (!treeNode.data.fees) {
|
|
|
+ treeNode.data.fees = [];
|
|
|
+ treeNode.data.feesIndex = {};
|
|
|
+ treeNode.changed = true;
|
|
|
+ };
|
|
|
+ };
|
|
|
|
|
|
- let project = projectObj.project;
|
|
|
+ checkFee(treeNode, feeObj){
|
|
|
+ if (feeObj.fieldName == '') return;
|
|
|
|
|
|
- // 缺省计算程序需要提供总金额作为计算基数,然后每条按比例(费率)计算,不需要工料机明细。
|
|
|
- if (treeNode.data.baseTotalPrice != undefined){
|
|
|
- delete treeNode.data.gljList;
|
|
|
+ if (!treeNode.data.feesIndex[feeObj.fieldName]){
|
|
|
+ let fee = {
|
|
|
+ 'fieldName': feeObj.fieldName,
|
|
|
+ 'unitFee': feeObj.unitFee,
|
|
|
+ 'totalFee': feeObj.totalFee,
|
|
|
+ 'tenderUnitFee': 0,
|
|
|
+ 'tenderTotalFee': 0
|
|
|
+ };
|
|
|
+ treeNode.data.fees.push(fee);
|
|
|
+ treeNode.data.feesIndex[feeObj.fieldName] = fee;
|
|
|
+ treeNode.changed = true;
|
|
|
}
|
|
|
- else {
|
|
|
- if (treeNode.sourceType === project.Ration.getSourceType()) {
|
|
|
- treeNode.data.gljList = project.ration_glj.getGljArrByRation(treeNode.data.ID);
|
|
|
- }
|
|
|
- else if (treeNode.sourceType === project.Bills.getSourceType()) {
|
|
|
- let rations = project.Ration.getBillsSortRation(treeNode.source.getID());
|
|
|
- treeNode.data.gljList = project.ration_glj.getGatherGljArrByRations(rations);
|
|
|
+ else{
|
|
|
+ if (treeNode.data.feesIndex[feeObj.fieldName].unitFee != feeObj.unitFee){
|
|
|
+ treeNode.data.feesIndex[feeObj.fieldName].unitFee = feeObj.unitFee;
|
|
|
+ treeNode.changed = true;
|
|
|
};
|
|
|
- };
|
|
|
-
|
|
|
- if (treeNode && template.hasCompiled) {
|
|
|
- let $CE = executeObj;
|
|
|
- $CE.treeNode = treeNode;
|
|
|
- $CE.template = template;
|
|
|
- $CE.calcBase = me.compiledCalcBases;
|
|
|
|
|
|
- if (!treeNode.data.fees) {
|
|
|
- treeNode.data.fees = [];
|
|
|
- treeNode.data.feesIndex = {};
|
|
|
+ if (treeNode.data.feesIndex[feeObj.fieldName].totalFee != feeObj.totalFee){
|
|
|
+ treeNode.data.feesIndex[feeObj.fieldName].totalFee = feeObj.totalFee;
|
|
|
treeNode.changed = true;
|
|
|
};
|
|
|
+ };
|
|
|
+ };
|
|
|
|
|
|
- for (let idx of template.compiledSeq) {
|
|
|
- let calcItem = template.calcItems[idx];
|
|
|
-
|
|
|
- let feeRate = calcItem.feeRate;
|
|
|
- if (!feeRate) feeRate = 100; // 100%
|
|
|
- calcItem.unitFee = round(eval(calcItem.compiledExpr) * feeRate * 0.01); // 如果eval()对清单树有影响,就换成小麦的Expression对象再试
|
|
|
-
|
|
|
- let quantity = treeNode.data.quantity;
|
|
|
- if (!quantity) quantity = 0;
|
|
|
- calcItem.totalFee = round(calcItem.unitFee * quantity);
|
|
|
-
|
|
|
- // 费用同步到定额
|
|
|
- // 引入小麦的字段检测后,快速切换定额出现计算卡顿现象,过多的循环造成。这里把她的代码拆出来,减少微循环。
|
|
|
- if (calcItem.fieldName != '') {
|
|
|
- if (!treeNode.data.feesIndex[calcItem.fieldName]){
|
|
|
- let fee = {
|
|
|
- 'fieldName': calcItem.fieldName,
|
|
|
- 'unitFee': calcItem.unitFee,
|
|
|
- 'totalFee': calcItem.totalFee,
|
|
|
- 'tenderUnitFee': 0,
|
|
|
- 'tenderTotalFee': 0
|
|
|
- };
|
|
|
- treeNode.data.fees.push(fee);
|
|
|
- treeNode.data.feesIndex[calcItem.fieldName] = fee;
|
|
|
- treeNode.changed = true;
|
|
|
- }
|
|
|
- else{
|
|
|
- if (treeNode.data.feesIndex[calcItem.fieldName].unitFee != calcItem.unitFee){
|
|
|
- treeNode.data.feesIndex[calcItem.fieldName].unitFee = calcItem.unitFee;
|
|
|
- treeNode.changed = true;
|
|
|
- };
|
|
|
+ calculate(treeNode){
|
|
|
+ let me = this;
|
|
|
+ let project = projectObj.project;
|
|
|
|
|
|
- if (treeNode.data.feesIndex[calcItem.fieldName].totalFee != calcItem.totalFee){
|
|
|
- treeNode.data.feesIndex[calcItem.fieldName].totalFee = calcItem.totalFee;
|
|
|
- treeNode.changed = true;
|
|
|
- };
|
|
|
- }
|
|
|
+ // 汇总定额或子清单的费用类别
|
|
|
+ if (treeNode.data.gatherType != undefined){
|
|
|
+ if (treeNode.sourceType != project.Bills.getSourceType()) return;
|
|
|
+
|
|
|
+ me.initFees(treeNode);
|
|
|
+
|
|
|
+ let objsArr = (treeNode.data.gatherType === CP_GatherType.rations) ? project.Ration.getRationsByNode(treeNode) : treeNode.children;
|
|
|
+ let rst = [];
|
|
|
+ for (let ft of feeType) {
|
|
|
+ let ftObj = {};
|
|
|
+ ftObj.fieldName = ft.type;
|
|
|
+ ftObj.name = ft.name;
|
|
|
+ let uf = 0, tf = 0, tuf = 0, ttf = 0;
|
|
|
+ for (let item of objsArr) {
|
|
|
+ let data = (treeNode.data.gatherType === CP_GatherType.rations) ? item : item.data;
|
|
|
+ if (data.feesIndex && data.feesIndex[ft.type]) {
|
|
|
+ uf = (uf + parseFloat(data.feesIndex[ft.type].unitFee)).toDecimal(me.digitDefault);
|
|
|
+ tf = (tf + parseFloat(data.feesIndex[ft.type].totalFee)).toDecimal(me.digitDefault);
|
|
|
+ tuf = (tuf + parseFloat(data.feesIndex[ft.type].tenderUnitFee)).toDecimal(me.digitDefault);
|
|
|
+ ttf = (ttf + parseFloat(data.feesIndex[ft.type].tenderTotalFee)).toDecimal(me.digitDefault);
|
|
|
+ };
|
|
|
};
|
|
|
+ ftObj.unitFee = uf.toDecimal(me.digit);
|
|
|
+ ftObj.totalFee = tf.toDecimal(me.digit);
|
|
|
+ ftObj.tenderUnitFee = tuf.toDecimal(me.digit);
|
|
|
+ ftObj.tenderTotalFee = ttf.toDecimal(me.digit);
|
|
|
+
|
|
|
+ me.checkFee(treeNode, ftObj);
|
|
|
+
|
|
|
+ rst.push(ftObj);
|
|
|
};
|
|
|
+ treeNode.data.calcTemplate = {"calcItems": rst};
|
|
|
}
|
|
|
+ else{
|
|
|
+ // 叶子清单的缺省计算程序需要提供总金额作为计算基数(不需要工料机),然后每条按比例(费率)计算,不需要工料机明细。
|
|
|
+ if (treeNode.data.baseTotalPrice != undefined){
|
|
|
+ if (treeNode.sourceType != project.Bills.getSourceType()) return;
|
|
|
+
|
|
|
+ delete treeNode.data.gljList;
|
|
|
+
|
|
|
+ if (treeNode.data.programID == undefined){
|
|
|
+ treeNode.data.programID = defaultBillTemplate.ID;
|
|
|
+ };
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if (treeNode.sourceType === project.Ration.getSourceType()) {
|
|
|
+ treeNode.data.gljList = project.ration_glj.getGljArrByRation(treeNode.data.ID);
|
|
|
+ }
|
|
|
+ else if (treeNode.sourceType === project.Bills.getSourceType()) {
|
|
|
+ let rations = project.Ration.getBillsSortRation(treeNode.source.getID());
|
|
|
+ treeNode.data.gljList = project.ration_glj.getGatherGljArrByRations(rations);
|
|
|
+ };
|
|
|
+
|
|
|
+ if (treeNode.data.programID == undefined){
|
|
|
+ treeNode.data.programID = 1;
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
+ let template = me.compiledTemplates[treeNode.data.programID];
|
|
|
+ treeNode.data.calcTemplate = template;
|
|
|
+
|
|
|
+ if (treeNode && template.hasCompiled) {
|
|
|
+ let $CE = executeObj;
|
|
|
+ $CE.treeNode = treeNode;
|
|
|
+ $CE.template = template;
|
|
|
+ $CE.calcBase = me.compiledCalcBases;
|
|
|
+
|
|
|
+ me.initFees(treeNode);
|
|
|
+
|
|
|
+ for (let idx of template.compiledSeq) {
|
|
|
+ let calcItem = template.calcItems[idx];
|
|
|
+
|
|
|
+ let feeRate = calcItem.feeRate;
|
|
|
+ if (!feeRate) feeRate = 100; // 100%
|
|
|
+ calcItem.unitFee = (eval(calcItem.compiledExpr) * feeRate * 0.01).toDecimal(me.digit); // 如果eval()对清单树有影响,就换成小麦的Expression对象再试
|
|
|
+
|
|
|
+ let quantity = treeNode.data.quantity;
|
|
|
+ if (!quantity) quantity = 0;
|
|
|
+ calcItem.totalFee = (calcItem.unitFee * quantity).toDecimal(me.digit);
|
|
|
+
|
|
|
+ me.checkFee(treeNode, calcItem);
|
|
|
+ };
|
|
|
+ }
|
|
|
+ };
|
|
|
}
|
|
|
};
|
|
|
|