| 
					
				 | 
			
			
				@@ -6,7 +6,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  *  用到费率的规则必须有feeRateID属性,当有该属性时,会自动显示费率值。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/*let defaultBillTemplate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/*  新版GLD 取消了默认清单模板,所以这里废弃。先留着,预防不时之需。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let defaultBillTemplate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ID: 15, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     name: "清单公式", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     calcItems: [ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -430,26 +431,74 @@ let treeNodeTools = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return nodes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    isRation: function(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.ration; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    isBill: function(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return treeNode.sourceType === ModuleNames.bills; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     isLeafBill: function(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return treeNode.sourceType === projectObj.project.Bills.getSourceType() && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return treeNode.sourceType === ModuleNames.bills && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.source.children && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.source.children.length === 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     isNullBill: function (treeNode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return this.isLeafBill(treeNode) && (treeNode.children.length === 0) && (!treeNode.data.calcBase); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    isRationCategory: function(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return treeNode.sourceType === ModuleNames.ration; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    isRation: function(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.ration; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     isVolumePrice: function (treeNode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.volumePrice; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     isGljRation: function (treeNode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.gljRation; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    initFeeField(treeNode, fieldName){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!treeNode.data.fees) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            treeNode.data.fees = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            treeNode.data.feesIndex = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!treeNode.data.feesIndex[fieldName]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let fee = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'fieldName': fieldName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'unitFee': 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'totalFee': 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'tenderUnitFee': 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                'tenderTotalFee': 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            treeNode.data.fees.push(fee); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            treeNode.data.feesIndex[fieldName] = fee; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getCalcType(treeNode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.isRationCategory(treeNode)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return treeNodeCalcType.ctRationCalcProgram; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else if (this.isNullBill(treeNode)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return treeNodeCalcType.ctCommonUnitFee; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else if (this.isLeafBill(treeNode)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (treeNode.children && treeNode.children.length > 0){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return treeNodeCalcType.ctBillCalcProgram; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else                                        // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return treeNodeCalcType.ctGatherRationsFees; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else{                                          // 公式计算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return treeNodeCalcType.ctCalcBaseValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else if (this.isBill(treeNode)) {                              // 父清单:汇总子清单的费用类别 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return treeNodeCalcType.ctGatherBillsFees; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return treeNodeCalcType.ctRationCalcProgram; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -463,18 +512,18 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     getSourceType () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return ModuleNames.calc_program; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    };    // 兼容Project框架方法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     loadData (datas) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         this.datas = datas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         this.compileAllTemps(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    };   // 兼容Project框架方法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     doAfterUpdate (err, data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(!err){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             $.bootstrapLoading.end(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    };  // 兼容Project框架方法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 经测试,全部编译一次耗时0.003~0.004秒。耗时基本忽略不计。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     compileAllTemps(){ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -648,28 +697,14 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    initFeeField(treeNode, fieldName){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!treeNode.data.fees) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            treeNode.data.fees = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            treeNode.data.feesIndex = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!treeNode.data.feesIndex[fieldName]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let fee = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                'fieldName': fieldName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                'unitFee': 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                'totalFee': 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                'tenderUnitFee': 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                'tenderTotalFee': 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            treeNode.data.fees.push(fee); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            treeNode.data.feesIndex[fieldName] = fee; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // 仅内部调用。注意:外部不能直接使用,因为这里传入的树节点必须有一定的初始化。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    InnerCalc(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    innerCalc(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let me = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let project = me.project; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 仅用作树节点显示的工料机不能参与计算。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (treeNode.sourceType === me.project.ration_glj.getSourceType()) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        treeNode.calcType = treeNodeTools.getCalcType(treeNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         function initFees(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (!treeNode.data.fees) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -711,12 +746,13 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return ['labour', 'material', 'machine', 'mainMaterial', 'equipment'].indexOf(type) > -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 汇总定额或子清单的费用类别 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees || treeNode.calcType == treeNodeCalcType.ctGatherBillsFees){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 父清单汇总子项(定额或子清单)的费用类别 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            treeNode.calcType == treeNodeCalcType.ctGatherBillsFees){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.data.programID = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             initFees(treeNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let objsArr = (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees) ? project.Ration.getRationsByNode(treeNode) : treeNode.children; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let objsArr = (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees) ? me.project.Ration.getRationsByNode(treeNode) : treeNode.children; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let rst = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for (let ft of cpFeeTypes) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 let ftObj = {}; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -798,7 +834,7 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             delete treeNode.data.fees;    // 直接删掉再新增,不用一个个费判断更新,效率更高。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             delete treeNode.data.feesIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            me.initFeeField(treeNode, 'common'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            treeNodeTools.initFeeField(treeNode, 'common'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.data.feesIndex.common.unitFee = uf.toDecimal(decimalObj.bills.unitPrice); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.data.feesIndex.common.totalFee = tf.toDecimal(decimalObj.bills.totalPrice); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.data.feesIndex.common.tenderUnitFee = tuf.toDecimal(decimalObj.bills.unitPrice); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -806,13 +842,12 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.changed = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.data.calcTemplate = {"calcItems": []}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 叶子清单的计算基数计算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 叶子清单公式计算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         else if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             delete treeNode.data.gljList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (treeNode.data.programID) treeNode.data.programID = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let f = treeNode.data.feeRate ? treeNode.data.feeRate : 100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // let q = treeNode.data.quantity ? treeNode.data.quantity : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (!treeNode.data.quantity) treeNode.data.quantity = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let q = treeNode.data.quantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let b = treeNode.data.calcBaseValue ? treeNode.data.calcBaseValue : 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -823,7 +858,7 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             delete treeNode.data.fees;    // 直接删掉再新增,不用一个个费判断更新,效率更高。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             delete treeNode.data.feesIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            me.initFeeField(treeNode, 'common'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            treeNodeTools.initFeeField(treeNode, 'common'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.data.feesIndex.common.unitFee = uf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.data.feesIndex.common.totalFee = tf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.data.feesIndex.common.tenderUnitFee = tuf; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -831,7 +866,7 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.changed = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             treeNode.data.calcTemplate = {"calcItems": []}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 定额或清单自己的计算程序计算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 定额或叶子清单自己的计算程序计算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (treeNode.calcType == treeNodeCalcType.ctRationCalcProgram) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (treeNode.data.type == rationType.volumePrice){ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -852,10 +887,9 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else if (treeNode.calcType == treeNodeCalcType.ctBillCalcProgram) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                let rations = project.Ration.getBillsSortRation(treeNode.source.getID()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                treeNode.data.gljList = project.ration_glj.getGatherGljArrByRations(rations); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let rations = me.project.Ration.getBillsSortRation(treeNode.source.getID()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                treeNode.data.gljList = me.project.ration_glj.getGatherGljArrByRations(rations); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // if (treeNode.data.programID == undefined || treeNode.data.programID == defaultBillTemplate.ID){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (treeNode.data.programID == undefined){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     treeNode.data.programID = projectInfoObj.projectInfo.property.engineering; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -891,40 +925,60 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /*// 计算公式结点(叶子清单的计算基数计算)。仅内部调用。注意:外部不能直接使用,因为这里传入的树节点必须有一定的初始化。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    innerCalcFormula(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        treeNode.calcType = treeNodeTools.getCalcType(treeNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (treeNode.calcType != treeNodeCalcType.ctCalcBaseValue) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let me = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete treeNode.data.gljList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (treeNode.data.programID) treeNode.data.programID = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let f = treeNode.data.feeRate ? treeNode.data.feeRate : 100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!treeNode.data.quantity) treeNode.data.quantity = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let q = treeNode.data.quantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let b = treeNode.data.calcBaseValue ? treeNode.data.calcBaseValue : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let uf = (b * f * q / 100).toDecimal(decimalObj.bills.unitPrice); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let tuf = uf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let tf = (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice) ? (b * f / 100).toDecimal(decimalObj.bills.totalPrice) : (uf * q).toDecimal(decimalObj.bills.totalPrice); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let ttf = tf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete treeNode.data.fees;    // 直接删掉再新增,不用一个个费判断更新,效率更高。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete treeNode.data.feesIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        treeNodeTools.initFeeField(treeNode, 'common'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        treeNode.data.feesIndex.common.unitFee = uf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        treeNode.data.feesIndex.common.totalFee = tf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        treeNode.data.feesIndex.common.tenderUnitFee = tuf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        treeNode.data.feesIndex.common.tenderTotalFee = ttf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        treeNode.changed = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        treeNode.data.calcTemplate = {"calcItems": []}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    };*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 计算本节点(默认同时递归计算所有父节点,可选) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     calculate(treeNode, calcParents = true){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let me = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (treeNode.sourceType === me.project.ration_glj.getSourceType()) return;     // 仅用作树节点显示的工料机不能参与计算。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let isRation = treeNode.sourceType === me.project.Ration.getSourceType(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let isBill = treeNode.sourceType === me.project.Bills.getSourceType(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let changedNodes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (isRation){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            treeNode.calcType = treeNodeCalcType.ctRationCalcProgram; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        else  if (treeNodeTools.isNullBill(treeNode)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            treeNode.calcType = treeNodeCalcType.ctCommonUnitFee; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        else if (treeNodeTools.isLeafBill(treeNode)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (treeNode.children && treeNode.children.length > 0){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (me.project.property.billsCalcMode === leafBillGetFeeType.billsPrice) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    treeNode.calcType = treeNodeCalcType.ctBillCalcProgram; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                else                                        // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    treeNode.calcType = treeNodeCalcType.ctGatherRationsFees; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            else{                                          // 公式计算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                treeNode.calcType = treeNodeCalcType.ctCalcBaseValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        else if (isBill)                                 // 父清单:汇总子清单的费用类别 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            treeNode.calcType = treeNodeCalcType.ctGatherBillsFees; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        me.innerCalc(treeNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        me.InnerCalc(treeNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (treeNode.changed) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!changedNodes.includes(treeNode)) changedNodes.push(treeNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 计算父结点 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (calcParents){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let curNode = treeNode.parent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                while (curNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    me.innerCalc(curNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (curNode.changed && !changedNodes.includes(curNode)) changedNodes.push(curNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    curNode = curNode.parent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 计算所有父结点 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (treeNode.changed && calcParents && treeNode.parent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            me.calculate(treeNode.parent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 父结点算完,再算所有的公式结点(必须先算完父结点,再算公式结点) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            me.calcFormulaNodes(changedNodes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return changedNodes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 存储、刷新本节点(默认存储刷新所有父节点,可选) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1016,20 +1070,32 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return changedNodes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 计算全部公式项 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    calcFormulaNodes(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let nodes = treeNodeTools.getFormulaNodes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (nodes.length == 0) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (let node of nodes){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              this.calcFormulaNode(node); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 计算全部公式项。 (参数意义:将通过本方法后发生改变的节点存入changedNodesArr中) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    calcFormulaNodes(changedNodesArr){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let me = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let formulaNodes = treeNodeTools.getFormulaNodes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (formulaNodes.length == 0) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (let formulaNode of formulaNodes){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            formulaNode.data.userCalcBase = formulaNode.data.calcBase;    // 这句不该出现,projectObj.project.calcBase中要改进。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            projectObj.project.calcBase.calculate(formulaNode, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (projectObj.project.calcBase.success){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 计算公式结点 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                me.innerCalc(formulaNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (formulaNode.changed && !changedNodesArr.includes(formulaNode)) changedNodesArr.push(formulaNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 计算父结点 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (formulaNode.changed){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    let curNode = formulaNode.parent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    while (curNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        me.innerCalc(curNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (curNode.changed && !changedNodesArr.includes(curNode)) changedNodesArr.push(curNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        curNode = curNode.parent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 计算公式项。(它一定是叶子结点,它的父结点一定没有公式) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    calcFormulaNode(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // do 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 计算叶子清单下的所有子结点(如定额、量价、工料机定额等), 并计算自身和所有父结点。最后打包存储。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     calcLeafAndSave(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let me = this; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1074,4 +1140,11 @@ class CalcProgram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         me.saveNodes(changedNodes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 计算并保存指定的一个树节点。修改一个树节点,实际上要计算和保存的是一批树结点:层层父结点、被其它结点(的公式)引用的公式结点。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 这个方法实际上封装了calculate()和saveNodes()两个方法,方便外部调用,少写一点代码。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    calcAndSave(treeNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let changedNodes = this.calculate(treeNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.saveNodes(changedNodes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |