瀏覽代碼

feat: 估算相关

vian 4 年之前
父節點
當前提交
7df41498d1

+ 14 - 8
modules/main/facade/bill_facade.js

@@ -260,7 +260,7 @@ module.exports={
             const totalFeeItem = totalItem.fees && totalItem.fees.find(f => f.fieldName === 'common');
             totalFee = totalFeeItem ? +totalFeeItem.totalFee : 0;
         }
-        // 方便报表取数据,规范数据
+        // 方便报表取数据,规范数据 
         rst.forEach(item => {
             item.code = item.code || '';
             item.name = item.name || '';
@@ -271,21 +271,24 @@ module.exports={
             const equipmentFeeItem = item.fees && item.fees.find(f => f.fieldName === 'equipment');
             const otherFeeItem = item.fees && item.fees.find(f => f.fieldName === 'other');
             const totalFeeItem = item.fees && item.fees.find(f => f.fieldName === 'common');
+            const estimateFeeItem = item.fees && item.fees.find(f => f.fieldName === 'estimation');
             item.buildingFee = buildingFeeItem ? buildingFeeItem.totalFee : 0;
             item.installationFee = installFeeItem ? installFeeItem.totalFee : 0;
             item.equipmentFee = equipmentFeeItem ? equipmentFeeItem.totalFee : 0;
             item.otherFee = otherFeeItem ? otherFeeItem.totalFee : 0;
             item.totalFee = totalFeeItem ? totalFeeItem.totalFee : 0;
+            item.estimateFee = estimateFeeItem ? estimateFeeItem.totalFee : 0;
             item.unitFee = totalFeeItem ? totalFeeItem.unitFee : 0;
+            item.diffFee = item.estimateFee - item.totalFee;  // 增减金额 估算合价-概算合价
+            item.diffRate = item.estimateFee ? scMathUtil.roundForObj((item.diffFee / item.estimateFee) * 100, 4) : 0; // 增减金额/估算合价*100
             // 计算占总投资比例
-            const rate = totalFee ?  scMathUtil.roundForObj(item.totalFee / totalFee, 4) : 0; 
-            item.rate = rate * 100; // 转换为百分比
+            item.rate = totalFee ?  scMathUtil.roundForObj((item.totalFee / totalFee) * 100, 4) : 0;
         });
         return rst;
     },
     // 获取工程费用数据,作为概算汇总数据的拼接树数据
     getConstructionFeeData: async function (constructionID, nextID) {
-        const projects = await pmFacade.getPosterityProjects([constructionID], true, { _id: 0, ID: 1, ParentID: 1, NextSiblingID: 1, name: 1, projType: 1, chapterCode: 1, sectionCode: 1, quantity: 1, unit: 1, 'property.engineeringName': 1});
+        const projects = await pmFacade.getPosterityProjects([constructionID], true, { _id: 0, ID: 1, ParentID: 1, NextSiblingID: 1, name: 1, projType: 1, chapterCode: 1, sectionCode: 1, quantity: 1, unit: 1, fees: 1, 'property.engineeringName': 1});
         const construction = projects.find(p => p.ID === constructionID);
         const items = getSortedTreeData(construction.ParentID, projects);
         // 转换为uuid
@@ -386,16 +389,16 @@ module.exports={
                     unitFeeObj[feeType] = unitFee;
                     singleFeeObj[feeType] = scMathUtil.roundForObj(singleFeeObj[feeType] + unitFee, processDecimal);
                 }
-                unit.fees = feeObj2Fees(unitFeeObj, unit.quantity);
+                unit.fees = feeObj2Fees(unitFeeObj, unit.fees, unit.quantity);
             }
-            single.fees = feeObj2Fees(singleFeeObj, single.quantity);
+            single.fees = feeObj2Fees(singleFeeObj, single.fees, single.quantity);
             // 汇算到建设项目
             constructionFeeObj.total = scMathUtil.roundForObj(constructionFeeObj.total + singleFeeObj.total, processDecimal);
             constructionFeeObj.building = scMathUtil.roundForObj(constructionFeeObj.building + singleFeeObj.building, processDecimal);
             constructionFeeObj.installation = scMathUtil.roundForObj(constructionFeeObj.installation + singleFeeObj.installation, processDecimal);
             constructionFeeObj.equipment = scMathUtil.roundForObj(constructionFeeObj.equipment + singleFeeObj.equipment, processDecimal);
         }
