Browse Source

Merge branch 'master' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost

zhongzewei 7 years atrás
parent
commit
c794fc62ec

+ 11 - 0
modules/glj/models/glj_list_model.js

@@ -109,6 +109,7 @@ class GLJListModel extends BaseModel {
                 projectGLJIDList: gljIdList
             };
             let quantityData = await RationGLJFacade.getQuantityByProjectGLJ(condition);
+            let rationTypeQuantity = await RationGLJFacade.getRationTypeGLJQuantity(projectId);
             let quantityList = {};
             // 整理数据 得到总定额消耗量
             for (let tmp of quantityData) {
@@ -122,6 +123,16 @@ class GLJListModel extends BaseModel {
                     quantityList[tmp_con_key] = scMathUtil.roundTo(quantityList[tmp_con_key]+tmp.quantity * tmpNum,-quantity_decimal);
                 }
             }
+            //计算定额类型工料机的消耗量
+            for(let rq of rationTypeQuantity){
+                let rq_key = keyMap[rq.projectGLJID];
+                let rq_quantity= scMathUtil.roundForObj(rq.quantity,quantity_decimal);
+                if(quantityList[rq_key] === undefined){
+                    quantityList[rq_key] =  scMathUtil.roundTo(rq_quantity,-quantity_decimal);
+                }else {
+                    quantityList[rq_key] = scMathUtil.roundTo(quantityList[rq_key]+rq_quantity,-quantity_decimal);
+                }
+            }
             // 整理获取有组成物的项目工料机的数据
             let connect_keys = [];
             for(let tmp of gljData) {

+ 18 - 16
modules/main/facade/quantity_detail_facade.js

@@ -112,9 +112,7 @@ async function updateRegex(datas) {
     await quantity_detail_model.bulkWrite(generateUpdateTaks(updateTasks));
     resultObjec.refreshList=updateTasks;
     if(datas.query.refreshQuantity==true){
-        let data = {};
-        data.quantity = await summateResults(datas.query,detailList,decimal);
-        data.isFromDetail = 1;
+        let data = await summateResults(datas.query,detailList,decimal);
         node.data = data;
         resultObjec.node = node;
     }
@@ -259,9 +257,7 @@ async function insertRecodeWithReg (doc) {
         let newRecord = await quantity_detail_model.create(doc) ;
         detailList.push(newRecord);
         if(refreshQuantity==true){
-            let data = {};
-            data.quantity = await summateResults(doc,detailList,decimal);
-            data.isFromDetail = 1;
+            let data = await summateResults(doc,detailList,decimal);
             returnObjec.node.data = data;
         }
         returnObjec.newRecord = newRecord;
@@ -283,9 +279,7 @@ async function doIsSummationUpdate(query,doc) {
     await quantity_detail_model.update(query,doc);
     let detailList = await getDatailList(query,returnObjec);
     if(refreshQuantity==true){
-        let data = {};
-        data.quantity = await summateResults(query,detailList,decimal);
-        data.isFromDetail = 1;
+        let data = await summateResults(query,detailList,decimal);
         returnObjec.node.data = data;
     }
     return returnObjec;
@@ -331,6 +325,7 @@ function updateReferenceRecode(index,detailList,updateTasks) {
 
 async function summateResults (query,detailList,decimal) {
     let quantity = 0;
+    let doc = {};
      decimal = decimal?decimal:await decimal_facade.getProjectDecimal(query.projectID);
     for(let d of detailList){
         if(d.isSummation==1){
@@ -340,17 +335,25 @@ async function summateResults (query,detailList,decimal) {
     }
     if(query.hasOwnProperty('rationID')){
         let ration = await  ration_model.findOne({'ID':query.rationID,'projectID':query.projectID,deleteInfo: null});
+        let bill = await bill_model.findOne({'projectID':query.projectID,deleteInfo: null,"ID":ration.billsItemID});
+        let bill_decimal = await decimal_facade.getBillsQuantityDecimal(query.projectID,bill.unit);
+        let bill_quantity = scMathUtil.roundForObj(bill.quantity,bill_decimal);
+        let contain = scMathUtil.roundForObj(quantity/bill_quantity,decimal.process);
+        let r_quantity = quantity;
         quantity = getQuantityByUnit(quantity,ration.unit);
         quantity = scMathUtil.roundTo(quantity, -decimal.ration.quantity);
-        await ration_model.update({'ID':query.rationID,'projectID':query.projectID,deleteInfo: null},{quantity:quantity,isFromDetail:1});
+        doc={quantity:quantity,isFromDetail:1,quantityEXP:'GCLMXHJ',contain:contain};
+        await ration_model.update({'ID':query.rationID,'projectID':query.projectID,deleteInfo: null},doc);
+        doc.r_quantity = r_quantity;
     }else {
         let bill = await bill_model.findOne({'ID':query.billID,'projectID':query.projectID,deleteInfo: null});
         decimal = await decimal_facade.getBillsQuantityDecimal(query.projectID,bill.unit);
-        quantity = getQuantityByUnit(quantity,bill.unit);
+       // quantity = getQuantityByUnit(quantity,bill.unit);
         quantity = scMathUtil.roundTo(quantity, -decimal);
-        await bill_model.update({'ID':query.billID,'projectID':query.projectID,deleteInfo: null},{quantity:quantity,isFromDetail:1});
+        doc = {quantity:quantity,isFromDetail:1};
+        await bill_model.update({'ID':query.billID,'projectID':query.projectID,deleteInfo: null},doc);
     }
-    return quantity
+    return doc
 }
 
 function getQuantityByUnit(quantity,unit) {
@@ -476,9 +479,8 @@ async function deleteRecode(doc) {
     await quantity_detail_model.deleteOne({ID:doc.ID,projectID:doc.projectID});
     _.remove(quantity_detail_List,{ID:doc.ID,projectID:doc.projectID});
 
-    let n_data = {};//更新节点信息
-    n_data.quantity = await summateResults(query,quantity_detail_List,decimal);
-    n_data.isFromDetail = 1;
+    //更新节点信息
+    let n_data = await summateResults(query,quantity_detail_List,decimal);
     resultObject.node.data = n_data;
 
     let r_data ={

+ 1 - 0
modules/main/models/bills.js

@@ -23,6 +23,7 @@ let billsSchema = new Schema({
     chapterID: Number,
     code: String,
     fullCode: String,
+    type:Number,
     name: String,
     unit: String,
     quantity: String, // Decimal

+ 1 - 0
modules/main/models/ration.js

@@ -38,6 +38,7 @@ let rationSchema = new Schema({
     unit: String,
     quantity: String,
     contain:String,//含量
+    quantityEXP:String,//工程量表达式
     programID: Number,
     marketUnitFee: String,
     marketTotalFee: String,

+ 7 - 1
modules/ration_glj/facade/ration_glj_facade.js

@@ -37,7 +37,8 @@ module.exports = {
     mReplaceGLJ: mReplaceGLJ,
     updateRationGLJByEdit: updateRationGLJByEdit,
     getGLJClass: getGLJClass,
-    insertGLJAsRation: insertGLJAsRation
+    insertGLJAsRation: insertGLJAsRation,
+    getRationTypeGLJQuantity:getRationTypeGLJQuantity
 }
 
 let operationMap = {
@@ -765,6 +766,11 @@ async function insertGLJAsRation(data) {
     return gljList;
 }
 
+async function  getRationTypeGLJQuantity(projectID) {
+    let rations = await ration.find({'projectID': projectID,'type':3,'deleteInfo': null}, ['ID', 'projectGLJID','quantity']);
+    return rations;
+}
+
 async function changAdjustState(data, rationList) {
     let stateList = [];
     for (let r of rationList) {

+ 1 - 0
modules/ration_glj/models/ration_glj_temp.js

@@ -50,6 +50,7 @@ let rationSchema = new Schema({
     unit: String,
     quantity: String,
     contain:String,//含量
+    quantityEXP:String,//工程量表达式
     programID: Number,
     marketUnitFee: String,
     marketTotalFee: String,

+ 8 - 1
public/web/tree_sheet/tree_sheet_helper.js

@@ -131,6 +131,10 @@ var TREE_SHEET_HELPER = {
                     }
                     return data;
                 };
+                if(colSetting.data.field=="quantity"){
+                    let tag = node.data.quantityEXP?node.data.quantityEXP:'';
+                    sheet.setTag(iRow, iCol,tag);
+                }
                 if (colSetting.data.getText && Object.prototype.toString.apply(colSetting.data.getText) === "[object Function]") {
                     cell.value(colSetting.data.getText(node));
                 } else {
@@ -317,7 +321,9 @@ var TREE_SHEET_HELPER = {
         TipCellType.prototype.processMouseEnter = function (hitinfo) {
             let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
             let tag = hitinfo.sheet.getTag(hitinfo.row, hitinfo.col);
-            if(tag !== undefined && tag) {
+            if(setting.cols[hitinfo.col].data.field=="quantity"){
+                text = tag;
+            }else if(tag !== undefined && tag) {
                 text = tag;
             }
             if (setting.pos && text && text !== '') {
@@ -356,6 +362,7 @@ var TREE_SHEET_HELPER = {
                 sheet.defaults.rowHeight = setting.defaultRowHeight;
             }
             sheet.setRowCount(tree.count() + setting.emptyRows, GC.Spread.Sheets.SheetArea.viewport);
+            sheet.getRange(tree.count(), -1, setting.emptyRows, -1).locked(true);
             setting.cols.forEach(function (colSetting, iCol) {
                 sheet.setStyle(-1, iCol, TREE_SHEET_HELPER.getSheetCellStyle(colSetting));
                 if (colSetting.showHint) {

+ 1 - 0
web/building_saas/glj/js/project_glj.js

@@ -417,6 +417,7 @@ function filterProjectGLJ(jsonData) {
     return jsonData;
 }
 
+
 function sortProjectGLJ(jsonData) {
     if (jsonData.length > 0) {
         jsonData = _.sortByAll(jsonData, [function (item) {

+ 3 - 0
web/building_saas/glj/js/project_glj_spread.js

@@ -48,6 +48,9 @@ ProjectGLJSpread.prototype.init = function () {
         {name: 'ID', field: 'id', visible: false},
         {name: '类型', field: 'unit_price.type', visible: false},
         {name: '总消耗量', field: 'quantity', visible: true,width:100,decimalField:'glj.quantity'},
+        {name: '总消耗量', field: 'quantity', visible: true,width:100,decimalField:'glj.quantity'},
+        {name: '分部分项总消耗量', field: 'subdivisionQuantity', visible: true,width:100,decimalField:'glj.quantity'},
+        {name: '技术措施项目总消耗量', field: 'techQuantity', visible: true,width:100,decimalField:'glj.quantity'},
         {name: '定额价', field: "base_price", visible: true,width:70,decimalField:"glj.unitPrice",validator: 'number'},//这里feiedID设置是为了在计不计取价差的时候做显示用
         {name: '调整价', field: 'adjust_price', visible: true,width:70,decimalField:"glj.unitPrice"},
         {name: '市场价', field: "unit_price.market_price", visible: true, validator: 'number',width:70,decimalField:"glj.unitPrice"},

+ 1 - 1
web/building_saas/main/html/main.html

@@ -557,7 +557,7 @@
     </div>    
     <!--弹出列设置-->
     <div class="modal fade" id="column" data-backdrop="static">
-        <div class="modal-dialog modal-lg" role="document">
+        <div class="modal-dialog modal-lg" role="document" style="width: 350px;">
             <div class="modal-content">
                 <div class="modal-header">
                     <h5 class="modal-title"><i class="fa fa-table"></i> 列设置</h5>

+ 0 - 49
web/building_saas/main/js/calc/calc_fees.js

@@ -1,38 +1,6 @@
 /**
  * Created by Mai on 2017/7/21.
  */
-
-let feeType = [
-    // {type: 'common', name: '工程造价'},
-    // {type: 'baseLabour', name: '基价人工费'},
-    // {type: 'material', name: '材料费'},
-    // {type: 'machine', name: '机械费'},
-    // {type: 'rationDirect', name: '定额直接费'},
-    // {type: 'manage', name: '企业管理费'},
-    // {type: 'profit', name: '利润'},
-    // {type: 'risk', name: '风险费'},
-
-// 以下标准由缪佩玲提供
-    {type: 'direct', name: '直接费'},
-    {type: 'labour', name: '人工费'},
-    {type: 'material', name: '材料费'},
-    {type: 'machine', name: '机械费'},
-    {type: 'mainMaterial', name: '主材费'},
-    {type: 'equipment', name: '设备费'},
-    {type: 'manage', name: '企业管理费'},
-    {type: 'profit', name: '利润'},
-    {type: 'risk', name: '风险费'},
-    {type: 'labourDiff', name: '人工价差'},
-    {type: 'materialDiff', name: '材料价差'},
-    {type: 'machineDiff', name: '机械价差'},
-    {type: 'common', name: '工程造价'},
-    {type: 'adjustLabour', name: '调整人工费'},
-    {type: 'adjustMachineLabour', name: '调整机上人工费'},
-    {type: 'zangu', name: '暂估'},
-    // 模拟用户新增
-    {type: 'fee1', name: '甲供材料费'}
-];
-
 let calcFees = {
     findFee: function (data, fieldName) {
         if (!data.fees) {
@@ -107,22 +75,5 @@ let calcFees = {
                 };
             }
         }
-    },
-    // CSL,2017.08.28
-    feeTypeToName: function (type) {
-        for (let ft of feeType) {
-            if (ft.type === type) {
-                return ft.name;
-            };
-        };
-    },
-
-    feeNameToType: function (name) {
-        for (let ft of feeType) {
-            if (ft.name === name) {
-                return ft.type;
-            };
-        };
-        return '';
     }
 }

+ 12 - 1
web/building_saas/main/js/controllers/project_controller.js

@@ -23,7 +23,6 @@ ProjectController = {
     },
     addBills: function (project, sheetController, std) {
         if (!project || !sheetController) { return null; }
-
         let target = project.getParentTarget(project.mainTree.selected, 'sourceType', project.Bills.getSourceType());
         let newSource = null, newNode = null, parentID, nextSiblingID;
         if (target) {
@@ -54,6 +53,18 @@ ProjectController = {
             this.syncDisplayNewNode(sheetController, newNode);
         }
     },
+    addRootBill:function (project, sheetController) {//添加大项费用
+        let newSource = null, newNode = null
+        newSource = project.Bills.insertBills(-1, project.mainTree.selected.source.getNextSiblingID(),true);
+        newNode = project.mainTree.insert(-1, project.mainTree.selected.getNextSiblingID());
+        if (newNode) {
+            newNode.source = newSource;
+            newNode.sourceType = project.Bills.getSourceType();
+            newNode.data = newSource.data;
+            this.syncDisplayNewNode(sheetController, newNode);
+        }
+
+    },
     addRation: function (project, sheetController, rationType, std) {
         if (!project || !sheetController) { return; }
 

+ 57 - 4
web/building_saas/main/js/models/bills.js

@@ -118,7 +118,7 @@ var Bills = {
 
         // 提交数据后的错误处理方法
         bills.prototype.doAfterUpdate = function(err, data){
-            console.log(data)
+            // console.log(data)
             if(data.quantityRefresh){
                 this.refreshDatas(data,'quantity');
             }
@@ -151,11 +151,14 @@ var Bills = {
             return updateData;
         };
 
-        bills.prototype.insertBills = function (parentId, nextSiblingId) {
+        bills.prototype.insertBills = function (parentId, nextSiblingId,isUserAdd) {//是否是用户新增的
             var insertData = this.tree.getInsertData(parentId, nextSiblingId);
             var that = this, newData = null;
             insertData.forEach(function (data) {
                 if (data.type === idTree.updateType.new) {
+                    if(isUserAdd==true){//如果是用户新增的,类型为1
+                        data.data.type = 1;
+                    }
                     newData = data.data;
                 }
             });
@@ -328,7 +331,6 @@ var Bills = {
             this.project.pushNow('replaceBills', this.getSourceType(), updateData);
             return node;            
         };
-
         bills.prototype.sameStdCodeBillsData = function (stdCode) {
             let reg = new RegExp('^' + stdCode);
             for (let data of this.datas) {
@@ -337,8 +339,59 @@ var Bills = {
                 }
             }
             return null;            
-        }
+        };
+
+        bills.prototype.getSubdivisionProjectLeavesID=function () {//取所有分部分项工程清单叶子节点ID
+            let roots = projectObj.project.mainTree.roots;//所有根节点
+            let subdivisionNode = null;
+            for(let r of roots){
+               if(isFlag(r.data)&&r.data.flagsIndex.fixed.flag==fixedFlag.SUB_ENGINERRING) {
+                   subdivisionNode = r;
+                   break;
+               }
+            }
+            let nodes = this.getLeavesBillNodes(subdivisionNode);
+            return  _.map(nodes,"data.ID");
+        };
+
+
+        bills.prototype.getTechLeavesID=function () {//取所有分计算技术措施项目清单叶子节点ID
+            let items = projectObj.project.mainTree.roots;//所有节点;
+            let techNode = null;
+            for(let item of items){
+                if(isFlag(item.data)&&item.data.flagsIndex.fixed.flag==fixedFlag.CONSTRUCTION_TECH){
+                    techNode = item;
+                    break;
+                }
+            }
+            let nodes = this.getLeavesBillNodes(techNode);
+            return  _.map(nodes,"data.ID");
+        };
 
+        bills.prototype.getLeavesBillNodes = function (rnode) {//取该节点下的所有清单叶子节点
+            let leaves = [];
+            getLeaves(rnode,leaves);
+            return leaves;
+
+            function  getLeaves(node,children) {
+                if(node){
+                    if(node.source.children.length>0){
+                        for(let c of node.children){
+                            getLeaves(c,children)
+                        }
+                    }else {
+                        children.push(node);
+                    }
+                }
+            }
+        };
         return new bills(project);
     }
 };
+function isDef(v) {
+    return v !== undefined && v !== null;
+}
+
+function isFlag(v) {
+    return this.isDef(v.flagsIndex) && this.isDef(v.flagsIndex.fixed);
+}

+ 0 - 1
web/building_saas/main/js/models/cache_tree.js

@@ -380,7 +380,6 @@ var cacheTree = {
             }
             return success;
         };
-
         return new Tree(owner);
     }
 };

+ 1 - 41
web/building_saas/main/js/models/calc_base.js

@@ -1,47 +1,7 @@
 /**
  * Created by Zhong on 2017/11/28.
  */
-//清单固定行
-const fixedFlag = {
-    // 分部分项工程
-    SUB_ENGINERRING: 1,
-    // 措施项目
-    MEASURE: 2,
-    // 施工技术措施项目
-    CONSTRUCTION_TECH: 3,
-    // 安全文明施工按实计算费用
-    SAFETY_CONSTRUCTION_ACTUAL: 4,
-    // 施工组织措施专项费用
-    CONSTRUCTION_ORGANIZATION: 5,
-    // 安全文明施工专项费用
-    SAFETY_CONSTRUCTION: 6,
-    // 其他项目
-    OTHER: 7,
-    // 暂列金额
-    PROVISIONAL: 8,
-    // 暂估价
-    ESTIMATE: 9,
-    // 材料(工程设备)暂估价
-    MATERIAL_PROVISIONAL: 10,
-    // 专业工程暂估价
-    ENGINEERING_ESITIMATE: 11,
-    // 计日工
-    DAYWORK: 12,
-    // 总承包服务费
-    TURN_KEY_CONTRACT: 13,
-    // 索赔与现场签证
-    CLAIM_VISA: 14,
-    // 规费
-    CHARGE: 15,
-    // 社会保险费及住房公积金 Social insurance fee and housing accumulation fund
-    SOCIAL_INSURANCE_HOUSING_FUND: 16,
-    // 工程排污费 charges for disposing pollutants
-    POLLUTANTS: 17,
-    // 税金
-    TAX: 18,
-    //工程造价
-    ENGINEERINGCOST: 19
-};
+
 
 let cbTools = {
     isDef: function (v) {

+ 80 - 32
web/building_saas/main/js/models/calc_program.js

@@ -150,6 +150,27 @@ let rationCalcBase = [
     }
 ];
 
+let cpFeeTypes = [
+    {type: 'direct', name: '直接费'},
+    {type: 'labour', name: '人工费'},
+    {type: 'material', name: '材料费'},
+    {type: 'machine', name: '机械费'},
+    {type: 'mainMaterial', name: '主材费'},
+    {type: 'equipment', name: '设备费'},
+    {type: 'manage', name: '企业管理费'},
+    {type: 'profit', name: '利润'},
+    {type: 'risk', name: '风险费'},
+    {type: 'labourDiff', name: '人工价差'},
+    {type: 'materialDiff', name: '材料价差'},
+    {type: 'machineDiff', name: '机械价差'},
+    {type: 'adjustLabour', name: '调整人工费'},
+    {type: 'adjustMachineLabour', name: '调整机上人工费'},
+    {type: 'zangu', name: '暂估'},
+    {type: 'fee1', name: '甲供材料费'},
+    // 模拟用户新增
+    {type: 'common', name: '工程造价'}
+];
+
 let analyzer = {
     calcTemplate: null,
     success: true,
@@ -363,7 +384,7 @@ let executeObj = {
                 };
                 return result;
             };
-            // 量价没有具体的工料机类型,但仍然要用定额的计算程序,所以要给计算基数直接指定。
+            // 量价没有具体的工料机类型,但仍然要用定额的计算程序,所以要给计算基数直接指定。
             function volumePriceFee() {
                 let result = 0;
                 if (
@@ -399,6 +420,39 @@ let executeObj = {
     }
 };
 
+let treeNodeTools = {
+    // 获取全部有公式的树节点清单
+    getFormulaNodes: function () {
+        let nodes = [];
+        for (let node of projectObj.project.mainTree.items){
+              if (node.sourceType == ModuleNames.bills && node.data.calcBase && node.data.calcBase != '') nodes.push(node);
+        };
+        return nodes;
+    },
+
+    isRation: function(treeNode){
+        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.ration;
+    },
+
+    isLeafBill: function(treeNode){
+        return treeNode.sourceType === projectObj.project.Bills.getSourceType() &&
+            treeNode.source.children &&
+            treeNode.source.children.length === 0;
+    },
+
+    isNullBill: function (treeNode) {
+        return this.isLeafBill(treeNode) && (treeNode.children.length === 0) && (!treeNode.data.calcBase);
+    },
+
+    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;
+    }
+};
+
 class CalcProgram {
     constructor(project){
         let me = this;
@@ -437,7 +491,7 @@ class CalcProgram {
 
         me.feeRates = this.project.FeeRate.datas.rates;
         me.labourCoes = this.project.labourCoe.datas.coes;
-        me.feeTypes = feeType;
+        me.feeTypes = cpFeeTypes;
         me.calcBases = rationCalcBase;
         me.templates = this.project.calcProgram.datas.templates;
 
@@ -594,30 +648,6 @@ class CalcProgram {
         };
     };
 
-    isLeafBill(treeNode){
-        let me = this;
-        return treeNode.sourceType === me.project.Bills.getSourceType() &&
-               treeNode.source.children &&
-               treeNode.source.children.length === 0;
-    };
-
-    isNullBill(treeNode){
-        let me = this;
-        return me.isLeafBill(treeNode) && (treeNode.children.length ===0) && (!treeNode.data.calcBase);
-    };
-
-    isRation(treeNode){
-        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.ration;
-    };
-
-    isVolumePrice(treeNode){
-        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.volumePrice;
-    };
-
-    isGljRation(treeNode){
-        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.gljRation;
-    };
-
     initFeeField(treeNode, fieldName){
         if (!treeNode.data.fees) {
             treeNode.data.fees = [];
@@ -688,7 +718,7 @@ class CalcProgram {
 
             let objsArr = (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees) ? project.Ration.getRationsByNode(treeNode) : treeNode.children;
             let rst = [];
-            for (let ft of feeType) {
+            for (let ft of cpFeeTypes) {
                 let ftObj = {};
                 ftObj.fieldName = ft.type;
                 ftObj.name = ft.name;
@@ -782,7 +812,9 @@ class CalcProgram {
             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;
+            // 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;
             let uf = (b * f * q / 100).toDecimal(decimalObj.bills.unitPrice);
             let tuf = uf;
@@ -869,10 +901,10 @@ class CalcProgram {
         if (isRation){
             treeNode.calcType = treeNodeCalcType.ctRationCalcProgram;
         }
-        else  if (me.isNullBill(treeNode)){
+        else  if (treeNodeTools.isNullBill(treeNode)){
             treeNode.calcType = treeNodeCalcType.ctCommonUnitFee;
         }
-        else if (me.isLeafBill(treeNode)) {
+        else if (treeNodeTools.isLeafBill(treeNode)) {
             if (treeNode.children && treeNode.children.length > 0){
                 // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机)
                 if (me.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
@@ -933,7 +965,9 @@ class CalcProgram {
                     fees: node.data.fees,
                     isFromDetail:node.data.isFromDetail,
                     feeRate: node.data.feeRate,
-                    feeRateID: node.data.feeRateID
+                    feeRateID: node.data.feeRateID,
+                    contain:node.data.contain,
+                    quantityEXP:node.data.quantityEXP
                 };
                 if(node.sourceType==ModuleNames.ration && node.data.type==rationType.gljRation){//定额类型的工料机做特殊处理
                     data.code=node.data.code;
@@ -982,10 +1016,24 @@ class CalcProgram {
         return changedNodes;
     };
 
+    // 计算全部公式项
+    calcFormulaNodes(){
+        let nodes = treeNodeTools.getFormulaNodes();
+        if (nodes.length == 0) return;
+        for (let node of nodes){
+              this.calcFormulaNode(node);
+        };
+    };
+
+    // 计算公式项。(它一定是叶子结点,它的父结点一定没有公式)
+    calcFormulaNode(treeNode){
+        // do
+    };
+
     // 计算叶子清单下的所有子结点(如定额、量价、工料机定额等), 并计算自身和所有父结点。最后打包存储。
     calcLeafAndSave(treeNode){
         let me = this;
-        if(!me.isLeafBill(treeNode)) return;
+        if(!treeNodeTools.isLeafBill(treeNode)) return;
         if (treeNode.children && treeNode.children.length > 0) {
             let changedNodes = [];
             for (let child of treeNode.children){

+ 43 - 3
web/building_saas/main/js/models/main_consts.js

@@ -11,7 +11,6 @@ const ModuleNames = {
     ration_coe:'ration_coe',
     ration_ass:'ration_ass',
     quantity_detail:'quantity_detail',
-    // volume_price: 'volume_price',
     labour_coe: 'labour_coe',
     calc_program: 'calc_program'
 };
@@ -114,7 +113,6 @@ const volumePriceMaps = {
     5: "量设"
 };
 
-
 const rationType = {
     ration: 1,
     volumePrice: 2,
@@ -133,5 +131,47 @@ const zanguCalcType = {
     gatherMaterial: 1
 };
 
+//清单固定行
+const fixedFlag = {
+    // 分部分项工程
+    SUB_ENGINERRING: 1,
+    // 措施项目
+    MEASURE: 2,
+    // 施工技术措施项目
+    CONSTRUCTION_TECH: 3,
+    // 安全文明施工按实计算费用
+    SAFETY_CONSTRUCTION_ACTUAL: 4,
+    // 施工组织措施专项费用
+    CONSTRUCTION_ORGANIZATION: 5,
+    // 安全文明施工专项费用
+    SAFETY_CONSTRUCTION: 6,
+    // 其他项目
+    OTHER: 7,
+    // 暂列金额
+    PROVISIONAL: 8,
+    // 暂估价
+    ESTIMATE: 9,
+    // 材料(工程设备)暂估价
+    MATERIAL_PROVISIONAL: 10,
+    // 专业工程暂估价
+    ENGINEERING_ESITIMATE: 11,
+    // 计日工
+    DAYWORK: 12,
+    // 总承包服务费
+    TURN_KEY_CONTRACT: 13,
+    // 索赔与现场签证
+    CLAIM_VISA: 14,
+    // 规费
+    CHARGE: 15,
+    // 社会保险费及住房公积金 Social insurance fee and housing accumulation fund
+    SOCIAL_INSURANCE_HOUSING_FUND: 16,
+    // 工程排污费 charges for disposing pollutants
+    POLLUTANTS: 17,
+    // 税金
+    TAX: 18,
+    //工程造价
+    ENGINEERINGCOST: 19
+};
+
 const gljKeyArray =['code','name','specs','unit','type'];
-const gljLibKeyArray =['code', 'name', 'specs', 'unit', 'gljType']
+const gljLibKeyArray =['code', 'name', 'specs', 'unit', 'gljType'];

+ 95 - 2
web/building_saas/main/js/models/project_glj.js

@@ -41,6 +41,7 @@ ProjectGLJ.prototype.loadData = function (callback = null) {
                 return false;
             }
             self.datas = response.data;
+            self.calcQuantity();
             // 回调函数
             if (callback !== null) {
                 callback(response.data);
@@ -157,8 +158,10 @@ ProjectGLJ.prototype.updatePriceFromRG = function (recode, updateField, newval)
 };
 
 ProjectGLJ.prototype.updatePropertyFromMainSpread = function (node, updateField, newval) {
-    if (updateField == "contain") {
-
+    if (updateField == "contain") {//更新含量和工程量时,要走定额更新的逻辑
+        projectObj.project.Ration.updateContain(newval,node);
+    }if(updateField == "quantity"){
+        projectObj.project.quantity_detail.editMainTreeNodeQuantity(newval,node,updateField);
     } else {
         this.updateGLJProperty(node, updateField, newval);
     }
@@ -394,3 +397,93 @@ ProjectGLJ.prototype.getShortNameByID = function (ID) {
     let gljTypeMap = this.datas.constData.gljTypeMap;
     return gljTypeMap["typeId" + ID].shortName;
 }
+
+ProjectGLJ.prototype.calcQuantity  = function (){
+    let project_gljs = this.datas.gljList;
+    let mixRatioConnectData = this.datas.mixRatioConnectData;
+    let mixRatioSubdivisionMap = {};
+    let mixRatioTechMap={};
+    for(let pglj of project_gljs ){
+        if(pglj.quantity !== 0 && pglj.quantity !== '0'){
+            let result = this.getQuantityPerGLJ(pglj,mixRatioSubdivisionMap,mixRatioTechMap);
+            pglj.subdivisionQuantity = result.subdivisionQuantity;
+            pglj.techQuantity = result.techQuantity;
+        }
+    }
+    //计算做为组成物的消耗量
+    for(let pg of project_gljs ){
+        if(pg.quantity !== 0 && pg.quantity !== '0'){
+            let pg_index = gljOprObj.getIndex(pg,gljKeyArray);
+            if(mixRatioConnectData[pg_index]){
+                if(mixRatioSubdivisionMap[pg_index]){
+                    pg.subdivisionQuantity = scMathUtil.roundForObj(mixRatioSubdivisionMap[pg_index]+pg.subdivisionQuantity,getDecimal("glj.quantity"));
+                }
+                if(mixRatioTechMap[pg_index]){
+                    pg.techQuantity = scMathUtil.roundForObj(mixRatioTechMap[pg_index]+pg.techQuantity,getDecimal("glj.quantity"));
+                }
+            }
+        }
+    }
+
+}
+
+ProjectGLJ.prototype.getQuantityPerGLJ =function (pglj,mixRatioSubdivisionMap,mixRatioTechMap) {
+    let billIDs =   projectObj.project.Bills.getSubdivisionProjectLeavesID();//取分部分项上的所有叶子清单ID
+    let tech_billIDS =  projectObj.project.Bills.getTechLeavesID();//取所有技术措施项目叶子清单ID
+    let ration_glj_list = projectObj.project.ration_glj.datas;
+    let mixRatioMap = this.datas.mixRatioMap;
+    let rations = projectObj.project.Ration.datas;
+    let q_decimal = getDecimal("glj.quantity");
+    let result={};
+    let sum = 0;
+    let tech_sum = 0;
+    for(let rg of ration_glj_list){
+        if(rg.projectGLJID==pglj.id){
+            if(_.includes(billIDs,rg.billsItemID)){//计算分部分项
+               let total = calcQuantity(rg,mixRatioSubdivisionMap);
+               sum = scMathUtil.roundForObj(sum+total,q_decimal);
+            }
+            if(_.includes(tech_billIDS,rg.billsItemID)){//计算技术措施项目消耗量
+                let tech_total = calcQuantity(rg,mixRatioTechMap);
+                tech_sum = scMathUtil.roundForObj(tech_sum+tech_total,q_decimal);
+            }
+        }
+
+    }
+    for(let ra of rations){//计算定额类型工料机的消耗量
+        if(ra.type == rationType.gljRation&&ra.projectGLJID===pglj.id){
+            let r_quantity = scMathUtil.roundForObj(ra.quantity,q_decimal);
+            r_quantity = r_quantity?r_quantity:0;
+            if(_.includes(billIDs,ra.billsItemID)){//计算分部分项
+                sum = scMathUtil.roundForObj(sum+r_quantity,q_decimal);
+            }
+            if(_.includes(tech_billIDS,ra.billsItemID)){//计算技术措施项目消耗量
+                tech_sum = scMathUtil.roundForObj(tech_sum+r_quantity,q_decimal);
+            }
+        }
+
+    }
+    result.subdivisionQuantity = sum;
+    result.techQuantity = tech_sum;
+    return result;
+
+    function calcQuantity(rg,quantityMap) { //计算工料机在所属定额下的总消耗量
+        let tem_ration = _.find(rations,{"ID":rg.rationID});
+        let total = parseFloat(gljOprObj.getTotalQuantity(rg,tem_ration));
+        let r_index = gljOprObj.getIndex(rg,gljKeyArray);
+        if(mixRatioMap.hasOwnProperty(r_index)){
+            let mixRatioList = mixRatioMap[r_index];
+            for(let m of mixRatioList){
+                let m_index = gljOprObj.getIndex(m,gljKeyArray);
+                let m_quantity = scMathUtil.roundForObj(total*m.consumption,q_decimal);
+                if(quantityMap[m_index]){
+                    quantityMap[m_index] = scMathUtil.roundForObj(quantityMap[m_index]+m_quantity,q_decimal);
+                }else {
+                    quantityMap[m_index] = m_quantity;
+                }
+            }
+        }
+        return total;
+    }
+
+} 

+ 115 - 5
web/building_saas/main/js/models/quantity_detail.js

@@ -146,7 +146,9 @@ var quantity_detail = {
                     me.cleanQuantityDetail();
                 }else {
                     data.newRecord?me.refreshAfterSave(data.newRecord):me.refreshAfterSave(data);
-                    data.node?gljOprObj.refreshTreeNode(data.node):"";
+                    if(data.node){
+                      me.refreshRationOrBillNodes(data.node);
+                    }
                     //gljOprObj.detailSheet.setActiveCell(0,0);
                     //gljOprObj.detailSheet.clearSelection();
                 }
@@ -156,6 +158,19 @@ var quantity_detail = {
                 $.bootstrapLoading.end();
             });
         };
+        quantity_detail.prototype.refreshRationOrBillNodes=function(node){//工程量明细更新后触发定额或清单工程量改变,进行相应的更新
+            var nodes = gljOprObj.refreshTreeNode(node);
+            if(nodes.length>0){//触发计算
+                let newNode = nodes[0];
+                if(newNode.sourceType === project.Bills.getSourceType()){
+                    console.log(newNode.data.quantity);
+                    this.updateBillQuantity(newNode.data.quantity,newNode);
+                }else {//更新定额所使用的值要用还没转换前的
+                    this.updateRationQuantity(node.data.r_quantity,newNode,newNode.data.quantityEXP);//to do 加上工程量表达式和含量更新
+                }
+            }
+        };
+
         quantity_detail.prototype.insertQuantityDetail = function (row) {
             var args = {
                 row:row,
@@ -175,7 +190,9 @@ var quantity_detail = {
                $.bootstrapLoading.start();
                var callback=function (result) {
                    me.refreshAfterDelete(result.data);
-                   result.node?gljOprObj.refreshTreeNode(result.node):"";
+                   if(result.node){//触发计算
+                       me.refreshRationOrBillNodes(result.node);
+                   }
                    $.bootstrapLoading.end();
                }
                CommonAjax.post("/quantity_detail/deleteRecode",recode,callback,function () {
@@ -315,7 +332,9 @@ var quantity_detail = {
             $.bootstrapLoading.start();
             var callback = function (data) {
                 me.refreshAfterUpdate(data);
-                data.node?gljOprObj.refreshTreeNode(data.node):"";
+                if(data.node){
+                  me.refreshRationOrBillNodes(data.node);
+                }
                 $.bootstrapLoading.end();
             }
             CommonAjax.post(url,postData,callback,function () {
@@ -489,10 +508,9 @@ var quantity_detail = {
             }
             return validate;
         };
-        quantity_detail.prototype.autoTransformQuantity = function(value,node){
+        quantity_detail.prototype.autoTransformQuantity = function(value,node){//根据单位转换定额工程量
             let data = node.data;
             let option = optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS,'rationQuanACToRationUnit');
-            console.log(option);
             if(option==true&&node.sourceType === project.Ration.getSourceType()&&data.unit) {//还需加入判读是否转换
                 let times = parseInt(data.unit);
                 if (isNaN(times)) {
@@ -502,6 +520,98 @@ var quantity_detail = {
             }
             return value;
         };
+        quantity_detail.prototype.reverseQuantity = function (value,node) {//根据单位反向运算出工程量
+            let data = node.data;
+            if(node.sourceType === project.Ration.getSourceType()&&data.unit){
+                let times = parseInt(data.unit);
+                if (isNaN(times)) {
+                    times = 1
+                }
+                value = value * times;
+            }
+            return value
+        };
+        quantity_detail.prototype.editMainTreeNodeQuantity=function (value,node,fieldName) {
+            var me = this;
+            if(isNaN(value)){
+                alert("当前输入的数据类型不正确,请重新输入");
+                projectObj.mainController.refreshTreeNode([node]);
+            }else {
+                value=value?value:0;
+                setTimeout(function () {//spreadjs事件和提示窗口会有冲突,所以要用延时的方法
+                    if(project.quantity_detail.quantityEditChecking(value,node,fieldName)){
+                        node.data.isFromDetail=0;
+                        project.quantity_detail.cleanQuantityDetail(node,true);
+                        if(node.sourceType === project.Bills.getSourceType()){
+                            me.updateBillQuantity(value,node);
+                        }else {
+                            me.updateRationQuantity(value,node);//to do 加上工程量表达式和含量更新
+                        }
+                    }else {
+                        projectObj.mainController.refreshTreeNode([node]);
+                    }
+                },100);
+            }
+        };
+        quantity_detail.prototype.updateBillQuantity=function (value,node) {
+            value = scMathUtil.roundForObj(value,getDecimal("quantity",node));
+            node.data.quantity = value+"";
+            let needUpdateChildren = [];//需更新的子定额
+            let gljNodes=[];//当定额工程量改变时需刷新的子工料机
+            if(node.children.length>0){//如果有子项则
+                for(let rationNode of node.children){
+                    let EXPString = rationNode.data.quantityEXP+"";
+                    if(EXPString.indexOf("QDL")!=-1){//如果定额的工程量是通过计算出来的,则应该重新计算。
+                        let tem_contain = scMathUtil.roundForObj(rationNode.data.contain,getDecimal("process"));
+                        let tem_quantity = scMathUtil.roundForObj(value*tem_contain,getDecimal("quantity",rationNode));
+                        rationNode.data.quantity = this.autoTransformQuantity(tem_quantity,rationNode);
+                        rationNode.changed = true;
+                        needUpdateChildren.push(rationNode);
+                        if (rationNode.children.length>0){//如果有子工料机
+                            gljNodes = gljNodes.concat(rationNode.children);
+                        }
+                    }else {
+                        let tem_contain=0;
+                        if(value&&value!=0){
+                           let children_quantity = scMathUtil.roundForObj(rationNode.data.quantity,getDecimal("quantity"),rationNode);
+                           children_quantity = scMathUtil.roundForObj(this.reverseQuantity(children_quantity,rationNode),getDecimal("quantity",rationNode));
+                            tem_contain =scMathUtil.roundForObj(children_quantity/value,getDecimal("process"));
+                        }
+                        rationNode.data.contain = tem_contain;
+                        rationNode.changed = true;
+                        needUpdateChildren.push(rationNode);
+                    }
+                }
+            }
+            if(needUpdateChildren.length>0){
+                project.calcProgram.calcRationsAndSave(needUpdateChildren);
+            }else {
+                node.changed = true;
+                project.calcProgram.calculate(node);
+                project.calcProgram.saveNode(node);
+            }
+            if(gljNodes.length>0){
+                projectObj.mainController.refreshTreeNode(gljNodes);
+            }
+        };
+        quantity_detail.prototype.updateRationQuantity=function(value,node,quantityEXP){
+            node.data.quantityEXP = quantityEXP?quantityEXP:value;
+            value = scMathUtil.roundForObj(value,getDecimal("ration.quantity"));
+            if(node.parent.data.quantity&&node.parent.data.quantity!=0&&node.parent.data.quantity!=""){
+                var billQuantity = scMathUtil.roundForObj(node.parent.data.quantity,getDecimal("quantity",node.parent));
+                node.data.contain = scMathUtil.roundForObj(value/billQuantity,getDecimal("process"));
+            }else {
+                node.data.contain=0;
+            }
+            value = project.quantity_detail.autoTransformQuantity(value,node);
+            value = scMathUtil.roundForObj(value,decimalObj.decimal("quantity",node))
+            node.data.quantity=value;
+            node.changed = true;
+            project.calcProgram.calculate(node);
+            project.calcProgram.saveNode(node);
+            projectObj.mainController.refreshTreeNode(node.children);//刷新子工料机总消耗量
+            gljOprObj.showRationGLJSheetData();
+        };
         quantity_detail.prototype.getDecimal=function (node) {
             var decimal = 3;
             if(node.sourceType === project.Bills.getSourceType()){

+ 35 - 2
web/building_saas/main/js/models/ration.js

@@ -335,13 +335,17 @@ var Ration = {
 
         ration.prototype.CalculateQuantity = function (ration) {
             // calculate ration Quantity
+            let quantity_decimal = getDecimal("ration.quantity");
+            let process_decimal = getDecimal("process");
             if (optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToBillsQuan')) {
                 let billsNode = this.project.Bills.tree.findNode(ration[this.project.masterField.ration]);
                 let billsQuantity = billsNode.data.quantity ? billsNode.data.quantity : 0;
+                ration.contain = 1;
+                ration.quantityEXP="QDL";
                 if (optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToRationUnit')) {
-                    ration.quantity = (billsQuantity / this.FilterNumberFromUnit(ration.unit)).toDecimal(4);
+                    ration.quantity = (billsQuantity / this.FilterNumberFromUnit(ration.unit)).toDecimal(quantity_decimal);
                 } else {
-                    ration.quantity = billsQuantity.toDecimal(4);
+                    ration.quantity = billsQuantity.toDecimal(quantity_decimal);
                 }
             }
         };
@@ -379,6 +383,35 @@ var Ration = {
 
             this.project.endUpdate();
         };
+        ration.prototype.updateContain=function (value,node) {
+            if(isNaN(value)){
+                alert("当前输入的数据类型不正确,请重新输入");
+                projectObj.mainController.refreshTreeNode([node]);
+                return;
+            }
+            let billNode = node.parent;
+            let contain = scMathUtil.roundForObj(value,getDecimal("process"));
+            if(node.data.quantityEXP=="GCLMXHJ"){//如果定额工程量是来自工程量明细
+                var c = confirm('已有工程量明细,是否清空明细表,采用手工输入的表达式?');
+                if(c){
+                    node.data.isFromDetail=0;
+                    project.quantity_detail.cleanQuantityDetail(node,true);
+                }else {
+                    projectObj.mainController.refreshTreeNode([node]);
+                    return;
+                }
+            }
+            let billQuantity = billNode.data.quantity||billNode.data.quantity!=""?billNode.data.quantity:0;
+            billQuantity = parseFloat(billQuantity);
+            node.data.contain = contain;
+            node.data.quantityEXP="QDL*"+contain;
+            node.data.quantity=scMathUtil.roundForObj(billQuantity*contain,getDecimal("quantity"),node);
+            node.data.quantity = projectObj.project.quantity_detail.autoTransformQuantity(node.data.quantity,node);//按单位做转换
+            node.changed = true;
+            project.calcProgram.calculate(node);
+            project.calcProgram.saveNode(node);
+            projectObj.mainController.refreshTreeNode(node.children);//刷新子工料机树节点总消耗量
+        };
         
         return new ration(project);
     }

+ 8 - 7
web/building_saas/main/js/models/ration_glj.js

@@ -118,12 +118,13 @@ var ration_glj = {
             //add to mainTree;
             me.addToMainTree(neRecodes);
             let node = project.mainTree.selected;
-            project.calcProgram.calculate(node);
-            project.calcProgram.saveNode(node);
-            if (activeSubSheetIs(subSheetIndex.ssiCalcProgram)) {
-                calcProgramObj.showData(node, false);
-            }
-            ;
+            project.projectGLJ.loadData(function () {
+                project.calcProgram.calculate(node);
+                project.calcProgram.saveNode(node);
+                if (activeSubSheetIs(subSheetIndex.ssiCalcProgram)) {
+                    calcProgramObj.showData(node, false);
+                };
+            });
         };
         ration_glj.prototype.addToMainTree = function (datas) {
             datas = sortRationGLJ(datas);
@@ -367,8 +368,8 @@ var ration_glj = {
                 if (initShow == false) {//不需要初始化,只需耍新当前显示就可以了
                     gljOprObj.showRationGLJSheetData();
                 }
-                me.reCalcWhenGLJChange(recode);//触发计算定额以及父节点
                 projectObj.project.projectGLJ.loadData(function () {//等项目工料机加载完成后再给用户编辑
+                    me.reCalcWhenGLJChange(recode);//触发计算定额以及父节点
                     if (initShow == true) {
                         gljOprObj.refreshView();
                     }

+ 1 - 1
web/building_saas/main/js/views/character_content_view.js

@@ -668,7 +668,7 @@ let pageCCOprObj = {
         node.data.itemCharacter = itemCharacter;
         this.nameCache = name;
         // 根据规则设置对应特征、内容、名称格式
-        const setting = projectObj.project.property.addRule !== undefined ? projectObj.project.property.addRule : null;
+        const setting = projectObj.project.property.addRule !== undefined ? projectObj.project.property.addRule : getAddRuleSetting();
         const updateData = pageCCOprObj.getCharacterUpdateData(setting, node);
         node.data.jobContentText = updateData.jobContentText;
         node.data.itemCharacterText = updateData.itemCharacterText;

+ 16 - 14
web/building_saas/main/js/views/glj_view.js

@@ -992,8 +992,6 @@ var gljOprObj = {
         }
     },
     updateRationTypeGLJ: function (value, node, fieldName) {
-        console.log(fieldName)
-        console.log(value);
         let newval;
         let updatePrice = false;
         if (fieldName == "marketUnitFee") {
@@ -1236,11 +1234,12 @@ var gljOprObj = {
                     gljOprObj.sheetData = gljOprObj.sheetData.concat(result.showData);
                     gljOprObj.showRationGLJSheetData();
                     project.ration_glj.addToMainTree(result.showData);
-                    project.projectGLJ.loadData();
-                    project.calcProgram.calculate(selected);
-                    project.calcProgram.saveNode(selected);
-                    projectObj.mainController.refreshTreeNode([selected]);
-                    $.bootstrapLoading.end();
+                    project.projectGLJ.loadData(function () {
+                        project.calcProgram.calculate(selected);
+                        project.calcProgram.saveNode(selected);
+                        projectObj.mainController.refreshTreeNode([selected]);
+                        $.bootstrapLoading.end();
+                    });
                 }
             });//doc.rationID=selected.data.ID;
         } else {
@@ -1276,11 +1275,12 @@ var gljOprObj = {
                     node ? nodes.push(node) : "";
                 }
                 //project.ration_glj.addToMainTree(data);
-                project.projectGLJ.loadData();
                 selected.data.adjustState = result.adjustState;
-                projectObj.mainController.refreshTreeNode(nodes);
-                project.calcProgram.calculate(selected);
-                project.calcProgram.saveNode(selected);
+                project.projectGLJ.loadData(function () {//加载完项目工料机再计算
+                    projectObj.mainController.refreshTreeNode(nodes);
+                    project.calcProgram.calculate(selected);
+                    project.calcProgram.saveNode(selected);
+                });
             }
             $.bootstrapLoading.end();
         })
@@ -1308,10 +1308,11 @@ var gljOprObj = {
                 }
             })
             me.showRationGLJSheetData();
-            project.projectGLJ.loadData();
             var rationNodes = me.refreshStateAfterMreplace(stateList, nodes);
-            project.calcProgram.calcRationsAndSave(rationNodes);
-            $.bootstrapLoading.end();
+            project.projectGLJ.loadData(function () {
+                project.calcProgram.calcRationsAndSave(rationNodes);
+                $.bootstrapLoading.end();
+            });
         })
     },
     updateProperty: function (obj, doc) {
@@ -1363,6 +1364,7 @@ var gljOprObj = {
             }
         }
         projectObj.mainController.refreshTreeNode(nodes);
+        return nodes;
 
     },
     getTreeNodeCellType: function (data) {

+ 10 - 6
web/building_saas/main/js/views/main_tree_col.js

@@ -43,7 +43,7 @@ let MainTreeCol = {
         calcProgramName: function (node) {
             if (
                 node.sourceType === projectObj.project.Ration.getSourceType() ||
-                (projectObj.project.calcProgram.isLeafBill(node) && projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
+                (treeNodeTools.isLeafBill(node) && projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
             ) return false
             else return true;
         },
@@ -51,7 +51,7 @@ let MainTreeCol = {
             return node.data.subType != 201 && node.data.subType != 4 && node.data.subType != 5
         },
         commonUnitFee: function (node) {
-            return !projectObj.project.calcProgram.isNullBill(node);
+            return !treeNodeTools.isNullBill(node);
         },
         //根据节点、父节点类型判断是否可用计算基数
         calcBaseType: function (node) {
@@ -85,7 +85,7 @@ let MainTreeCol = {
             return node.sourceType === projectObj.project.Bills.getSourceType();
         },
         ration: function (node) {
-            return projectObj.project.calcProgram.isRation(node);
+            return treeNodeTools.isRation(node);
         },
         glj: function (node) {
             return node.sourceType == projectObj.project.ration_glj.getSourceType();
@@ -129,6 +129,9 @@ let MainTreeCol = {
         },
         forMarketPrice: function (node) {
             return MainTreeCol.readOnly.bills(node) || (MainTreeCol.readOnly.ration(node) && node.data.type == rationType.ration) || gljOprObj.marketPriceReadOnly(node);
+        },
+        forContain:function (node) {
+            return MainTreeCol.readOnly.non_ration(node)&&!MainTreeCol.readOnly.glj(node);
         }
     },
     cellType: {
@@ -156,7 +159,7 @@ let MainTreeCol = {
         calcProgramName: function (node) {
             if (
                 node.sourceType === projectObj.project.Ration.getSourceType() ||
-                (projectObj.project.calcProgram.isLeafBill(node) && projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
+                (treeNodeTools.isLeafBill(node) && projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
             ) {
                 // var names = new GC.Spread.Sheets.CellTypes.ComboBox();
                 var names = sheetCommonObj.getDynamicCombo();
@@ -249,7 +252,8 @@ let colSettingObj = {
         sheet.setColumnCount(1);
         sheet.getRange(-1, 0, -1, 1).cellType(this.checkBox).hAlign(GC.Spread.Sheets.HorizontalAlign.center);
         sheet.getCell(0, 0, GC.Spread.Sheets.SheetArea.colHeader).value('显示');
-        sheet.setColumnWidth(0, 300);
+        sheet.setColumnWidth(0, 100);
+        sheet.setColumnWidth(0, 150, GC.Spread.Sheets.SheetArea.rowHeader);
 
         setting.cols.forEach(function (col, index) {
             let i, iCol = 0, cell;
@@ -266,7 +270,7 @@ let colSettingObj = {
             ;
             let colWidth = sheet.getColumnWidth(index, GC.Spread.Sheets.SheetArea.rowHeader);
             colWidth = colWidth > col.width ? colWidth : col.width;
-            sheet.setColumnWidth(index, colWidth, GC.Spread.Sheets.SheetArea.rowHeader);
+            //sheet.setColumnWidth(index, colWidth, GC.Spread.Sheets.SheetArea.rowHeader);
             cell = sheet.getCell(index, 0).value(col.visible);
             sheet.autoFitRow(index);
         });

+ 31 - 23
web/building_saas/main/js/views/project_view.js

@@ -119,7 +119,7 @@ var projectObj = {
         return value;
     },
     checkSpreadEditingText: function (editingText, colSetting) {
-        if (colSetting.data.field === 'quantity') {
+        if (colSetting.data.field === 'quantity'||colSetting.data.field === 'contain') {
             return this.checkFormulaValidField(editingText, colSetting);
         }
         else if (colSetting.data.field === 'programID') {
@@ -210,11 +210,11 @@ var projectObj = {
                 });
             }
         }
-        if (value.length === 9 && /^[\d]+$/.test(value)) {
+        if (value&&value.length === 9 && /^[\d]+$/.test(value)) {
             stdMatchCode = value;
             formatCode = project.Bills.newFormatCode(stdMatchCode);
             searchStdBillsAndUpdate(stdMatchCode, formatCode);
-        } else if (value.length === 12 && /^[\d]+$/.test(value)) {
+        } else if (value&&value.length === 12 && /^[\d]+$/.test(value)) {
             stdMatchCode = value.substr(0, 9);
             matchs = project.Bills.sameStdCode(stdMatchCode, node.data.code);
             if (matchs.indexOf(value) === -1) {
@@ -268,33 +268,22 @@ var projectObj = {
         let project = projectObj.project, fieldName = colSetting.data.field;
         if(node.sourceType==project.ration_glj.getSourceType()){
             project.ration_glj.updateFromMainSpread(value,node,fieldName);
-        }if(node.sourceType==ModuleNames.ration&&node.data.type==rationType.gljRation){
+        }else if(treeNodeTools.isGljRation(node)){
             gljOprObj.updateRationTypeGLJ(value,node,fieldName);
         } else if (value !== calcFees.getFee(node.data, fieldName)||fieldName == 'quantity') {//工程量需要进行转换,所以做特殊处理
-            if (fieldName === 'code' && !project.calcProgram.isVolumePrice(node)) {
+            if (fieldName === 'code' && !treeNodeTools.isVolumePrice(node)) {
                 projectObj.updateCode(node, value);
             }
             else if(fieldName ==='feeRate'){
                 project.FeeRate.updateFeeRateFromBills(value,node,fieldName);
+            }else if(fieldName ==='contain'){//编辑含量
+                project.Ration.updateContain(value,node);
             }
             else if (fieldName === 'quantity' || fieldName === 'marketUnitFee' || fieldName === 'programID' ||
                 fieldName === 'subType' || fieldName === 'calcBase' || fieldName === 'feesIndex.common.unitFee'){
                 if (fieldName === 'quantity') {
-                   if (value) {
-                       value = project.quantity_detail.autoTransformQuantity(value,node);
-                       value = scMathUtil.roundForObj(value,decimalObj.decimal(fieldName,node));
-                       if(value==node.data[fieldName]){
-                           projectObj.mainController.refreshTreeNode([node]);
-                           return;
-                       }
-                   };
-                   if(project.quantity_detail.quantityEditChecking(value,node,fieldName)){
-                       node.data.isFromDetail=0;
-                       project.quantity_detail.cleanQuantityDetail(node,true);
-                   }else {
-                       projectObj.mainController.refreshTreeNode([node]);
-                       return;
-                   }
+                    project.quantity_detail.editMainTreeNodeQuantity(value,node,fieldName);
+                    return;
                 }
                 else if (fieldName === 'marketUnitFee' || fieldName === 'feesIndex.common.unitFee') {
                     if (value) {value = parseFloat(value).toDecimal(decimalObj.decimal("unitPrice", node))};
@@ -394,13 +383,15 @@ var projectObj = {
     loadProjectData: function () {
         var that = this;
         this.project = PROJECT.createNew(scUrlUtil.GetQueryString('project'), userID);
+        let startTime = +new Date();
+        console.log("开始加载-----"+startTime);
         this.project.loadDatas(function (err) {
-
             if (!err) {
+                that.project.projectGLJ.calcQuantity();//计算分部分项和技术措施项目消耗量;
                 that.project.property = projectInfoObj.projectInfo.property;
                 //that.project.calcProgram.compileAllTemps();
                 that.project.calcBase.init(that.project);
-                that.project.calcFields = JSON.parse(JSON.stringify(feeType));
+                that.project.calcFields = JSON.parse(JSON.stringify(cpFeeTypes));
                 // that.project.initCalcFields();
                 let str = JSON.stringify(that.project.projSetting.main_tree_col);
                 that.project.projSetting.mainGridSetting = JSON.parse(str);
@@ -446,7 +437,9 @@ var projectObj = {
                             col.data.wordWrap = true;
                         }
                     }
-
+                    if(col.data.field ==='quantity'){
+                        col.showHint = true;
+                    }
                     // for test digit. CSLAAAAA
                     if (col.data.field.hasSubStr("totalFee"))
                        col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.totalPrice, false)
@@ -469,6 +462,8 @@ var projectObj = {
                 that.mainSpread.bind(GC.Spread.Sheets.Events.SelectionChanged, that.amountAreaNumber);
                 that.loadMainSpreadContextMenu();
                 that.loadFocusLocation();
+                let endTime = +new Date();
+                console.log("加载完成-----"+endTime);
             }
             else {
 
@@ -486,6 +481,19 @@ var projectObj = {
                 return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
             },
             items: {
+                "insertRootBill": {
+                    name: "插入大项费用",
+                    icon: 'fa-sign-in',
+                    disabled: function () {
+                        //return project.mainTree.selected ? project.mainTree.selected.sourceType !== project.Bills.getSourceType() : false;
+                    },
+                    callback: function (key, opt) {
+                        ProjectController.addRootBill(project, controller);
+                    },
+                    visible: function(key, opt){
+                        return false;//project.mainTree.selected&&project.mainTree.selected.parent ==null;;
+                    }
+                },
                 "insertBills": {
                     name: "插入清单",
                     icon: 'fa-sign-in',

+ 1 - 1
web/building_saas/main/js/views/std_bills_lib.js

@@ -281,7 +281,7 @@ var billsLibObj = {
                 "font":"Arial"
             }
         }, {
-            "width":50,
+            "width":45,
             "readOnly": true,
             "showHint": true,
             "head":{