zhangweicheng 7 年之前
父节点
当前提交
1b527ddb9d

+ 15 - 0
modules/main/controllers/project_controller.js

@@ -78,5 +78,20 @@ module.exports = {
                 callback(req, res, err, message, result);
             }
         });
+    },
+    calcInstallationFee:async function(req,res){
+        let result={
+            error:0
+        }
+        try {
+            let data =  JSON.parse(req.body.data);
+            let resultData= await project_facade.calcInstallationFee(data);
+            result.data=resultData;
+        }catch (err){
+            logger.err(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        res.json(result);
     }
 };

+ 107 - 1
modules/main/facade/project_facade.js

@@ -1,19 +1,125 @@
 /**
  * Created by zhang on 2018/1/26.
  */
+let mongoose = require('mongoose');
 let  projectsModel = require("../../pm/models/project_schema");
 let async_n = require("async");
+let _ = require('lodash');
 let ration_model = require('../models/ration');
 let bill_model = require('../models/bills');
 let consts = require('../models/project_consts');
 let projectConsts = consts.projectConst;
+let ration_glj_model = mongoose.model('ration_glj');
+let ration_glj_facade = require("../../ration_glj/facade/ration_glj_facade");
+const uuidV1 = require('uuid/v1');
 
 module.exports = {
     markUpdateProject:markUpdateProject,
     removeProjectMark:removeProjectMark,
-    updateNodes:updateNodes
+    updateNodes:updateNodes,
+    calcInstallationFee:calcInstallationFee
 };
 
+async function calcInstallationFee(data) {
+    let result={};
+    let billTasks  = generateTasks(data.bills,data.useID);
+    let rationTasks = generateTasks(data.ration,data.useID);
+    if(billTasks.length>0){
+        await bill_model.model.bulkWrite(billTasks);
+    }
+    console.log(rationTasks);
+    if(rationTasks.length>0){
+        await ration_model.model.bulkWrite(rationTasks);
+    }
+    //如果删除定额,需要删除对应的工料机
+    if(data.ration.delete.length>0){
+        let rationIDS = _.map(data.ration.delete,'ID');
+        await ration_glj_model.deleteMany({projectID: data.ration.delete[0].projectID, rationID: {"$in": rationIDS}});//删除定额工料机
+    }
+
+    let rationGLJTasks = [];
+    let updateList = [];
+    if(data.ration.update.length>0){//如果有需要更新的定额工料机
+        for(let ur of data.ration.update){
+            for(let g of ur.glj){
+                let gTasks = {
+                    updateOne:{
+                        filter:{
+                            ID:g.ID,
+                            projectID:g.projectID
+                        },
+                        update :{
+                            quantity:g.quantity,
+                            rationItemQuantity:g.rationItemQuantity
+                        }
+                    }
+                };
+                rationGLJTasks.push(gTasks);
+                updateList.push(g);
+            }
+        }
+    }
+    if(rationGLJTasks.length>0){
+       await ration_glj_model.bulkWrite(rationGLJTasks);
+    }
+
+    let newGljList = [];
+    if(data.ration.add.length>0){//新增的安装子目要增加对应的工料机
+        for(let nr of data.ration.add){
+            for(let tkey in nr.glj){
+                newGljList.push(await addInstallationGLJ(nr.glj[tkey]));
+            }
+        }
+    }
+    if(newGljList.length>0){
+        await ration_glj_model.insertMany(newGljList);
+    }
+    result.update = updateList;
+    result.add = newGljList;
+    return result;
+}
+
+async function addInstallationGLJ(glj) {
+    glj.ID = uuidV1();
+    let info = await ration_glj_facade.getInfoFromProjectGLJ(glj);
+    let newRecode  = ration_glj_facade.createNewRecord(info);
+    return newRecode;
+}
+
+
+function generateTasks(data,userID) {
+    let tasks=[];
+    let deleteInfo={deleted: true, deleteDateTime: new Date(), deleteBy: userID};
+    if(data.delete && data.delete.length > 0){
+        for(let bd of data.delete){
+            let task={
+                updateOne:{
+                    filter:{
+                        ID:bd.ID,
+                        projectID:bd.projectID
+                    },
+                    update :{
+                        deleteInfo:deleteInfo
+                    }
+                }
+            };
+            tasks.push(task);
+        }
+    }
+    if(data.add && data.add.length > 0){
+        for(let n_data of data.add){
+            let task = {
+                insertOne :{
+                    document:n_data
+                }
+            };
+            tasks.push(task);
+        }
+    }
+    return tasks;
+}
+
+
 function updateNodes(datas,callback) {
     let tasks = [];
     for(let node of datas){

+ 8 - 5
modules/main/facade/ration_facade.js

@@ -4,7 +4,7 @@
 let mongoose = require('mongoose');
 import SearchDao from '../../complementary_ration_lib/models/searchModel';
 const scMathUtil = require('../../../public/scMathUtil').getUtil();
-let ration_glj_facade = require("../../ration_glj/facade/ration_glj_facade")
+let ration_glj_facade = require("../../ration_glj/facade/ration_glj_facade");
 let quantity_detail = require("../facade/quantity_detail_facade");
 let ration_glj = mongoose.model('ration_glj');
 let ration_coe = mongoose.model('ration_coe');
@@ -35,7 +35,7 @@ async function addNewRation(data) {
     }
     let newRation =await insertNewRation(data.newData,stdRation,data.calQuantity);
     if(stdRation){
-        return await addRationSubList(stdRation,newRation);
+        return await addRationSubList(stdRation,newRation,data.needInstall);
     }else {
         return {ration:newRation};
     }
@@ -105,16 +105,19 @@ async function replaceRation(nodeInfo,stdRation,projectID,calQuantity) {
     if(stdRation){
         await deleRationSubRecode(projectID,nodeInfo.ID);
         let newRation = await updateRation(stdRation,nodeInfo.ID,nodeInfo.billsItemID,projectID,calQuantity);//生成并插入新的定额
-        return await addRationSubList(stdRation,newRation);
+        return await addRationSubList(stdRation,newRation,nodeInfo.needInstall);
     }else {
         return null;
     }
 }
 
-async function addRationSubList(stdRation,newRation) {
+async function addRationSubList(stdRation,newRation,needInstall) {
     let ration_gljs = await addRationGLJ(stdRation,newRation);
     let ration_coes = await addRationCoe(stdRation,newRation);
-    let ration_installs =  await addRationInstallFee(stdRation,newRation);
+    let ration_installs = [];
+    if(needInstall){
+        ration_installs =  await addRationInstallFee(stdRation,newRation);
+    }
     return {ration:newRation,ration_gljs:ration_gljs,ration_coes:ration_coes,ration_installs:ration_installs};
 }
 

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

@@ -25,7 +25,7 @@ let billsSchema = new Schema({
     billsLibId: Number,
     code: String,
     fullCode: String,
-    type:{type: Number,default:4},//1 :大项费用 2:分部 3分项 4清单
+    type:{type: Number,default:4},//1 :大项费用 2:分部 3分项 4清单;5补项
     isAdd:{type: Number,default:0},//1 true 0 false是否新增
     name: String,
     unit: String,
@@ -65,6 +65,7 @@ let billsSchema = new Schema({
     fees: [subSchema.feesSchema],
     // 标记字段
     flags: [subSchema.flagsSchema],
+    installationKey:String,//用来记录安装增加费的关联字段
     deleteInfo: deleteSchema,
 });
 

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

@@ -48,6 +48,7 @@ let rationSchema = new Schema({
     subType: Number,                            // 子类型:1人工、201材料、301机械、4主材、5设备
     from:{type: String,default:'std'},          //std, cpt  来自标准、补充
     isSubcontract: Boolean,                     // 是否分包
+    installationKey:String,                   //用来记录安装增加费的关联字段
 
     // 定额特有属性:
     libID: Number,

+ 1 - 0
modules/main/routes/project_route.js

@@ -12,6 +12,7 @@ module.exports = function (app) {
     projectRouter.post('/markUpdateProject', projectController.markUpdateProject);
     projectRouter.post('/removeProjectMark', projectController.removeProjectMark);
     projectRouter.post('/updateNodes', projectController.updateNodes);
+    projectRouter.post('/calcInstallationFee', projectController.calcInstallationFee);
 
     app.use('/project',projectRouter);
 };

+ 1 - 1
modules/pm/controllers/pm_controller.js

@@ -87,7 +87,7 @@ module.exports = {
         };
 
         // 人工系数
-        if (datas.labourCoes.updateData){
+        if (datas.labourCoes&&datas.labourCoes.updateData){
             functions.push(updateLC());
         };
 

+ 2 - 2
modules/ration_glj/facade/ration_glj_facade.js

@@ -166,8 +166,8 @@ function createNewRecord(ration_glj) {
     newRecoed.from = ration_glj.from ? ration_glj.from : undefined;
     newRecoed.createType = ration_glj.createType ? ration_glj.createType : undefined;
     newRecoed.shortName = ration_glj.shortName;
-    newRecoed.billsItemID = ration_glj.billsItemID,
-        newRecoed.type = ration_glj.type;
+    newRecoed.billsItemID = ration_glj.billsItemID;
+    newRecoed.type = ration_glj.type;
     newRecoed.repositoryId = ration_glj.repositoryId;
     newRecoed.projectGLJID = ration_glj.projectGLJID;
     newRecoed.adjCoe = ration_glj.adjCoe

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

@@ -58,6 +58,7 @@ let rationSchema = new Schema({
     deleteInfo: deleteSchema,
     type: Number,                               // 1 定额、2 量价、3 工料机定额
     subType: Number,                            // 子类型:1人工、201材料、301机械、4主材、5设备
+    installationKey:String,//用来记录安装增加费的关联字段
 
     // 定额特有属性:
     libID: Number,
@@ -185,7 +186,8 @@ let billsSchema = new Schema({
     fees: [subSchema.feesSchema],
     // 标记字段
     flags: [subSchema.flagsSchema],
-    deleteInfo: deleteSchema
+    deleteInfo: deleteSchema,
+    installationKey:String//用来记录安装增加费的关联字段
 });
 
 mongoose.model("bills", billsSchema);

+ 1 - 1
server.js

@@ -91,7 +91,7 @@ app.use(function (req, res, next) {
 //加载路由文件
 fileUtils.getGlobbedFiles('./modules/**/routes/*.js').forEach(function(modelPath) {
     require(path.resolve(modelPath))(app);
-})
+});
 
 //app.use(express.static(_rootDir+"/web"));
 //app.use(express.static(_rootDir+"/lib"));

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

@@ -926,7 +926,7 @@
                                     <legend class="legend" >分项费用:</legend>
                                     <div class="form-check">
                                         <label class="form-check-label">
-                                            <input class="form-check-input" name="install_setting_radios" id="all_project_calc" value="0" checked type="radio">
+                                            <input class="form-check-input" name="install_setting_radios" id="all_project_calc" value="0" type="radio">
                                             整个项目统一计取
                                         </label>
                                     </div>

+ 67 - 1
web/building_saas/main/js/models/bills.js

@@ -124,7 +124,16 @@ var Bills = {
                 this.refreshDatas(data,'quantity');
             }
         };
-
+        bills.prototype.getBillByCode = function(code){
+            let sortData = _.sortBy(projectObj.project.Bills.datas,'code');
+            return _.find(sortData, function(b) {
+                if(b.code&&b.code.indexOf(code)!=-1){
+                    return true;
+                }else {
+                    return false;
+                }
+            });
+        };
         bills.prototype.refreshDatas = function(data,fieldName){
             var dataIndex = _.findIndex(this.datas,function(item) {
                 return item.ID ==data.billID;
@@ -238,6 +247,10 @@ var Bills = {
             return this.tree.delete(node);
         };
 
+        bills.prototype.removeByID = function(ID){
+            _.remove(this.datas,{'ID':ID});
+        };
+
         bills.prototype.singleDeleteBills=function(node,controller){//只删除选中的分部,不删除其子项
             let updateData = {};
             let updateNode={};
@@ -547,6 +560,18 @@ var Bills = {
                 }
             }
         };
+        bills.prototype.getTechNode=function () {//取技术措施项目节点
+            let items = projectObj.project.mainTree.items;//所有节点;
+            let techNode = null;
+            for(let item of items){
+                if(isFlag(item.data)&&item.data.flagsIndex.fixed.flag==fixedFlag.CONSTRUCTION_TECH){
+                    techNode = item;
+                    break;
+                }
+            }
+           return techNode;
+        };
+
         bills.prototype.deleteSelectedNode=function(){//删除选中单行时的节点
             let controller = projectObj.mainController, project = projectObj.project;
             let selected = controller.tree.selected, parent = selected.parent;
@@ -715,6 +740,47 @@ var Bills = {
             });
             cbTools.refreshFormulaNodes();
         };
+        bills.prototype.getAllBXs = function () {
+          return _.filter(this.datas,{"type":billType.BX});
+        };
+        bills.prototype.getNewInstallBillData = function (code,billID,feeType) {
+            let controller = projectObj.mainController;
+            let parentNode;
+            if(feeType == '措施费用'){
+                parentNode = this.getTechNode();
+            }else {
+                let rootNode = this.getFBFXNode(controller);
+                   parentNode =getLeaveBill(rootNode.source);
+                if(parentNode.data.type == billType.FX){//如果是分项的话,取父节点
+                    parentNode = parentNode.parent;
+                }
+            }
+            if(!billID){
+                billID = uuid.v1();
+            }
+            let data = {
+                ID:billID,
+                projectID: parseInt(projectObj.project.ID()),
+                ParentID:parentNode.data.ID,
+                NextSiblingID:-1,
+                code : this.newFormatCode(code),
+                name:'安装增加费',
+                unit:'元',
+                quantity:'1'
+            };
+            return data;
+
+            function getLeaveBill(node) {
+                if(node.children.length>0){
+                    return getLeaveBill(node.children[node.children.length-1]);
+                }else {
+                    return node;
+                }
+            }
+
+
+        };
+
         return new bills(project);
     }
 };

+ 476 - 0
web/building_saas/main/js/models/installation_fee.js

@@ -189,7 +189,483 @@ var installation_fee = {
                 })
             }
         };
+        installation_fee.prototype.calcInstallationFee=function(callback){
+            let project = projectObj.project,me = this;
+            let engineering = projectInfoObj.projectInfo.property.engineering;
+            let installSetting = projectInfoObj.projectInfo.property.installSetting;
+            let rationInstallation  = project.ration_installation;
+            let BXs =  project.Bills.getAllBXs();//取所有补项
+            let allBillsDatas = _.sortBy(_.cloneDeep(project.Bills.datas),'code');//取所有清单信息,用来查找清单信息和存放中间过程产生的清单
+            let rationKeyMap={};//安装子目关联表
+            let newBills = [];
+            let billSerialMap = {};
+            let FBMap = {};//保存分部下对应的补项
+            let usedBXMap = {};//有使用到的补项
+            if(engineering!=engineeringType.BUILD_IN){//如果不是安装工程,则不用计算
+                return;
+            }
+            for(let bx of BXs){//把补项放入映射表中
+                FBMap[bx.ParentID] =bx;
+            }
+            for(let d of me.datas){
+                for(let item of d.installFeeItem){
+                    if(item.isCal == 1){ //勾选了记取的费用项
+                        let rule_ration_map={};//费用规则定额映射表;
+                        let ra_installs = rationInstallation.getCalcRIByItemID(d.libID,item.ID);//取所有有效的定额安装增加费
+                        for(let ri of ra_installs){
+                            let rationNode = project.mainTree.getNodeByID(ri.rationID);
+                            if(rationNode){
+                                if(rule_ration_map[ri.ruleId]){
+                                    rule_ration_map[ri.ruleId].push(rationNode.data);
+                                }else {
+                                    rule_ration_map[ri.ruleId] = [rationNode.data];
+                                }
+                            }
+                        }
+                        for(let ruleIDKey in rule_ration_map){
+                            calcEachRule(item,d.libID,ruleIDKey,rule_ration_map[ruleIDKey],rationKeyMap,newBills);
+                        }
+                    }
+                }
+            }
+
+            console.log("------------------生成的定额安装费");
+            console.log(rationKeyMap);
+            console.log("------------------新的清单");
+            console.log(newBills);
+            let updateData = {
+                bills:{
+                    delete:[],
+                    add:newBills
+                },
+                ration:{//定额更新只有更新对应的工料机数据
+                    delete:[],
+                    update:[],
+                    add:[]
+                },
+                userID: userID
+            };
+            let oldITypeRations = _.cloneDeep(project.Ration.getAllInstallTypeRation())//取所有旧的安装增加费定额-没有用的要删除
+            let oldRationMap = {};
+            let deleteRationNodes = [];
+            let deleteBillsNodes = [];
+            let isChange = newBills.length>0;//记录数据是否发生了改变;
+            for(let o of oldITypeRations){//过滤出要删除的定额
+                if(rationKeyMap[o.installationKey]==undefined){
+                    updateData.ration.delete.push(o);
+                    let d_node =  project.mainTree.getNodeByID(o.ID);
+                    if(d_node){
+                        deleteRationNodes.push(d_node);
+                        isChange = true;
+                    }
+                }
+                oldRationMap[o.installationKey] = o;
+            }
+
+            for(let inKey in rationKeyMap){
+                if(oldRationMap[inKey]){//存在,则更新就可以了
+                    if(checkRation(oldRationMap[inKey],rationKeyMap[inKey])){//检查是否需要更新
+                        updateData.ration.update.push(oldRationMap[inKey]);
+                        isChange = true;
+                    }
+                }else {
+                    updateData.ration.add.push(rationKeyMap[inKey]);
+                    isChange = true;
+                }
+            }
+
+            for(let tem_bx of BXs){//过滤要删除的补项
+                if(usedBXMap[tem_bx.ParentID]==undefined){
+                    updateData.bills.delete.push(tem_bx);
+                    let b_node =  project.mainTree.getNodeByID(tem_bx.ID);
+                    if(b_node){
+                        deleteBillsNodes.push(b_node);
+                        isChange = true;
+                    }
+                }
+            }
+
+            console.log(updateData);
+            console.log(isChange);
+            if(isChange == true){
+                $.bootstrapLoading.start()
+                CommonAjax.post("/project/calcInstallationFee",updateData,function (data) {
+                    //提交后台成功后所做的操作,删除要先删除定额,再删除清单,添加要先添加清单再添加定额
+                    console.log(data);
+                    project.ration_glj.addDatasToList(data.add);//添加插入的定额
+                    for(let ur of data.update){
+                        let glj = project.ration_glj.getDataByID(ur.ID);
+                        glj.quantity = ur.quantity;
+                        glj.rationItemQuantity = ur.rationItemQuantity;
+                    }
+
+                    //对树节点的操作并删除、添加清单、删除添加定额、删除对应的定额工料机缓存
+                    TREE_SHEET_HELPER.massOperationSheet(projectObj.mainController.sheet, function () {
+                        deleteOldNodes(deleteRationNodes,deleteBillsNodes);
+                        addNewNodes(updateData);
+                    });
+                    projectObj.project.projectGLJ.loadData(function () {
+                        cbTools.refreshFormulaNodes();
+                        if(callback){
+                            callback();
+                        }
+                        $.bootstrapLoading.end();
+                    });
+                });
+            }
+            function addNewNodes(updateData) {
+                let controller = projectObj.mainController;
+                let Bill = project.Bills;
+                let newAddNode = [];
+                for(let nb of updateData.bills.add){
+                    let newSource = Bill.tree.insertByData(nb, nb.ParentID, -1, true);
+                    let newNode = project.mainTree.insert(nb.ParentID, -1, newSource.data.ID);
+                    newNode.source = newSource;
+                    newNode.sourceType = Bill.getSourceType();
+                    newNode.data = newSource.data;
+                    controller.sheet.addRows(newNode.serialNo(), 1);
+                    controller.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+                    newAddNode.push(newNode);
+                    Bill.datas.push(nb);
+                }
+                for(let nr of updateData.ration.add){
+                   let newNode = project.mainTree.insert(nr.billsItemID, -1, nr.ID);
+                    newNode.source = nr;
+                    newNode.sourceType = project.Ration.getSourceType();
+                    newNode.data = nr;
+                    controller.sheet.addRows(newNode.serialNo(), 1);
+                    controller.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+                    newAddNode.push(newNode);
+                    project.Ration.datas.push(nr);
+                }
+                TREE_SHEET_HELPER.refreshTreeNodeData(controller.setting, controller.sheet, newAddNode, false);
+            }
+
+            function deleteOldNodes(deleteRationNodes,deleteBillsNodes) {
+                let controller = projectObj.mainController, project = projectObj.project;
+                let Bill = project.Bills, Ration = project.Bills.Ration,ration_glj = project.ration_glj;
+             //   let sels = controller.sheet.getSelections();
+                for(let rd of deleteRationNodes){
+                    controller.sheet.deleteRows(rd.serialNo(),1);
+                    controller.tree.delete(rd);
+                    Ration.removeByID(rd.getID());
+                    ration_glj.deleteByRation(rd.data);
+                }
+                for(let bd of deleteBillsNodes){
+                    controller.sheet.deleteRows(bd.serialNo(),1);
+                    controller.tree.delete(bd);
+                    Bill.tree.delete(bd.source);
+                    Bill.removeByID(bd.getID());
+                }
+                controller.setTreeSelected(controller.tree.items[1]);
+            }
+
+            
+            function checkRation(oldRation,newRation) {//检查定额是否需要更新
+                let gljs = project.ration_glj.getGljByRationID(oldRation.ID);
+                let modify = false;
+                let gljList =[];
+                for(let g of gljs){
+                    if(g.quantity != newRation.glj[g.code].quantity){//消耗量不一样,需重新修改
+                        let tem ={
+                            ID:g.ID,
+                            projectID:g.projectID,
+                            quantity :newRation.glj[g.code].quantity,
+                            rationItemQuantity:newRation.glj[g.code].rationItemQuantity
+                        };
+                        gljList.push(tem);
+                        modify = true;
+                    }
+                }
+                oldRation.glj = gljList;
+                return modify;
+
+            }
+
+            function calcEachRule(item,libID,ruleID,rations,rationKeyMap,newBills) {
+                let rule = me.getFeeRuleByID(libID,ruleID);
+                let pre_key = libID+item.ID+item.feeType+ruleID;
+                if(item.feeType == '子目费用'){
+                    for(let r of rations){//在定额的同级新增一条
+                        let billItemID = r.billsItemID;
+                        let nextID = -1;
+                        let newRationData = createNewRationData(billItemID,nextID,rule);
+                        let [labourQuantity,materialQuantity,machineQuantity] = calcQuantity(rule,r);
+                        newRationData = setGljQuantity(newRationData,labourQuantity,materialQuantity,machineQuantity);
+                        let installationKey = pre_key+billItemID;
+                        newRationData['installationKey'] = installationKey;
+                        if(rationKeyMap[installationKey]){//如果已经存在,则工料机消耗量累加起来
+                            sumGLJquantity(rationKeyMap[installationKey],labourQuantity,materialQuantity,machineQuantity);
+                        }else {
+                            rationKeyMap[installationKey] = newRationData;//在映射表中添加
+                        }
+                    }
+                }else if(item.feeType == '措施费用'){//措施费用时,则在记取位置选择的清单下新增安装子目。
+                    allInOne(item,rule,rations,newBills,pre_key,rationKeyMap);
+                }else if(item.feeType=='分项费用'){
+                    if(installSetting==undefined||installSetting=="0"){//选择了“整个项目统一计取”,则在记取位置选择的分项下新增安装子目
+                        allInOne(item,rule,rations,newBills,pre_key,rationKeyMap);
+                    }else {//选择了每个分部单独记取
+                        calcEveryFB(item,rule,rations,newBills,pre_key,rationKeyMap);
+                    }
+                }
+            }
+
+
+            function sumGLJquantity(ration,labourQuantity,materialQuantity,machineQuantity) {
+                let gljDecimal = getDecimal('glj.quantity');
+                let sumLabour = scMathUtil.roundForObj(ration.glj['RGFTZ'].quantity,gljDecimal)+labourQuantity;
+                let sumMaterial = scMathUtil.roundForObj(ration.glj['CLFTZ'].quantity,gljDecimal)+materialQuantity;
+                let sumMachine = scMathUtil.roundForObj(ration.glj['JXFTZ'].quantity,gljDecimal)+machineQuantity;
+                ration.glj['RGFTZ'].quantity =scMathUtil.roundToString(sumLabour,gljDecimal);
+                ration.glj['RGFTZ'].rationItemQuantity = scMathUtil.roundToString(sumLabour,gljDecimal);
+                ration.glj['CLFTZ'].quantity = scMathUtil.roundToString(sumMaterial,gljDecimal);
+                ration.glj['CLFTZ'].rationItemQuantity = scMathUtil.roundToString(sumMaterial,gljDecimal);
+                ration.glj['JXFTZ'].quantity = scMathUtil.roundToString(sumMachine,gljDecimal);
+                ration.glj['JXFTZ'].rationItemQuantity = scMathUtil.roundToString(sumMachine,gljDecimal);
+            }
+
+            function calcEveryFB(item,rule,rations,newBills,pre_key,rationKeyMap) {
+                let parentMap = {};
+                for(let r of rations){//先归类
+                    let rationNode = project.mainTree.getNodeByID(r.ID);
+                    if(rationNode){
+                        if(parentMap[rationNode.parent.parent.getID()]){
+                            parentMap[rationNode.parent.parent.getID()].push(r)
+                        }else {
+                            parentMap[rationNode.parent.parent.getID()] = [r];
+                        }
+                    }
+                }
+                for(let billID_key in parentMap){
+                    let gljDecimal = getDecimal('glj.quantity');
+                    let tem_rations = parentMap[billID_key];
+                    let BXNodeData;
+                    if(FBMap[billID_key]){//查看有没有对应的补项,如果没有,新增一个
+                        BXNodeData = FBMap[billID_key];
+                    }else {//新增一个
+                        BXNodeData = {
+                            projectID: parseInt(project.ID()),
+                            ParentID:billID_key,
+                            NextSiblingID:-1,
+                            code : 'BAZF',
+                            name:'安装增加费',
+                            unit:'元',
+                            quantity:'1',
+                            type:billType.BX
+                        };
+                        BXNodeData.ID =  uuid.v1();
+                        FBMap[billID_key] = BXNodeData;
+                        newBills.push(BXNodeData);
+                    }
+                    usedBXMap[billID_key] = BXNodeData;//记录有用到的补项,最后没有用到的要删除
+                    let newRationData = createNewRationData(BXNodeData.ID,-1,rule);
+                    let labourSum = 0,materialSum =0,machineSum = 0;
+                    for(let ra of tem_rations){//措施费用的情况下,多条定额生成一条安装子目
+                        let [tem_labourQuantity,tem_materialQuantity,tem_machineQuantity] = calcQuantity(rule,ra);
+                        labourSum =scMathUtil.roundForObj(labourSum+tem_labourQuantity,gljDecimal);
+                        materialSum= scMathUtil.roundForObj(materialSum+tem_materialQuantity,gljDecimal);
+                        machineSum = scMathUtil.roundForObj(machineSum+tem_machineQuantity,gljDecimal);
+                    }
+                    newRationData = setGljQuantity(newRationData,labourSum,materialSum,machineSum);
+                    let installationKey = pre_key+BXNodeData.ID;
+                    newRationData['installationKey'] = installationKey;
+                    rationKeyMap[installationKey] = newRationData;//在映射表中添加
+                }
+            }
+
+
+            function allInOne(item,rule,rations,newBills,pre_key,rationKeyMap) {//统一设置
+                let billData = getBillNodeData(item,rule,newBills);//取对应的清单或生成一个新的清单数据
+                let newRationData = createNewRationData(billData.ID,-1,rule);
+                let gljDecimal = getDecimal('glj.quantity');
+                let labourSum = 0,materialSum =0,machineSum = 0;
+                for(let r of rations){//措施费用的情况下,多条定额生成一条安装子目
+                    let [tem_labourQuantity,tem_materialQuantity,tem_machineQuantity] = calcQuantity(rule,r);
+                    labourSum =scMathUtil.roundForObj(labourSum+tem_labourQuantity,gljDecimal);
+                    materialSum= scMathUtil.roundForObj(materialSum+tem_materialQuantity,gljDecimal);
+                    machineSum = scMathUtil.roundForObj(machineSum+tem_machineQuantity,gljDecimal);
+                }
+                newRationData = setGljQuantity(newRationData,labourSum,materialSum,machineSum);
+                let installationKey = pre_key+billData.ID;
+                newRationData['installationKey'] = installationKey;
+                rationKeyMap[installationKey] = newRationData;//在映射表中添加
+            }
+
+            function setGljQuantity(rationData,labourQuantity,materialQuantity,machineQuantity) {
+                let gljDecimal = getDecimal('glj.quantity');
+                rationData.glj['RGFTZ'].quantity = scMathUtil.roundToString(labourQuantity,gljDecimal);
+                rationData.glj['RGFTZ'].rationItemQuantity = scMathUtil.roundToString(labourQuantity,gljDecimal);
+                rationData.glj['CLFTZ'].quantity = scMathUtil.roundToString(materialQuantity,gljDecimal);
+                rationData.glj['CLFTZ'].rationItemQuantity = scMathUtil.roundToString(materialQuantity,gljDecimal);
+                rationData.glj['JXFTZ'].quantity = scMathUtil.roundToString(machineQuantity,gljDecimal);
+                rationData.glj['JXFTZ'].rationItemQuantity = scMathUtil.roundToString(machineQuantity,gljDecimal);
+                return rationData;
+            }
+
+            function createNewRationData(billItemID,nextID,rule) {
+                let br = project.Ration.getBillsSortRation(billItemID);
+                let serialNo = 0;
+                if(billSerialMap[billItemID]){
+                    serialNo = billSerialMap[billItemID]+1
+                }else {
+                    serialNo = br.length > 0 ? br[br.length - 1].serialNo + 1 : 1;
+                    billSerialMap[billItemID] = serialNo;
+                }
+                serialNo = br.length > 0 ? br[br.length - 1].serialNo + 1 : 1;
+                let newRationData = project.Ration.getTempRationData(project.Ration.getNewRationID(), billItemID, serialNo, rationType.install);
+                newRationData = setNewRationProperty(newRationData,nextID,rule);
+                return newRationData;
+            }
+
+
+            function getBillNodeData(item,rule,newBills) {
+                let billData = null;
+                let billID = null;
+                if(rule.billID&&rule.billID!=""){
+                    billData = getBillsByID(rule.billID);
+                    billID = rule.billID;
+                }
+                if(!billData){
+                    billData = getBillsByCode(rule.position);
+                    if(!billData){//如果按ID和按code都找不到清单的话,自动生成一个
+                        let newBillData = project.Bills.getNewInstallBillData(rule.position,billID,item.feeType);
+                        if(item.feeType == '措施费用'){
+                            newBillData.type = billType.BILL;
+                        }else if(item.feeType == '分项费用'){
+                            newBillData.type = billType.FX;
+                        }
+                        newBills.push(newBillData);
+                        allBillsDatas.push(newBillData);
+                        return newBillData;
+                    }
+                }
+                return billData;
+            }
+            function getBillsByID(billID){
+                return _.find(allBillsDatas,{"ID":billID});
+            }
+
+            function getBillsByCode(code){
+                return _.find(allBillsDatas, function(b) {
+                    if(b.code&&b.code.indexOf(code)!=-1){
+                        return true;
+                    }else {
+                        return false;
+                    }
+                })
+            }
+
+
+            function calcQuantity(rule,ration) {//计算单条定额的三个消耗量
+                let gljDecimal = getDecimal('glj.quantity');
+                let labourQuantity = 0, materialQuantity = 0, machineQuantity = 0;
+                let labour = rule.labour?rule.labour*0.01:0;
+                let material = rule.material?rule.material*0.01:0;
+                let machine = rule.machine?rule.machine*0.01:0;
+                let feeRate =  rule.feeRate?rule.feeRate*0.01:0;
+                if(rule.base=='分别按人材机乘系数'){//'分别按人材机乘系数','人工','材料','机械'
+                    labourQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getLabourTotalFee(ration))*parseFloat(labour),gljDecimal);
+                    materialQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getMaterialTotalFee(ration))*parseFloat(material),gljDecimal);
+                    machineQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getMachineTotalFee(ration))*parseFloat(machine),gljDecimal);
+                }else if(rule.base=='人工'){
+                    labourQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getLabourTotalFee(ration))*parseFloat(feeRate)*parseFloat(labour),gljDecimal);
+                }else if(rule.base=='材料'){
+                    materialQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getMaterialTotalFee(ration))*parseFloat(feeRate)*parseFloat(material),gljDecimal);
+                }else if(rule.base=='机械'){
+                    machineQuantity = scMathUtil.roundForObj(parseFloat(project.Ration.getMachineTotalFee(ration))*parseFloat(feeRate)*parseFloat(machine),gljDecimal);
+                }
+                return [labourQuantity,materialQuantity,machineQuantity];
+            }
+
+            function setNewRationProperty(data,nextID,rule) {
+                data.code = rule.code;
+                data.name = rule.rule;
+                data.unit = '元';
+                data.quantity = '1';
+                data.nextID = nextID;
+                data.glj = {
+                    'RGFTZ':{
+                        rationID:data.ID,
+                        billsItemID:data.billsItemID,
+                        shortName:project.projectGLJ.getShortNameByID(gljType.LABOUR),
+                        GLJID:-1,
+                        projectID:data.projectID,
+                        code:'RGFTZ',
+                        original_code:'RGFTZ',
+                        name:'人工费调整',
+                        specs:'',
+                        unit:'元',
+                        type:gljType.LABOUR,
+                        basePrice:1,
+                        adjCoe:null,
+                        from:'std',
+                        repositoryId:-1,
+                        quantity:'0',
+                        rationItemQuantity:'0'
+                    },
+                    'CLFTZ':{
+                        rationID:data.ID,
+                        billsItemID:data.billsItemID,
+                        shortName:project.projectGLJ.getShortNameByID(gljType.GENERAL_MATERIAL),
+                        GLJID:-1,
+                        projectID:data.projectID,
+                        code:'CLFTZ',
+                        original_code:'CLFTZ',
+                        name:'材料费调整',
+                        specs:'',
+                        unit:'元',
+                        type:gljType.GENERAL_MATERIAL,
+                        basePrice:1,
+                        adjCoe:null,
+                        from:'std',
+                        repositoryId:-1,
+                        quantity:'0',
+                        rationItemQuantity:'0'
+                    },
+                    'JXFTZ':{
+                        rationID:data.ID,
+                        billsItemID:data.billsItemID,
+                        shortName:project.projectGLJ.getShortNameByID(gljType.GENERAL_MACHINE),
+                        GLJID:-1,
+                        projectID:data.projectID,
+                        code:'JXFTZ',
+                        original_code:'JXFTZ',
+                        name:'机械费调整',
+                        specs:'',
+                        unit:'元',
+                        type:gljType.GENERAL_MACHINE,
+                        basePrice:1,
+                        adjCoe:null,
+                        from:'std',
+                        repositoryId:-1,
+                        quantity:'0',
+                        rationItemQuantity:'0'
+                    }
+                };
+                return data;
+            }
+        };
+
+        installation_fee.prototype.updateInstallSetting = function (newValue,callback) {
+           let mixDatas = {
+                projectID: projectObj.project.ID(),
+                updateType: 'update',
+                properties: {
+                    "property.installSetting":newValue
+                },
+                labourCoes: {},
+                rations: [],
+                bills: []
+            };
+            CommonAjax.post('/pm/api/updateMixDatas', {user_id: userID, mixDataArr: mixDatas}, function (rstData) {
+                projectInfoObj.projectInfo.property.installSetting = newValue;
+                if(callback){
+                    callback();
+                }
+            });
 
+        };
         // 提交数据后返回数据处理
         installation_fee.prototype.doAfterUpdate = function(err, data){
 

+ 8 - 4
web/building_saas/main/js/models/main_consts.js

@@ -155,7 +155,8 @@ const volumePriceMaps = {
 const rationType = {
     ration: 1,
     volumePrice: 2,
-    gljRation: 3
+    gljRation: 3,
+    install:4
 };
 const leafBillGetFeeType = {
     rationContent: 0,
@@ -240,13 +241,15 @@ const billType ={
     DXFY:1,//大项费用
     FB:2,//分部
     FX:3,//分项
-    BILL:4//清单
+    BILL:4,//清单
+    BX:5//补项
 };
 const billText = {
     1:'费用',
     2:'分部',
     3:'分项',
-    4:'清单'
+    4:'清单',
+    5:'补项'
 };
 
 const cpFeeTypes = [
@@ -300,4 +303,5 @@ const engineeringType = {
 };
 
 const installFeeType = ['子目费用','分项费用','措施费用'];
-const installSectionBase = ['分别按人材机乘系数','人工','材料','机械'];
+const installSectionBase = ['分别按人材机乘系数','人工','材料','机械'];
+

+ 1 - 1
web/building_saas/main/js/models/project.js

@@ -6,7 +6,7 @@ var PROJECT = {
         // 定义private方法
         var tools = {
             _project: null,
-            _ID: projectID,
+            _ID: parseInt(projectID),
             _userID: userID,
             updateLock: 0,
             updateData: [],

+ 1 - 1
web/building_saas/main/js/models/project_glj.js

@@ -500,7 +500,7 @@ ProjectGLJ.prototype.calcQuantity  = function (){
 
 }
 
-ProjectGLJ.prototype.getQuantityPerGLJ =function (pglj,mixRatioSubdivisionMap,mixRatioTechMap) {
+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;

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

@@ -110,6 +110,9 @@ var Ration = {
                 newData['subType'] = gljType.GENERAL_MATERIAL;   // 默认的量价类型为材料
                 newData['programID'] = projectInfoObj.projectInfo.property.engineering;
             };
+            if(rType == rationType.install){//是安装增加费生成的定额
+                newData['programID'] = projectInfoObj.projectInfo.property.engineering;
+            }
             return newData;
         };
 
@@ -265,6 +268,9 @@ var Ration = {
             project.ration_installation.deleteByRation(ration);
             this.datas.splice(this.datas.indexOf(ration), 1);
         };
+        ration.prototype.removeByID = function(ID){
+            _.remove(this.datas,{'ID':ID});
+        };
         ration.prototype.getDeleteDataByBill = function (nodes) {
             let updateData = [];
             for (let node of nodes) {
@@ -369,13 +375,18 @@ var Ration = {
         };
         ration.prototype.updateRationCodes = function (recodes) {
             let libID = projectInfoObj.projectInfo.engineeringInfo.ration_lib[0].id;
+            let engineering = projectInfoObj.projectInfo.property.engineering;
             let projectID = projectInfoObj.projectInfo.ID;
             let project = projectObj.project;
             let mainTree = project.mainTree;
             let nodeInfo =[];
             let refershNodes = [];
             for(let r of recodes){
-                nodeInfo.push({ID:r.node.data.ID,billsItemID:r.node.data.billsItemID,newCode:r.value});
+                let needInstall = false;
+                if(engineering==engineeringType.BUILD_IN) {//如果是安装工程,要看需不需要生成安装增加费
+                    needInstall = project.Bills.isFBFX(r.node);
+                }
+                nodeInfo.push({ID:r.node.data.ID,billsItemID:r.node.data.billsItemID,newCode:r.value,needInstall:needInstall});
                 refershNodes.push(r.node);
             }
             let calQuantity = optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToBillsQuan');
@@ -410,8 +421,10 @@ var Ration = {
         ration.prototype.addNewRation = function (itemQuery,rationType) {
             let me = this;
             let project = projectObj.project, sheetController = projectObj.mainController;
+            let engineering = projectInfoObj.projectInfo.property.engineering;
             let selected = project.mainTree.selected, newSource = null, newNode = null,pre=null,br=null;
             let billItemID = null,serialNo=1,nextID=null;
+            let needInstall = false;
             if (selected === null) { return; }
             if (selected.sourceType === project.Bills.getSourceType() && selected.depth() > 0) {
                 if (selected.source.children.length > 0) {
@@ -446,8 +459,12 @@ var Ration = {
                         brUpdate.push({projectID:newData.projectID,ID:br[i].ID,serialNo:br[i].serialNo});
                     }
                 }
+                if(engineering==engineeringType.BUILD_IN) {//如果是安装工程,要看需不需要生成安装增加费
+                    let billsNode = project.mainTree.getNodeByID(billItemID);
+                    needInstall = project.Bills.isFBFX(billsNode);//在分部分项插入的定额才需要定额安装增加费
+                }
                 $.bootstrapLoading.start();
-                CommonAjax.post("/ration/addNewRation",{itemQuery:itemQuery,newData:newData,calQuantity:calQuantity,brUpdate:brUpdate},function (data) {
+                CommonAjax.post("/ration/addNewRation",{itemQuery:itemQuery,newData:newData,calQuantity:calQuantity,brUpdate:brUpdate,needInstall:needInstall},function (data) {
                     //更新缓存
                     console.log(data);
                     me.datas.push(data.ration);
@@ -559,7 +576,31 @@ var Ration = {
             }
             return true;
         };
+        ration.prototype.getAllInstallTypeRation = function () {//取所有计取安装增加费生成的定额
+            return _.filter(this.datas,{'type':rationType.install});
+        };
 
+        ration.prototype.getLabourTotalFee=function(ration){//feesIndex.labour.totalFee  取定额的人工费合价
+            if(ration.feesIndex&&ration.feesIndex.labour&&ration.feesIndex.labour.totalFee){
+                return ration.feesIndex.labour.totalFee;
+            }else {
+                return 0;
+            }
+        };
+        ration.prototype.getMaterialTotalFee=function(ration){//feesIndex.material.totalFee 取定额的材料费合价
+            if(ration.feesIndex&&ration.feesIndex.material&&ration.feesIndex.material.totalFee){
+                return ration.feesIndex.material.totalFee;
+            }else {
+                return 0;
+            }
+        } ;
+        ration.prototype.getMachineTotalFee=function(ration){//feesIndex.machine.totalFee 取定额的机械费合价
+            if(ration.feesIndex&&ration.feesIndex.machine&&ration.feesIndex.machine.totalFee){
+                return ration.feesIndex.machine.totalFee;
+            }else {
+                return 0;
+            }
+        } ;
         return new ration(project);
     }
 };

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

@@ -104,6 +104,10 @@ var ration_glj = {
             }
             projectObj.project.projectGLJ.loadData();
         };
+        ration_glj.prototype.getDataByID = function (ID) {
+           return _.find(this.datas,{'ID':ID});
+        };
+
         ration_glj.prototype.refreshAfterSave = function (data) {
             let me = projectObj.project.ration_glj;
             let neRecodes = [];
@@ -127,6 +131,9 @@ var ration_glj = {
                 }
             });
         };
+        ration_glj.prototype.getGljByRationID = function(rationID){
+            return  _.filter(this.datas, {'rationID': rationID});
+        };
         ration_glj.prototype.addDatasToList = function (datas) {
             let  me = projectObj.project.ration_glj;
             if(datas&&datas.length>0){
@@ -397,7 +404,7 @@ var ration_glj = {
             var doc = {};
             doc[updateField] = newval;
             if (updateField == "type") {
-                doc.shortName = projectObj.project.projectGLJ.getShortNameByID[newval];
+                doc.shortName = projectObj.project.projectGLJ.getShortNameByID(newval);
             }
             CommonAjax.post("/rationGlj/updateRationGLJByEdit", {
                 query: query,

+ 10 - 0
web/building_saas/main/js/models/ration_installation.js

@@ -45,6 +45,16 @@ let ration_installation = {
             let ri = _.find(me.datas,{'ID':ID})
             return ri;
         };
+        ration_installation.prototype.getCalcRIByItemID = function (libID,itemID) {//按费用项ID取费用规则不为空的定额安装增加费
+            return _.filter(this.datas,function (item) {
+                if(item.libID == libID && item.feeItemId == itemID && item.ruleId && item.ruleId !=""){
+                    return true;
+                }
+                return false;
+            })
+        };
+
+
         ration_installation.prototype.update = function (updateData,callback) {
             let  me = this;
             $.bootstrapLoading.start();

+ 37 - 3
web/building_saas/main/js/views/glj_view.js

@@ -300,8 +300,7 @@ var gljOprObj = {
         sheet.name('quantity_detail');
         me.bindSheetEvent(sheet);
         sheet.bind(GC.Spread.Sheets.Events.EditStarting, function (sender, args) {
-             let selected = projectObj.project.mainTree.selected;
-            if(selected&&selected.sourceType == ModuleNames.ration_glj){//是主材或者是设备时只读
+            if(me.detailSheetReadonly()){
                 args.cancel = true;
             }else {
                 if(args.sheet.getValue(args.row,args.col)==null){//这里是为了解决当单元格里的值是null的时候,在单元格里输入数据,按键盘箭头移动光标的时候,会直接结束编辑,跳到另外的单元格。
@@ -310,6 +309,18 @@ var gljOprObj = {
             }
         });
     },
+    detailSheetReadonly:function () {
+        let selected = projectObj.project.mainTree.selected;
+        if(selected) {//是主材或者是设备时只读
+            if(selected.sourceType == ModuleNames.ration_glj){
+                return true;
+            }else if(selected.sourceType == ModuleNames.bills&&selected.data.type==billType.BX){//是补项时只读
+                return true;
+            }
+            return false;
+        }
+        return true;
+    },
     showCoeData: function (sheet, setting, datas) {
         sheet.floatingObjects.remove("customerCoe");
         sheetCommonObj.showData(sheet, setting, datas);
@@ -329,6 +340,7 @@ var gljOprObj = {
         sheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, me.onClipboardPasted);
         sheet.bind(GC.Spread.Sheets.Events.EditEnded, me.onEditEnded);
         sheet.bind(GC.Spread.Sheets.Events.RangeChanged, me.onRangeChanged);
+        sheet.bind(GC.Spread.Sheets.Events.EditStarting, me.startEditChecking);
         // sheet.bind(GC.Spread.Sheets.Events.CellClick, me.onCellClick);
     },
 
@@ -345,7 +357,26 @@ var gljOprObj = {
         //  if (!me.ration) {return;};
         // your code...
     },
-
+    startEditChecking:function (sender,args) {
+        let me = gljOprObj;
+        let selected = projectObj.project.mainTree.selected;
+        if(selected){
+            if(me.isInstallationNode()==true){
+                args.cancel = true;
+            }
+        }else {
+            args.cancel = true;
+        }
+    },
+    isInstallationNode:function(){
+        let selected = projectObj.project.mainTree.selected;
+        if(selected){
+            if((selected.sourceType == ModuleNames.ration&&selected.data.type == rationType.install)||(selected.sourceType == ModuleNames.bills&&selected.data.type==billType.BX)){//是定额安装费类型或者补项
+                return true;
+            }
+        }
+        return false
+    },
     onEditEnded: function (sender, args) {
         var me = gljOprObj;
         if (args.sheetName == 'ration_glj') {
@@ -424,6 +455,9 @@ var gljOprObj = {
         if(args.sheetName == 'rationInstallSheet' && checkboxValue){
             return;
         }
+        if(gljOprObj.isInstallationNode()==true){
+            return;
+        }
         let newval = 0;
         if (checkboxValue) {
             newval = 0;

+ 5 - 1
web/building_saas/main/js/views/glj_view_contextMenu.js

@@ -115,7 +115,11 @@ var gljContextMenu = {
                     icon: 'fa-sign-in',
                     disabled: function () {
                         var sheetData = gljOprObj.detailData;
-                        return gljContextMenu.selectedRow>sheetData.length;
+                        if(gljOprObj.detailSheetReadonly()){
+                            return true
+                        }else {
+                            return  gljContextMenu.selectedRow>sheetData.length;
+                        }
                     },
                     callback: function () {
                         projectObj.project.quantity_detail.insertQuantityDetail(gljContextMenu.selectedRow);

+ 91 - 9
web/building_saas/main/js/views/installation_fee_view.js

@@ -884,7 +884,7 @@ let installationFeeObj={
             //更新缓存
             feeItem.position =recode.code;
             feeItem.billID = recode.ID;
-            feeItem.displayPosition = recode.code + ' '+recode.name;
+            feeItem.displayPosition = me.getDisplayText(feeItem);
             me.feeItemSheet.getCell(selection.row, selection.col).value(feeItem.displayPosition);
             for(let ir of impacRules){
                 ir.position = recode.code;
@@ -1140,23 +1140,93 @@ let installationFeeObj={
         }
         return data;
     },
-    calcInstallationFee:function(){//计算定额安装费
-
-
-
-
+    calcInstallationFee:function(callback){//计算安装增加费
+        let engineering = projectInfoObj.projectInfo.property.engineering;
+        let installSetting = projectInfoObj.projectInfo.property.installSetting;
+        let install_fee = projectObj.project.installation_fee;
+        let autoCreate = false;
+        if(engineering!=engineeringType.BUILD_IN){//如果不是安装工程,则不用计算
+            return;
+        }
+        //可执行检查
+        let install_datas = install_fee.datas;
+        for(let d of install_datas){
+            for(let item of d.installFeeItem){
+                if(item.isCal == 1){ //勾选了记取的费用项
+                    let positionCheck = false;//是否做记取位置检查的开关
+                    if(item.feeType=='措施费用'){//如果是措施费用,检查是否选取了记取位置或者清单编码是否存在
+                        positionCheck = true;
+                    }else if(item.feeType=='分项费用'&&(installSetting==undefined||installSetting=="0")){//当费用项是分项费用时,且选择了“整个项目统一计取”
+                        positionCheck = true;
+                    }
+                    if(positionCheck == true){
+                        let sections = install_fee.getInstallSectionsByfeeItemID(d.libID,item.ID);
+                        for(let s of sections){
+                            if(s.feeRuleId&&s.feeRuleId!=""){//有选中规则项
+                                let feeRule = install_fee.getFeeRuleByID(d.libID,s.feeRuleId);
+                                if(feeRule){
+                                    if((!feeRule.billID||feeRule.billID=="")&&(!feeRule.position||feeRule.position=="")){//清单ID和position都为空的时候
+                                         alert("计取位置不能为空!");
+                                         return
+                                    }
+                                    if (autoCreate == false){//不自动生成的时候才做检查
+                                        if(feeRule.billID&&feeRule.billID!=""){//先检查清单ID
+                                            let node = projectObj.project.mainTree.getNodeByID(item.billID);
+                                            if(!node){
+                                                let c = confirm("所选清单没有找到,需要自动生成吗?");
+                                                if(c){
+                                                    autoCreate = true;
+                                                }else {
+                                                    return;
+                                                }
+                                            }
+                                        }else if(feeRule.position && feeRule.position!=""){//再检查code
+                                            let bill = projectObj.project.Bills.getBillByCode(feeRule.position);
+                                            if(!bill){
+                                                let c = confirm("所选清单没有找到,需要自动生成吗?");
+                                                if(c){
+                                                    autoCreate = true;
+                                                }else {
+                                                    return;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        $('#calc_installation_fee').modal('hide');
+        install_fee.calcInstallationFee(function () {
+            projectObj.project.calcProgram.calcAllNodesAndSave();
+            gljOprObj.refreshView();
+            console.log("cal end");
+        });
     },
 };
 
 
 $(function () {
     $('#calc_installation_fee').on('shown.bs.modal',function () {
+        let installSetting = projectInfoObj.projectInfo.property.installSetting;
         if(installationFeeObj.feeItemSpread == null){//初始化显示
             installationFeeObj.initInstallationFeeSpread();
         }else {
             installationFeeObj.showFeeItemData();
             installationFeeObj.showFeeDetailData();
         }
+        //radio 值设置
+        if(installSetting==undefined||installSetting=="0"){
+            $("#all_project_calc").attr("checked","checked");
+            $("#FB_calc").attr("checked",false);
+        }else {
+            $("#all_project_calc").attr("checked",false);
+            $("#FB_calc").attr("checked","checked");
+        }
+
     });
     $('#calc_position').on('shown.bs.modal',function () {
         installationFeeObj.positionSelectedObject = null;
@@ -1206,10 +1276,22 @@ $(function () {
         if(canChange==false){
             return;
         }
-        let val = $('input[name="install_setting_radios"]:checked').val();
-        console.log(val);
+        me.calcInstallationFee();
+    });
+
 
+    $("input[name='install_setting_radios']").each(function(){
+        $(this).click(function(){
+            var settingVal = $(this).val();
+            let installSetting = projectInfoObj.projectInfo.property.installSetting;
+            if(installSetting==settingVal){
+                return;
+            }
+            projectObj.project.installation_fee.updateInstallSetting(settingVal);
+        });
     });
+
+
     $('#calc_installation_fee_close').click(function (){
         let me = installationFeeObj;
         let info = {
@@ -1221,7 +1303,7 @@ $(function () {
         if(canChange==false){
             return;
         }
-        $('#calc_installation_fee').modal('hide');
+        me.calcInstallationFee();
     });
 
     $('#more_feeRule_confirm').click(function (){

+ 2 - 0
web/building_saas/main/js/views/main_tree_col.js

@@ -16,6 +16,8 @@ let MainTreeCol = {
                 }
                 else if (node.data.type == 3) {    // 工料机定额
                     return projectObj.project.projectGLJ.getShortNameByID(node.data.subType);//工料机名字缩写
+                }else if(node.data.type == 4){//安装增加费生成的定额
+                    return '安';
                 }
             } else if (node.sourceType === projectObj.project.ration_glj.getSourceType()) {
                 return projectObj.project.projectGLJ.getShortNameByID(node.data.subType);//工料机名字缩写

+ 2 - 3
web/users/html/login.html

@@ -17,15 +17,14 @@
             <h1 class="d-flex justify-content-center">Smartcost</h1>
             <h4 class="d-flex justify-content-center mb-2">用户登录</h4>
             <div class="form-group">
-                <input id="inputEmail" class="form-control " name="inputEmail" placeholder="通行账号 邮箱/手机" autofocus="" value="laiku123@qq.com
-" />
+                <input id="inputEmail" class="form-control " name="inputEmail" placeholder="通行账号 邮箱/手机" autofocus="" value="laiku123@qq.com" />
             </div>
             <div class="form-group">
                 <input id="inputPassword" class="form-control " name="inputPassword" placeholder="输入密码" type="password" value="19930523" />
             </div>
             <div class="form-group" id="error-tips" style="display: none;">
                 <div class="alert alert-danger" role="alert">
-                    <strong>登录失败</strong> <span id="message"</span>
+                    <strong>登录失败</strong> <span id="message"></span>
                 </div>
             </div>
             <div class="form-group">