-        construction.fees = feeObj2Fees(constructionFeeObj, construction.quantity);
+        construction.fees = feeObj2Fees(constructionFeeObj, construction.fees, construction.quantity);
         // 更新fees字段
         const bulks = [];
         items.forEach(item => {
@@ -420,17 +423,20 @@ module.exports={
         }
         construction.fees.push(equipmentFeeObj); */
 
-        function feeObj2Fees(feeObj, quantity) {
+        function feeObj2Fees(feeObj, orgFees, quantity) {
             const totalFee = scMathUtil.roundForObj(feeObj.total, decimal)
             let unitFee = 0;
             if (+quantity && totalFee) {
                 unitFee = scMathUtil.roundForObj(totalFee / (+quantity), 2);
             }
+            const estimateItem = orgFees && orgFees.find(item => item.fieldName === 'estimation') || null;
+            const estimateFee = estimateItem ? estimateItem.totalFee : 0;
             return [
                 { fieldName: 'common', totalFee: scMathUtil.roundForObj(feeObj.total, decimal), unitFee },
                 { fieldName: 'building', totalFee: scMathUtil.roundForObj(feeObj.building, decimal) },
                 { fieldName: 'installation', totalFee: scMathUtil.roundForObj(feeObj.installation, decimal) },
                 { fieldName: 'equipment', totalFee: scMathUtil.roundForObj(feeObj.equipment, decimal) },
+                { fieldName: 'estimation', totalFee: estimateFee },
             ];
         }
     },

+ 34 - 0
web/building_saas/budget-summary/js/budgetSummarySetting.js

@@ -105,6 +105,23 @@ const budgetInstallationSetting = {
             hAlign: 2,
             font: "Arial"
         }
+    },{
+        width: 100,
+        head: {
+            titleNames: ["估算总额"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "feesIndex.estimation.totalFee",
+            type: 'number',
+            vAlign: 1,
+            hAlign: 2,
+            font: "Arial"
+        }
     }, {
         width: 140,
         head: {
@@ -366,6 +383,23 @@ const budgetRailSetting = {
             font: "Arial"
         }
     }, {
+        width: 100,
+        head: {
+            titleNames: ["估算总额"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "feesIndex.estimation.totalFee",
+            type: 'number',
+            vAlign: 1,
+            hAlign: 2,
+            font: "Arial"
+        }
+    }, {
         width: 140,
         head: {
             titleNames: ["计算基数"],

+ 75 - 0
web/building_saas/budget-summary/js/budgetSummarySheet.js

@@ -89,6 +89,9 @@ const budgetSummaryObj = (() => {
     'feesIndex.common.totalFee': (node) => {
       return _.get(node, 'data.feesIndex.common.totalFee', '') || '';
     },
+    'feesIndex.estimation.totalFee': (node) => {
+      return _.get(node, 'data.feesIndex.estimation.totalFee', '') || '';
+    },
     'feesIndex.building.totalFee': (node) => {
       return _.get(node, 'data.feesIndex.building.totalFee', '') || '';
     },
@@ -142,6 +145,44 @@ const budgetSummaryObj = (() => {
     }
   };
 
+  // 计算汇总估算总额
+  const calcEstimate = (nodes) => {
+    const dataArr = [];
+    const parentIDs = new Set();
+    nodes.forEach(node => parentIDs.add(node.data.ParentID));
+    const parentNodes = [];
+    parentIDs.forEach(parentID => {
+      const node = tree.findNode(parentID);
+      if (!node) {
+        return;
+      }
+      parentNodes.push(node);
+      if (!node.children || !node.children.length) {
+        return;
+      }
+      let estimateFee = 0;
+      node.children.forEach(child => {
+        const childEstimateItem = child.data.fees && child.data.fees.find(item => item.fieldName === 'estimation') || null;
+        const childEstimateFee = childEstimateItem ? childEstimateItem.totalFee : 0;
+        estimateFee = scMathUtil.roundForObj(estimateFee + childEstimateFee, decimalObj.bills.totalPrice);
+      });
+      const estimateItem = node.data.fees && node.data.fees.find(item => item.fieldName === 'estimation') || null;
+      const orgEstimateFee = estimateItem ? estimateItem.totalFee : 0;
+      if (orgEstimateFee !== estimateFee) {
+        if (estimateItem) {
+          estimateItem.totalFee = estimateFee;
+        } else {
+          node.data.fees.push({ fieldName: 'estimation', totalFee: estimateFee, unitFee: 0 });
+        }
+        dataArr.push({ ID: node.data.ID, fees: node.data.fees });
+      }
+    });
+    if (parentNodes.length) {
+      dataArr.push(...calcEstimate(parentNodes));
+    }
+    return dataArr;
+  };
+
   // 编辑相关
   const edit = async (sheet, changedCells, calcNodes = null) => {
     if (!changedCells.length && !calcNodes) {
@@ -160,6 +201,7 @@ const budgetSummaryObj = (() => {
       }
     }
     let needCalc = false;
+    const calcEstimateNodes = [];
     const nodes = [];
     try {
       $.bootstrapLoading.start();
@@ -187,6 +229,18 @@ const budgetSummaryObj = (() => {
           data[field] = fees;
           node.data[field] = fees;
           node.data.feesIndex = getFeeIndex(node.data.fees);
+        } else if (field === 'feesIndex.estimation.totalFee') {
+          const fees = node.data.fees || [];
+          const feeItem = fees.find(item => item.fieldName === 'estimation');
+          if (feeItem) {
+            feeItem.totalFee = value;
+          } else {
+            fees.push({ fieldName: 'estimation', totalFee: +value, unitFee: 0 });
+          }
+          data.fees = fees;
+          node.data.fees = fees;
+          node.data.feesIndex = getFeeIndex(node.data.fees);
+          calcEstimateNodes.push(node);
         } else {
           data[field] = value;
           node.data[field] = value;
@@ -208,6 +262,7 @@ const budgetSummaryObj = (() => {
           needCalc = true;
         }
       });
+
       calcNodes = calcNodes ? calcNodes : needCalc ? nodes : [];
       // 重算节点
       const dataArr = [];
@@ -221,6 +276,11 @@ const budgetSummaryObj = (() => {
           }
         }
       }
+      // 汇总估算总额
+      if (calcEstimateNodes.length) {
+        dataArr.push(...calcEstimate(calcEstimateNodes));
+      }
+      
       dataArr.forEach(item => {
         delete item.projectID;
         const data = IDMap[item.ID];
@@ -238,6 +298,18 @@ const budgetSummaryObj = (() => {
           if (!node) {
             return;
           }
+          // 处理被计算程序计算冲掉的估算总额
+          const orgData = orgMap[ID];
+          const orgEstimationItem = orgData.fees && orgData.fees.find(item => item.fieldName === 'estimation');
+          const orgEstimationFee = orgEstimationItem ? orgEstimationItem.totalFee : 0;
+          const estimationItem = data.fees && data.fees.find(item => item.fieldName === 'estimation');
+          const estimationFee = estimationItem ? estimationItem.totalFee : 0;
+          if (orgEstimationFee !== estimationFee) {
+            if (!estimationItem) {
+              data.fees.push({ fieldName: 'estimation', totalFee: orgEstimationFee });
+            }
+          }
+          
           // 处理其他费用
           if (node.isBelongToFlags([fixedFlag.CONSTRUCTION_OTHER_FEE])) {
             const fees = data.fees || [];
@@ -369,6 +441,9 @@ const budgetSummaryObj = (() => {
     name(node) {
       return !!(node && (node.getFlag() || node.data.area === BudgetArea.CONSTRUCTION_FEE));
     },
+    'feesIndex.estimation.totalFee'(node) {
+      return !!(!node || node.children.length);
+    },
     'feesIndex.common.unitFee'(node) {
       return !!(node && (node.data.area === BudgetArea.CONSTRUCTION_FEE));
     },