Bläddra i källkod

Merge branch 'budget' of http://192.168.1.41:3000/SmartCost/ConstructionCost into budget

zhangweicheng 4 år sedan
förälder
incheckning
03cad359d3

+ 2 - 0
modules/all_models/bills.js

@@ -13,6 +13,8 @@ let billsSchema = new Schema({
     chapterID: Number,
     billsLibId: Number,
     code: String,
+    chapterCode: String,
+    sectionCode: String,
     fullCode: String,
     type:{type: Number,default:4},//1 :大项费用 2:分部 3分项 4清单;5补项
     isAdd:{type: Number,default:0},//1 true 0 false是否新增

+ 2 - 0
modules/all_models/projects.js

@@ -21,6 +21,8 @@ const ProjectSchema = new Schema({
     "userID": {type:String,index: true},
     "importedByInterface": {type: Boolean, default: false},
     "code": {type: String, default: ''},
+    chapterCode: String,
+    sectionCode: String,
     "name": String,
     "projType": String,
     "recentDateTime": Date,

+ 2 - 2
modules/main/controllers/bills_controller.js

@@ -272,8 +272,8 @@ module.exports = {
     initialBudgetSummary: async function (req, res) {
         const data = JSON.parse(req.body.data);
         try {
-            const bills = await bill_facade.initialBudgetSummary(data.constructionID);
-            callback(req, res, 0, 'success', bills);
+            const rst = await bill_facade.initialBudgetSummary(data.constructionID);
+            callback(req, res, 0, 'success', rst);
         } catch (err) {
             console.log(err);
             callback(req, res, 1, err, null);

+ 11 - 4
modules/main/facade/bill_facade.js

@@ -20,7 +20,7 @@ let bill_Model = require('../models/bills').model;
 let billsLibDao = require("../../bills_lib/models/bills_lib_interfaces");
 const pmFacade = require('../../pm/facade/pm_facade');
 const { getSortedTreeData, getEngineeringFeeType } = require('../../../public/common_util');
-const { billType, constructionFeeNodeID, constructionEquipmentFeeNodeID, BudgetArea, fixedFlag } = require('../../../public/common_constants');
+const { billType, constructionFeeNodeID, constructionEquipmentFeeNodeID, BudgetArea, fixedFlag, BudgetType } = require('../../../public/common_constants');
 const scMathUtil = require('../../../public/scMathUtil').getUtil();
 const uuidV1 = require('uuid/v1');
 const equipmentFacade = require('../../equipment_purchase/facade/equipment_purchase_facade');
@@ -149,10 +149,12 @@ module.exports={
     // 获取概算汇总初始化数据
     initialBudgetSummary: async function (constructionID) {
         const treeData = await this.getBudgetSummary(constructionID);
-        const construction = await projectModel.findOne({ ID: constructionID }, { 'property.costGrowthRate': 1, 'property.growthPeriod': 1 }).lean();
+        const construction = await projectModel.findOne({ ID: constructionID }, { 'property.costGrowthRate': 1, 'property.growthPeriod': 1, 'property.budgetType': 1 }).lean();
         const costGrowthRate = construction && construction.property && construction.property.costGrowthRate || 0;
         const growthPeriod = construction && construction.property && construction.property.growthPeriod || 0;
+        const budgetType = construction && construction.property && construction.property.budgetType || BudgetType.BUILDING;
         return {
+            budgetType,
             treeData,
             costGrowthRate,
             growthPeriod,
@@ -164,13 +166,18 @@ module.exports={
         const task = [];
         for (const constructionID of constructionIDs) {
             task.push(this.getBudgetSummary(constructionID, true));
-            
         }
         const summaryResult = await Promise.all(task);
         summaryResult.forEach(items => {
+            const constructionBudget = items.find(item => item.flags && item.flags[0] && item.flags[0].flag === fixedFlag.CONSTRUCTION_BUDGET);
             items.forEach(item => {
                 if (item.orgProjectID) {
                     map[item.orgProjectID] = item;
+                    if (item.projType === 'Project' && constructionBudget) {
+                        // 建设项目的总价需要取建设项目总概算
+                        map[item.orgProjectID].totalFee = constructionBudget.totalFee;
+                        map[item.orgProjectID].fees = constructionBudget.fees;
+                    }
                 }
             });
         });
@@ -223,7 +230,7 @@ module.exports={
     },
     // 获取工程费用数据,作为概算汇总数据的拼接树数据
     getConstructionFeeData: async function (constructionID, nextID) {
-        const projects = await pmFacade.getPosterityProjects([constructionID], true, { _id: 0, ID: 1, ParentID: 1, NextSiblingID: 1, name: 1, projType: 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, 'property.engineeringName': 1});
         const construction = projects.find(p => p.ID === constructionID);
         const items = getSortedTreeData(construction.ParentID, projects);
         // 转换为uuid

+ 2 - 2
modules/pm/models/project_property_template.js

@@ -4,8 +4,8 @@
 
 //默认的小数位数,用于定义用户可编辑的字段(入库),用户不可编辑的字段在前端defaultDecima._def中定义即可
 const defaultDecimal = {
-    bills: { unitPrice: 2, totalPrice: 2 },
-    ration: { quantity: 4, unitPrice: 2, totalPrice: 2 },
+    bills: { unitPrice: 2, totalPrice: 0 },
+    ration: { quantity: 4, unitPrice: 2, totalPrice: 0 },
     glj: { quantity: 4, unitPriceHasMix: 2, unitPrice: 2 },
     feeRate: 3,
     quantity_detail: 4,

+ 4 - 0
modules/reports/controllers/rpt_controller.js

@@ -314,6 +314,10 @@ async function getAllPagesCommon(construct_id, user_id, prj_id, prj_ids, rpt_id,
                     rptTplDataFacade.prepareMultiProjectData(user_id, prj_ids, filter).then(function(multiRawData) {
                         //终于出来结果了 !_! (multiRawData是多个单位工程的原始数据!)
                         if (multiRawData.length > 0) {
+                            //要排排序,与prj_ids的原始次序一致
+                            multiRawData.sort(function(d1, d2){
+                                return (prj_ids.indexOf(d1.prj.ID) - prj_ids.indexOf(d2.prj.ID));
+                            });
                             //考虑到工料机的数据还需要再计算,所以还不能直接用,需要每个工程都处理一遍后,再合并
                             let tplData = rptDataUtil.assembleData(multiRawData[0]);
                             for (let idx = 1; idx < multiRawData.length; idx++) {

+ 265 - 4
web/building_saas/budget-summary/js/budgetSummarySetting.js

@@ -1,4 +1,5 @@
-const budgetSummaryTreeSetting = {
+// 建筑安装工程
+const budgetInstallationSetting = {
     rowHeaderWidth: 15,
     treeCol: 0,
     emptyRows: 0,
@@ -56,7 +57,7 @@ const budgetSummaryTreeSetting = {
     }, {
         width: 70,
         head: {
-            titleNames: ["量"],
+            titleNames: ["工程总量"],
             spanCols: [1],
             spanRows: [1],
             vAlign: [1],
@@ -73,7 +74,7 @@ const budgetSummaryTreeSetting = {
     }, {
         width: 100,
         head: {
-            titleNames: ["单价"],
+            titleNames: ["技术经济指标"],
             spanCols: [1],
             spanRows: [1],
             vAlign: [1],
@@ -223,4 +224,264 @@ const budgetSummaryTreeSetting = {
         }
     },
     ]
-};
+};
+
+// 轨道工程
+const budgetRailSetting = {
+    rowHeaderWidth: 15,
+    treeCol: 0,
+    emptyRows: 0,
+    headRows: 1,
+    headRowHeight: [40],
+    defaultRowHeight: 21,
+    cols: [{
+        width: 140,
+        head: {
+            titleNames: ["编码"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "code",
+            vAlign: 1,
+            hAlign: 0,
+            font: "Arial"
+        }
+    },{
+        width: 100,
+        head: {
+            titleNames: ["章编号"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "chapterCode",
+            vAlign: 1,
+            hAlign: 0,
+            font: "Arial"
+        }
+    }, {
+        width: 100,
+        head: {
+            titleNames: ["节编号"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "sectionCode",
+            vAlign: 1,
+            hAlign: 0,
+            font: "Arial"
+        }
+    }, {
+        width: 140,
+        head: {
+            titleNames: ["名称"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "name",
+            vAlign: 1,
+            hAlign: 0,
+            font: "Arial"
+        }
+    }, {
+        width: 60,
+        head: {
+            titleNames: ["单位"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "unit",
+            vAlign: 1,
+            hAlign: 1,
+            font: "Arial"
+        }
+    }, {
+        width: 70,
+        head: {
+            titleNames: ["工程总量"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "quantity",
+            type: 'number',
+            vAlign: 1,
+            hAlign: 2,
+            font: "Arial",
+        }
+    }, {
+        width: 100,
+        head: {
+            titleNames: ["技术经济指标"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"],
+        },
+        data: {
+            field: "feesIndex.common.unitFee",
+            type: 'number',
+            vAlign: 1,
+            hAlign: 2,
+            font: "Arial"
+        }
+    }, {
+        width: 100,
+        readOnly: true,
+        head: {
+            titleNames: ["合价"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "feesIndex.common.totalFee",
+            vAlign: 1,
+            hAlign: 2,
+            font: "Arial"
+        }
+    }, {
+        width: 140,
+        head: {
+            titleNames: ["计算基数"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "calcBase",
+            vAlign: 1,
+            hAlign: 0,
+            font: "Arial"
+        }
+    }, {
+        width: 80,
+        head: {
+            titleNames: ["费率(%)"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "feeRate",
+            type: 'number',
+            vAlign: 1,
+            hAlign: 2,
+            font: "Arial"
+        }
+    }, {
+        width: 100,
+        readOnly: true,
+        head: {
+            titleNames: ["建筑工程费"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "feesIndex.building.totalFee",
+            vAlign: 1,
+            hAlign: 2,
+            font: "Arial"
+        }
+    }, {
+        width: 100,
+        readOnly: true,
+        head: {
+            titleNames: ["安装工程费"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "feesIndex.installation.totalFee",
+            vAlign: 1,
+            hAlign: 2,
+            font: "Arial"
+        }
+    }, {
+        width: 100,
+        readOnly: true,
+        head: {
+            titleNames: ["设备购置费"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "feesIndex.equipment.totalFee",
+            vAlign: 1,
+            hAlign: 2,
+            font: "Arial"
+        }
+    }, {
+        width: 80,
+        readOnly: true,
+        head: {
+            titleNames: ["其他费用"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "feesIndex.other.totalFee",
+            vAlign: 1,
+            hAlign: 2,
+            font: "Arial"
+        }
+    }, {
+        width: 140,
+        head: {
+            titleNames: ["备注"],
+            spanCols: [1],
+            spanRows: [1],
+            vAlign: [1],
+            hAlign: [1],
+            font: ["Arial"]
+        },
+        data: {
+            field: "remark",
+            vAlign: 1,
+            hAlign: 0,
+            font: "Arial"
+        }
+    },
+    ]
+};

+ 25 - 3
web/building_saas/budget-summary/js/budgetSummarySheet.js

@@ -1,8 +1,13 @@
+
 /* 建设其他费表格相关 */
 const budgetSummaryObj = (() => {
 
   const { isEmptyVal, isDef, isNumber } = window.commonUtil;
-  const { fixedFlag, BudgetArea } = window.commonConstants;
+  const { fixedFlag, BudgetArea, BudgetType } = window.commonConstants;
+
+  let budgetSummaryTreeSetting;
+
+  let curBudgetType = BudgetType.BUILDING;
 
   // 原始数据
   let rawData = [];
@@ -231,7 +236,9 @@ const budgetSummaryObj = (() => {
               fees.push({ fieldName: 'other', totalFee: commonFeeItem && commonFeeItem.totalFee || 0 });
             }
           }
-          bulkData.push({ type: 'update', data: { ID, ...data } });
+          const actualID = node.data.area === BudgetArea.CONSTRUCTION_FEE ? node.data.orgProjectID : ID;
+          const updateType = node.data.area === BudgetArea.CONSTRUCTION_FEE ? 'updateProject' : 'update';
+          bulkData.push({ type: updateType, data: { ...data, ID: actualID } });
         });
       await bulkOperation(bulkData);
       Object
@@ -369,6 +376,19 @@ const budgetSummaryObj = (() => {
       }
       const endIndex =  constructionFeeNode.posterityCount() + 1;
       sheet.getRange(0, 0, endIndex, budgetSummaryTreeSetting.cols.length, GC.Spread.Sheets.SheetArea.viewport).locked(true);
+      // 除第一行,章编号 节编号可编辑
+      if (curBudgetType === BudgetType.RAIL) {
+        const chapterCodeCol = budgetSummaryTreeSetting.cols.findIndex(item => item.data.field === 'chapterCode');
+        const sectionCodeCol = budgetSummaryTreeSetting.cols.findIndex(item => item.data.field === 'sectionCode');
+        for (let row = 1; row < endIndex; row++) {
+          if (chapterCodeCol > -1) {
+            sheet.getCell(row, chapterCodeCol).locked(false);
+          }
+          if (sectionCodeCol > -1) {
+            sheet.getCell(row, sectionCodeCol).locked(false);
+          }
+        }
+      }
       return endIndex;
     }
     if (isMass) {
@@ -689,7 +709,9 @@ const budgetSummaryObj = (() => {
       $.bootstrapLoading.start();
       // 得先计算费用汇总(概算汇总计算基于费用汇总算出来的总金额)
       await projectObj.project.calcProgram.getGatherFeeData();
-      const { treeData, costGrowthRate, growthPeriod } = await ajaxPost('/bills/initialBudgetSummary', { constructionID });
+      const { budgetType, treeData, costGrowthRate, growthPeriod } = await ajaxPost('/bills/initialBudgetSummary', { constructionID });
+      budgetSummaryTreeSetting = budgetType === BudgetType.BUILDING ? budgetInstallationSetting : budgetRailSetting;
+      curBudgetType = budgetType;
       calcSetting.costGrowthRate = costGrowthRate;
       calcSetting.growthPeriod = growthPeriod;
       $('#costGrowthRate').val(costGrowthRate);

+ 2 - 2
web/building_saas/main/html/gather_fees.html

@@ -14,10 +14,10 @@
 
     <div class="container-fluid">
         <div class="row">
-            <div class="col-lg-2 p-0">
+            <div class="col-lg-3 p-0">
                 <div class="grid main-data-full" id="gfMainSpread"></div>
             </div>
-            <div class="col-lg-10 p-0">
+            <div class="col-lg-9 p-0">
                 <div class="grid main-data-full" id="gfDetailSpread"></div>
             </div>
         </div>

+ 9 - 6
web/building_saas/main/js/views/gather_fees_view.js

@@ -7,7 +7,7 @@ let gatherFeesView = {
     mainSetting: {
         header:[
             // {headerName:"ID",headerWidth:80,dataCode:"ID", hAlign: "center"},
-            {headerName:"费用类别",headerWidth:120,dataCode:"name", dataType: "String"},
+            {headerName:"费用类别",headerWidth:160,dataCode:"name", dataType: "String"},
             {headerName:"金额",headerWidth:80,dataCode:"totalFee", dataType: "String",hAlign: "right"}
         ],
         view:{
@@ -94,12 +94,15 @@ let gatherFeesView = {
       $('#lblGatherFee').text(`费用汇总 ${obj.totalFee}`);
       sheetCommonObj.showData(me.mainSheet, me.mainSetting, me.datas);
       me.mainSheet.setRowCount(me.datas.length);
-      sheetCommonObj.showData(me.detailSheet, me.detailSetting, me.datas[0].calcItems);
-      me.getfeeRateColor(me.datas[0].calcItems);
-      customRowHeader(me.detailSheet, me.datas[0].calcItems.length);
 
-      let count = gatherFeesView.datas[gatherFeesView.mainSheet.getActiveRowIndex()].calcItems.length;
-      gatherFeesView.detailSheet.setRowCount(count, GC.Spread.Sheets.SheetArea.viewport);
+      let count = 0;
+      if (me.datas.length > 0){
+          sheetCommonObj.showData(me.detailSheet, me.detailSetting, me.datas[0].calcItems);
+          me.getfeeRateColor(me.datas[0].calcItems);
+          customRowHeader(me.detailSheet, me.datas[0].calcItems.length);
+          count = me.datas[me.mainSheet.getActiveRowIndex()].calcItems.length;
+      }
+      me.detailSheet.setRowCount(count, GC.Spread.Sheets.SheetArea.viewport);
       $.bootstrapLoading.end();
     },
     onMainEnterCell: function(sender, args) {

+ 1 - 1
web/building_saas/pm/js/pm_newMain.js

@@ -3047,7 +3047,7 @@ function initProjects(callback, expandCallback) {
             sheet.frozenColumnCount(2);
             sheet.name('projectSheet');
             sheetCommonObj.spreadDefaultStyle(projTreeObj.workBook);
-            projTreeObj.sumEngineeringCost();
+            //projTreeObj.sumEngineeringCost();
             if (expandCallback) {
                 expandCallback();
             } else {