Преглед изворни кода

子目增加费,确认,取消

zhangweicheng пре 5 година
родитељ
комит
c7c908caea

+ 63 - 63
modules/main/facade/project_facade.js

@@ -270,79 +270,76 @@ async function calcOverHeightFee(data) {
 
 async function updateNodes(datas){
     let nodeGroups = _.groupBy(datas,'type');
-    let rationTasks = [];
-    let billTasks = [];
-    let rationGLJTasks = [];
-    let projectGLJTasks = [];
-    let projectTasks = [];
-    let rationTemplateTasks = [];
     let asyncTasks = [];
+    let deleteRationIDs=[];
+    let taskMap = {};
+    taskMap[projectConsts.BILLS] = {tasks:[],model:bill_model.model};
+    taskMap[projectConsts.RATION] = {tasks:[],model:ration_model.model};
+    taskMap[projectConsts.RATION_GLJ] = {tasks:[],model:ration_glj_model};
+    taskMap[projectConsts.PROJECTGLJ] = {tasks:[],model:project_glj_model};
+    taskMap[projectConsts.PROJECT] = {tasks:[],model:projectsModel};
+    taskMap[projectConsts.RATION_TEMPLATE] = {tasks:[],model:rationTemplateModel};
+
     for(let type in nodeGroups){
         for(let node of nodeGroups[type]){
-            if(type == projectConsts.BILLS){
-                billTasks.push(getTask(node));
-            }else if(type == projectConsts.RATION){
-                //处理面积增加费的数据
-                if(node.data.hasOwnProperty("areaIncreaseFee")){
-                    let areaSetting = null;
-                    if(nodeGroups[projectConsts.PROJECT]){
-                        for(let pn of nodeGroups[projectConsts.PROJECT]){
-                            if(pn.data['property.areaSetting']) areaSetting = pn.data['property.areaSetting'];
+            if(taskMap[type]){
+                if(type == projectConsts.RATION){
+                    //处理面积增加费的数据
+                    if(node.data.hasOwnProperty("areaIncreaseFee")){
+                        let areaSetting = null;
+                        if(nodeGroups[projectConsts.PROJECT]){
+                            for(let pn of nodeGroups[projectConsts.PROJECT]){
+                                if(pn.data['property.areaSetting']) areaSetting = pn.data['property.areaSetting'];
+                            }
                         }
+                        let t = await glj_calculate_facade.calculateQuantity({rationID:node.data.ID},true,false,node.data.areaIncreaseFee,areaSetting);
+                        node.data.adjustState = t.adjustState;
                     }
-                    let t = await glj_calculate_facade.calculateQuantity({rationID:node.data.ID},true,false,node.data.areaIncreaseFee,areaSetting);
-                    node.data.adjustState = t.adjustState;
+                    if(node.action == "delete") deleteRationIDs.push(node.data.ID);
                 }
-                rationTasks.push(getTask(node));
-            }else if(type == projectConsts.RATION_GLJ){
-                rationGLJTasks.push(getTask(node));
-            }else if(type == projectConsts.PROJECTGLJ){
-                projectGLJTasks.push(getTask(node,'id'));
-            }else if(type == projectConsts.PROJECT){
-                projectTasks.push(getTask(node));
-            }else if(type == projectConsts.RATION_TEMPLATE){
-                rationTemplateTasks.push(getTask(node))
+                if(type == projectConsts.RATION_GLJ){
+                    if(node.action == "add"){//添加定額工料机的時候,要先走项目工料机的逻辑
+                        let [newRecode,projectGLJ] = await createRationGLJData(node.data);
+                        node.data =newRecode;
+                        node.projectGLJ = projectGLJ;
+                    }
+                }
+                taskMap[type].tasks.push(getTask(node));
             }
-
         }
     }
-    //test------------------------
-    if (billTasks.length) {
-        console.log(`billTasks===============================`);
-        billTasks.forEach(task => {
-            if (task.updateOne.update.name === '分部分项工程') {
-                console.log(`task.updateOne.filter`);
-                console.log(task.updateOne.filter);
-                console.log(`task.updateOne.update`);
-                console.log(task.updateOne.update);
-            }
-            /*console.log(`task.updateOne.filter`);
-            console.log(task.updateOne.filter);
-            console.log(`task.updateOne.update`);
-            console.log(task.updateOne.update);*/
-        });
+
+    for(let key in taskMap){
+        if(taskMap[key].tasks.length> 0) asyncTasks.push(taskMap[key].model.bulkWrite(taskMap[key].tasks))
     }
-    //test------------------------
-    rationTasks.length>0?asyncTasks.push(ration_model.model.bulkWrite(rationTasks)):'';
-    billTasks.length>0?asyncTasks.push(bill_model.model.bulkWrite(billTasks)):"";
-    rationGLJTasks.length>0?asyncTasks.push(ration_glj_model.bulkWrite(rationGLJTasks)):"";
-    projectGLJTasks.length>0?asyncTasks.push(project_glj_model.bulkWrite(projectGLJTasks)):"";
-    projectTasks.length>0?asyncTasks.push(projectsModel.bulkWrite(projectTasks)):"";
-    rationTemplateTasks.length>0?asyncTasks.push(rationTemplateModel.bulkWrite(rationTemplateTasks)):"";
-    asyncTasks.length>0?await Promise.all(asyncTasks):"";
+
+    if(asyncTasks.length>0) await Promise.all(asyncTasks);
+    if(deleteRationIDs.length > 0) await ration_glj_model.deleteMany({rationID: {$in: deleteRationIDs}});
+
+
     return datas;
 
 
     function getTask(node,idFiled = 'ID') {
-
-        let task={
-            updateOne:{
+        let task={};
+        if(node.action == "add"){
+            task.insertOne ={
+                document:node.data
+            }
+        }else if(node.action =="delete"){
+            task.deleteOne ={
+                filter:{}
+            };
+            task.deleteOne.filter[idFiled] = node.data[idFiled];
+        }else {
+            task.updateOne = {
                 filter:{},
                 update :_.cloneDeep(node.data)
-            }
-        };
-        task.updateOne.filter[idFiled] = node.data[idFiled];//现在复制项目也重新生成一个新的ID了,所以ID是唯一的
-        delete task.updateOne.update[idFiled];//防止误操作
+            };
+            task.updateOne.filter[idFiled] = node.data[idFiled];//现在复制项目也重新生成一个新的ID了,所以ID是唯一的
+            delete task.updateOne.update[idFiled];//防止误操作
+        }
+
         return task;
     }
 }
@@ -557,12 +554,15 @@ async function setSEILibData(property){
 }
 
 function setDefaultItemIncrease(property) {
-    property.itemIncreaseSetting = [
-        {"name":"在生产车间边生产边施工","base":"人工费","coe":10,"scope":{}},
-        {"name":"在有害身体健康的场所内施工","base":"人工费","coe":10,"scope":{}},
-        {"name":"在洞内、地下室内、库内或暗室内进行施工","base":"人工费","coe":40,"scope":{}},
-        {"name":"在洞内、地下室内、库内或暗室内进行施工(模板拆除)","base":"人工费","coe":10,"scope":{}}
-    ]
+    property.itemIncreaseSetting = {
+        isCalc : false,
+        setting:[
+            {"name":"在生产车间边生产边施工","base":"人工费","coe":10,"scope":{}},
+            {"name":"在有害身体健康的场所内施工","base":"人工费","coe":10,"scope":{}},
+            {"name":"在洞内、地下室内、库内或暗室内进行施工","base":"人工费","coe":40,"scope":{}},
+            {"name":"在洞内、地下室内、库内或暗室内进行施工(模板拆除)","base":"人工费","coe":10,"scope":{}}
+        ]
+    }
 }
 
 async function getIndexReportData(projectID,keyArr) {

+ 9 - 1
public/web/gljUtil.js

@@ -584,7 +584,15 @@ let gljUtil = {
             return v !== undefined && v !== null;
         }
     },
-
+    setProperty:function(Obj,updateData) {
+        for(let ukey in updateData){
+            if(_.isObject(updateData[ukey]) && _.isObject(Obj[ukey])){
+                setProperty(Obj[ukey],updateData[ukey]);
+            }else {
+                Obj[ukey] = updateData[ukey];
+            }
+        }
+    },
     fixedFlag : {
         // 分部分项工程
         SUB_ENGINERRING: 1,

+ 14 - 10
public/web/sheet/sheet_common.js

@@ -179,7 +179,6 @@ var sheetCommonObj = {
             if(setting.header[col].cellType === "comboBox"){
                 this.setComboBox(-1,col,sheet,setting.header[col].options,setting.header[col].editorValueType,setting.header[col].editable,setting.header[col].maxDropDownItems);
             }
-
             for (let row = 0; row < data.length; row++) {
                 if(data[row].cellType === 'comboBox'){
                     let options = data[row].options ? data[row].options.split("@") : [];
@@ -197,6 +196,9 @@ var sheetCommonObj = {
                         val =scMathUtil.roundToString(val,2);
                     }
                 }
+                if(val!=null && setting.header[col].cellType == "checkBox"){
+                    this.setCheckBoxCell(row,col,sheet,val);
+                }
                 sheet.setValue(row, col, val, ch);
                 if(col==0){
                     let treeType = sheetCommonObj.getTreeNodeCellType(data,row,parentMap);
@@ -334,6 +336,11 @@ var sheetCommonObj = {
         for (var col = 0; col < setting.header.length; col++) {
             //var cell = sheet.getCell(row, col, GC.Spread.Sheets.SheetArea.viewport);
             var val = data[row][setting.header[col].dataCode];
+            let style = null;
+            if(data[row].foreColor && data[row].styleCol == col){
+                style = {foreColor: data[row].foreColor};
+                sheet.setStyle(row, col, {foreColor: data[row].foreColor});
+            }
             if(val&&setting.header[col].dataType === "Number"){
                 if(setting.header[col].hasOwnProperty('tofix')){
                     val =scMathUtil.roundToString(val,setting.header[col].tofix);
@@ -359,7 +366,7 @@ var sheetCommonObj = {
                 this.setReplaceButton(row,col,sheet,setting.header[col]);
             }
             if(setting.header[col].cellType === "cusButton"){
-                this.setCusButton(row,col,sheet,setting);
+                this.setCusButton(row,col,sheet,setting,style);
             }
             if(setting.header[col].cellType === "tipsCell"){
                 this.setTipsCell(row,col,sheet,setting.header[col]);
@@ -378,9 +385,6 @@ var sheetCommonObj = {
                 val = setting.getText[setting.header[col].getText](data[row],val)
             }
             sheet.setValue(row, col, val, ch);
-            if(data[row].foreColor && data[row].styleCol == col){
-                sheet.setStyle(row, col, {foreColor: data[row].foreColor});
-            }
         }
         this.setRowStyle(row,sheet,data[row].bgColour);
         if(setting.autoFit==true){//设置自动行高
@@ -666,25 +670,24 @@ var sheetCommonObj = {
         sheet.setCellType(row, col,this.getSelectButton(header.headerWidth),GC.Spread.Sheets.SheetArea.viewport);
     },
 
-    setCusButton:function (row,col,sheet,setting) {
+    setCusButton:function (row,col,sheet,setting,style) {
         let functionName = setting.header[col].callback;
-        let readOnly = setting.disable[setting.header[col].disable];
+        let readOnly = setting.disable?setting.disable[setting.header[col].disable]:false;
         if(typeof(readOnly) == 'function' ){
             readOnly = readOnly(row,col);
         }
         if(functionName){
-            sheet.setCellType(row, col,this.getCusButtonCellType(setting.callback[functionName],readOnly));
+            sheet.setCellType(row, col,this.getCusButtonCellType(setting.callback[functionName],readOnly,style));
         }
         //sheet.setCellType(row, col,this.getSelectButton(header.headerWidth),GC.Spread.Sheets.SheetArea.viewport);
     },
 
-    getCusButtonCellType:function (callback,readOnly=false) {
+    getCusButtonCellType:function (callback,readOnly=false,ostyle) {
         var ns = GC.Spread.Sheets;
         function CusButtonCellType() {
         }
         CusButtonCellType.prototype = new ns.CellTypes.Text();
         CusButtonCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
-
             if(!readOnly){
                 if(options.sheet.getActiveRowIndex()==options.row&&options.sheet.getActiveColumnIndex()==options.col){
                     var image = document.getElementById('f_btn'),imageMagin = 3;
@@ -718,6 +721,7 @@ var sheetCommonObj = {
                     }
                 }
             }
+            if(ostyle)  gljUtil.setProperty(style,ostyle);
             GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
         };
         CusButtonCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {

+ 11 - 1
public/web/tree_sheet/tree_sheet_controller.js

@@ -207,8 +207,18 @@ var TREE_SHEET_CONTROLLER = {
             TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
                 TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, nodes, recursive)
             })
-        }
+        };
 
+        controller.prototype.setTreeSelection = function (oldSelect) {
+            let controller = this;
+            let sel = controller.sheet.getSelections()[0];
+            if(controller.tree.getNodeByID(oldSelect.getID())){//如果旧选中节点还存在
+                controller.sheet.setSelection(oldSelect.serialNo(),sel.col,sel.rowCount,sel.colCount);
+                controller.setTreeSelected(oldSelect)
+            }else {//选中节点已被删除,自动选中新的节点
+                controller.setTreeSelected(controller.tree.items[sel.row]);
+            }
+        };
         controller.prototype.setTreeSelected = function (node) {
             if (this.event.beforeTreeSelectedChange) {
                 this.event.beforeTreeSelectedChange(this.tree.selected);

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

@@ -2324,7 +2324,7 @@
                 </button>
             </div>
             <div class="modal-body" style="height: 200px;padding: 0px">
-                <div class="ovf-hidden full-h" id="itemIncreaseFee_sheet"></div>
+                <div class="ovf-hidden full-h" id="itemIncreaseFee_sheet" style="height: 100%"></div>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-primary" data-dismiss="modal" id="itemIncreaseFeeConfirm">确定</button>
@@ -2334,7 +2334,28 @@
     </div>
 </div>
 
-
+<!--弹出 子目增加费范围选择树-->
+<div class="modal fade" id="item_increase_scope" data-backdrop="static" style="z-index: 1060">
+    <div class="modal-dialog modal-lg"  role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">指定范围</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body" style="padding: 0px">
+                <div class="row" style="height:400px"><!--sjs id设置在这个div-->
+                    <div class="col-12" style="height: 100%;overflow: hidden" id="scopeSheet"></div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button class="btn btn-primary" data-dismiss="modal", id="select_scope_confirm">确定</button>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</div>
 
     <img src="/web/dest/css/img/folder_open.png" id="folder_open_pic" style="display: none">
     <img src="/web/dest/css/img/folder_close.png" id="folder_close_pic" style="display: none">

+ 2 - 1
web/building_saas/main/js/models/main_consts.js

@@ -138,7 +138,8 @@ const rationType = {
     volumePrice: 2,
     gljRation: 3,
     install:4,
-    overHeight: 5 // 超高子目
+    overHeight: 5, // 超高子目
+    itemIncrease:6//子目增加
 };
 const rationPrefix = { //定额前缀,补/借
     none: '',

+ 73 - 5
web/building_saas/main/js/models/project.js

@@ -539,17 +539,38 @@ var PROJECT = {
 
         project.prototype.updateNodesCache =function (datas) {
             let refreshNode = [];
+            let reclacQuantity = false;
+            let deleteNode=[],addNodeDatas=[];
             for(let d of datas){
                 let temObj = null;
                 if(d.type == ModuleNames.bills || d.type == ModuleNames.ration){//如果是树节点类型,直接取树节点更新
-                    let temNode = this.mainTree.getNodeByID(d.data.ID);
-                    if(temNode){
-                        temObj = temNode.data;
-                        refreshNode.push(temNode);
+                    if(d.action =="add"){
+                        if(d.type == ModuleNames.ration) this.Ration.datas.push(d.data);
+                        reclacQuantity = true;
+                        addNodeDatas.push(d);
+                    }else {
+                        let temNode = this.mainTree.getNodeByID(d.data.ID);
+                        if(temNode){
+                            if(d.action =="delete"){
+                                if(d.type == ModuleNames.ration){
+                                    _.remove(this.Ration.datas,{'ID':d.data.ID});
+                                    this.Ration.deleteSubListOfRation({ID:d.data.ID});
+                                    reclacQuantity = true;
+                                }
+                                deleteNode.push(temNode);//对于删除节点,统一不加入refreshNode中,由外部加入,避免重复
+                            }else {
+                                temObj = temNode.data;
+                                if(gljUtil.isDef(d.data.quantity))reclacQuantity = true;
+                                refreshNode.push(temNode);
+                            }
+                        }
                     }
                 }else if(d.type == ModuleNames.project){
                     temObj = this;
-                }else {//其它类型,更新datas
+                }else if (d.type == ModuleNames.ration_glj && d.action == "add"){
+                    this[d.type].datas.push(d.data);
+                    if(d.projectGLJ) this.projectGLJ.loadNewProjectGLJToCache(d.projectGLJ);
+                } else {//其它类型,更新datas
                     temObj = _.find(this[d.type].datas,{"ID":d.data.ID});
                 }
                 if(temObj){
@@ -561,7 +582,54 @@ var PROJECT = {
                     }
                 }
             }
+
+            //对树节点的操作并删除、添加清单、删除添加定额、删除对应的定额工料机缓存
+            TREE_SHEET_HELPER.massOperationSheet(projectObj.mainController.sheet, function () {
+                deleteTreeNodes(deleteNode);
+                addNewNodes(addNodeDatas,refreshNode);
+            });
+
+
+            if(reclacQuantity) this.projectGLJ.calcQuantity();
             return refreshNode;
+
+
+
+
+            function deleteTreeNodes(deleteNodes) {
+                let controller = projectObj.mainController, project = projectObj.project;
+                let Bill = project.Bills, Ration = project.Ration;
+                for(let rd of deleteNodes){
+                    controller.sheet.deleteRows(rd.serialNo(),1);
+                    controller.tree.delete(rd);
+                    if(rd.sourceType == Bill.getSourceType()) Bill.tree.delete(rd.source);
+                }
+            }
+            function addNewNodes(newDatas,refreshNode) {
+                let controller = projectObj.mainController;
+                let Bill = projectObj.project.Bills;
+                let newAddNode = [];
+                for(let nr of newDatas){
+                    let nextID = -1;
+                    let preNode = projectObj.project.mainTree.getNodeByID(nr.preSiblingID);
+                    if(preNode) nextID = preNode.getNextSiblingID();
+                    let newNode = projectObj.project.mainTree.insert(nr.parentID, nextID, nr.data.ID);
+                    if(nr.type == ModuleNames.bills){
+                        let newSource = Bill.tree.insertByData(nr.data, nr.ParentID, nextID, true);
+                        newNode.source = newSource;
+                    }else {
+                        newNode.source = nr.data;
+                    }
+                    newNode.sourceType = nr.type;
+                    newNode.data = nr.data;
+                    controller.sheet.addRows(newNode.serialNo(), 1);
+                    controller.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+                    newAddNode.push(newNode);
+                    refreshNode.push(newNode);
+                }
+                TREE_SHEET_HELPER.refreshTreeNodeData(controller.setting, controller.sheet, newAddNode, false);
+            }
+
         };
         project.prototype.setValue=function (obj,key,value) {
             let keyArray = key.split('.');

+ 380 - 16
web/building_saas/main/js/views/item_increase_fee_view.js

@@ -7,19 +7,39 @@ let itemIncreaseFeeObj = {
     itemSetting:{
         header:[
             {headerName: "名称", headerWidth: 270, dataCode: "name", dataType: "String"},
-            {headerName: "范围", headerWidth: 70, dataCode: "displayScope",hAlign: "center",dataType: "String"},
+            {headerName: "范围", headerWidth: 70, dataCode: "displayScope",hAlign: "center",dataType: "String",cellType:'cusButton',callback:'selectScope'},
             {headerName: "取费基数", headerWidth: 150, dataCode: "base",  hAlign: "center", dataType: "String",cellType:'comboBox',options:itemBaseOptions},
             {headerName: "系数(%)", headerWidth: 55, dataCode: "coe", hAlign: "center", dataType: "Number",validator:"number"}
         ],
         view: {
-            lockColumns: ["code","specs"],
+            lockColumns: ["name","displayScope"],
             rowHeaderWidth:25,
             colHeaderHeight:36
         },
         autoFit:true,
-        fitRow:['name']
+        fitRow:['name'],
+        callback:{
+            selectScope:function (hitinfo) {
+                $("#item_increase_scope").modal('show');
+            }
+        }
     },
     settingDatas:[],
+    scopeSpread:null,
+    scopeSetting:{
+        header:[
+            {headerName: "编码", headerWidth: 250, dataCode: "code", dataType: "String"},
+            {headerName: "类别", headerWidth: 100, dataCode: "type",hAlign: "center",dataType: "String"},
+            {headerName: "名称", headerWidth: 300, dataCode: "name", dataType: "String"},
+            {headerName: "计取", headerWidth: 100, dataCode: "selected", hAlign: "center", dataType: "String",cellType:'checkBox'}
+        ],
+        view: {
+            lockColumns: ["name","code","type","selected"],
+            rowHeaderWidth:25,
+            colHeaderHeight:36
+        }
+    },
+    scopeDatas:[],
     initSpread:function () {
         if(this.settingSpread) return this.settingSpread.refresh();
         this.settingSpread = SheetDataHelper.createNewSpread($("#itemIncreaseFee_sheet")[0]);
@@ -28,16 +48,86 @@ let itemIncreaseFeeObj = {
         sheetCommonObj.initSheet(this.settingSheet, this.itemSetting, 4);
         this.settingSheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onItemSelectionChange);
         this.settingSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onItemValueChange);
-    /*   ;
-
-        this.settingSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onElectrovalenceEditStarting);*/
-        /*
-         ;*/
         this.settingSheet.name('itemIncreaseFee_sheet');
         if(projectReadOnly){
             disableSpread(this.settingSpread);
         }
     },
+    initScopeSpread:function () {
+        if(this.scopeSpread) return this.scopeSpread.refresh();
+        this.scopeSpread = SheetDataHelper.createNewSpread($("#scopeSheet")[0]);
+        sheetCommonObj.spreadDefaultStyle(this.scopeSpread);
+        this.scopeSheet = this.scopeSpread.getSheet(0);
+        sheetCommonObj.initSheet(this.scopeSheet, this.scopeSetting, 0);
+        this.scopeSpread.bind(GC.Spread.Sheets.Events.ButtonClicked, this.onScopeCheckBoxClick);
+        this.scopeSheet.name('scopeSheet');
+        if(projectReadOnly){
+            disableSpread(this.scopeSpread);
+        }
+    },
+    getSelectedItem:function () {
+        let selectedItem = null;
+        let sel = this.settingSheet.getSelections()[0];
+        if(sel.row != -1 && this.settingDatas.length>sel.row){
+            selectedItem = this.settingDatas[sel.row];
+        }
+        return selectedItem;
+    },
+    showScopeDatas:function () {
+        let controller = projectObj.mainController, project = projectObj.project;
+        let allNodes=[];
+        this.scopeDatas=[];
+        let selectedItem = this.getSelectedItem();
+        let fbfcNode = project.Bills.getFBFXNode(controller).source;//分部分项节点
+        if(fbfcNode){
+            allNodes.push(fbfcNode);
+            controller.tree.getAllSubNode(project.Bills.getFBFXNode(controller).source,allNodes);
+        }
+        let meaNode = project.Bills.getMeasureNode(controller).source;//措施项目节点
+        if(meaNode){
+            allNodes.push(meaNode);
+            controller.tree.getAllSubNode(project.Bills.getMeasureNode(controller).source,allNodes);
+        }
+        for(let row=0;row<allNodes.length;row++){
+            let node = allNodes[row];
+            let tem = {
+                ID:node.data.ID,
+                ParentID:node.data.ParentID,
+                code:node.data.code,
+                name:node.data.name,
+                type:billText[node.data.type],
+                selected:0,
+                collapsed:false,
+                row:row
+            };
+            if(selectedItem && selectedItem.scope&&selectedItem.scope[tem.ID]) tem.selected = 1;
+            this.scopeDatas.push(tem);
+        }
+        this.scopeSheet.setRowCount(this.scopeDatas.length);
+        sheetCommonObj.showTreeData(this.scopeSheet, this.scopeSetting,this.scopeDatas);
+    },
+    onScopeCheckBoxClick:function (sender,args) {
+        let me = itemIncreaseFeeObj;
+        let checkboxValue = args.sheet.getCell(args.row, args.col).value();
+        let newval = 0;
+        checkboxValue?newval=0:newval=1;
+        let record = me.scopeDatas[args.row];
+        let dataMap= _.groupBy(me.scopeDatas,"ParentID");
+        args.sheet.suspendPaint();
+        args.sheet.suspendEvent();
+        cascadeSelected(record,newval);
+        args.sheet.resumeEvent();
+        args.sheet.resumePaint();
+        function cascadeSelected(parent,val) {
+            args.sheet.getCell(parent.row, args.col).value(val);
+            parent.selected = val;
+            if(dataMap[parent.ID]){
+                for(let c of dataMap[parent.ID]){
+                    cascadeSelected(c,val);
+                }
+            }
+        }
+    },
     onItemSelectionChange:function (sender,args) {
         args.sheet.repaint();
     },
@@ -46,20 +136,29 @@ let itemIncreaseFeeObj = {
         let oldData = sel.row<this.settingDatas.length?this.settingDatas[sel.row]:"";
         this.settingSheet.setRowCount(0);
         this.settingDatas = datas?datas:this.getItemSettingDatas();
+        this.setItemForeStyle(this.settingDatas);
         sheetCommonObj.showData(this.settingSheet, this.itemSetting,this.settingDatas);
         this.settingSheet.setRowCount(this.settingDatas.length);
         sel.row =  oldData?_.findIndex(this.settingDatas,{'name':oldData.name}):sel.row ;
         this.settingSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
     },
+    setItemForeStyle:function (datas) {
+        for(let d of datas){
+            if(_.isEmpty(d.scope)){
+                d.foreColor = "#ff2a23";
+                d.styleCol = 1;
+            }else {
+                delete  d.foreColor;
+                delete  d.styleCol;
+            }
+        }
+    },
+
     getItemSettingDatas:function () {
         let datas = [];
         if(projectObj.project.property.itemIncreaseSetting){
-            for(let i of projectObj.project.property.itemIncreaseSetting){
+            for(let i of projectObj.project.property.itemIncreaseSetting.setting){
                 let d = {name:i.name,displayScope:"范围",scope:i.scope,base:i.base,coe:i.coe};
-                if(_.isEmpty(d.scope)){
-                    d.foreColor = "#ff2a23";
-                    d.styleCol = 1;
-                }
                 datas.push(d);
             }
         }
@@ -79,6 +178,259 @@ let itemIncreaseFeeObj = {
         }
         tem[dataCode] = value;
         me.showDatas(me.settingDatas);
+        me.itemChange = true;
+    },
+    confirmScope:function(){
+        let selectedItem = this.getSelectedItem();
+        let scope = {};
+        for(let n of this.scopeDatas){
+            if(n.selected == 1) scope[n.ID] = true;
+        }
+        if(JSON.stringify(scope) != JSON.stringify(selectedItem.scope)) this.itemChange = true;//有改变的情况下才更新
+        selectedItem.scope=scope;
+        this.showDatas(this.settingDatas);
+    },
+    confirmItemIncreaseSetting:async function () {
+        if(this.itemChange == true || projectObj.project.property.itemIncreaseSetting.isCalc == false){
+            let datas = [];
+            let itemIncreaseSetting = {
+                isCalc : true,
+                setting :[]
+            };
+            for(let d of this.settingDatas){
+                itemIncreaseSetting.setting.push({name:d.name,scope:d.scope,base:d.base,coe:d.coe});
+            }
+            let tem ={
+                type:'project',
+                data:{ID:projectObj.project.ID(),"property.itemIncreaseSetting":itemIncreaseSetting}
+            };
+            datas.push(tem);
+            let changeNodes = this.calcAllItemIncreaseFee(itemIncreaseSetting,datas);
+            console.log(datas);
+            let selectedNode = projectObj.project.mainTree.selected;
+            //刷新缓存和树节点的插入删除
+            let nodes = await projectObj.project.syncUpdateNodesAndRefresh(datas);
+            //重新计算
+            cbTools.refreshFormulaNodes();
+            projectObj.project.calcProgram.calcNodesAndSave(changeNodes.concat(nodes));
+            projectObj.mainController.setTreeSelection(selectedNode);
+
+        }
+    },
+    cancelItemIncreaseFee:async function () {
+        let itemIncreaseSetting = projectObj.project.property.itemIncreaseSetting;
+        let datas = [];
+        let refreshNodes = [];
+        if(itemIncreaseSetting && itemIncreaseSetting.isCalc == true){
+            itemIncreaseSetting.isCalc = false;
+            let billNodeMap = {};
+            let tem ={
+                type:'project',
+                data:{ID:projectObj.project.ID(),"property.itemIncreaseSetting":itemIncreaseSetting}
+            };
+            datas.push(tem);
+            for(let s of itemIncreaseSetting.setting){
+                if(!_.isEmpty(s.scope)){
+                    for (let ID in s.scope){
+                        billNodeMap[ID] = true;//为了去重复
+                    }
+                }
+            }
+            for(let cancelID in billNodeMap){
+                let tnode = projectObj.project.mainTree.getNodeByID(cancelID);
+                if(tnode){
+                    let cNode = this.cancelBillNode(tnode,datas);
+                    if(cNode) refreshNodes.push(cNode);
+                }
+            }
+            let selectedNode = projectObj.project.mainTree.selected;
+            //刷新缓存和树节点的插入删除
+            await projectObj.project.syncUpdateNodesAndRefresh(datas);
+            if(refreshNodes.length > 0){
+                //重新计算
+                cbTools.refreshFormulaNodes();
+                projectObj.project.calcProgram.calcNodesAndSave(refreshNodes);
+                projectObj.mainController.setTreeSelection(selectedNode);
+            }
+        }
+    },
+    getAllBillsIDMap:function () {
+        let map = {};
+        let itemIncreaseSetting = projectObj.project.property.itemIncreaseSetting;
+        if(itemIncreaseSetting.isCalc == true){
+            for(let s of itemIncreaseSetting.setting){
+                if(!_.isEmpty(s.scope)){
+                    for (let ID in s.scope){
+                        map[ID] = true;
+                    }
+                }
+            }
+        }
+        return map;
+    },
+
+    calcAllItemIncreaseFee : function(setting,datas){
+        let refreshNodes = [];
+        let itemIncreaseSetting = setting?setting:projectObj.project.property.itemIncreaseSetting;
+        let billNodeMap = {},rationGLJMap={};
+        let cancelBillsIDMap = this.getAllBillsIDMap();
+        if(itemIncreaseSetting && itemIncreaseSetting.isCalc == true){
+            //为了不用循环所有节点,先挑出所有受影响的节点
+            for(let s of itemIncreaseSetting.setting){
+                if(!_.isEmpty(s.scope)){
+                    for (let ID in s.scope){
+                        billNodeMap[ID] = true;//为了去重复
+                        delete cancelBillsIDMap[ID];
+                    }
+                }
+            }
+            for(let billsID in billNodeMap){
+                let node = projectObj.project.mainTree.getNodeByID(billsID);
+                let newRefreshNodes = this.calcItemIncreasePerNode(node,itemIncreaseSetting,rationGLJMap,datas);
+                if(newRefreshNodes.length > 0) refreshNodes = refreshNodes.concat(newRefreshNodes);
+            }
+            //删除取消范围的清单下的子目定额
+            for(let cancelID in cancelBillsIDMap){
+                let tnode = projectObj.project.mainTree.getNodeByID(cancelID);
+                let cNode = this.cancelBillNode(tnode,datas);
+                if(cNode) refreshNodes.push(cNode);
+            }
+        }
+        return refreshNodes;
+    },
+    cancelBillNode:function (node,datas) {
+        if (node.children.length <= 0) return null;//如果没子项,不用计算
+        if (node.source.children.length > 0) return null;//如果不是清单叶子节点,不用计算
+        let isDelete = false;
+        for(let rationNode of node.children){
+            if(rationNode.data.code.indexOf("ZMZJF")!= -1){
+                datas.push({type:ModuleNames.ration,data:{ID:rationNode.data.ID},action:"delete"});
+                isDelete = true;
+            }
+        }
+        return isDelete == true?node:null;
+    },
+
+
+    calcItemIncreasePerNode:function (node,setting,rationGLJMap,datas) {
+        let itemIncreaseSetting = setting ? setting : projectObj.project.property.itemIncreaseSetting;
+        let refreshNodes = [],rationCodeMap={},FeeMap={},updateDataIDMap={};
+        if (node.children.length <= 0) return [];//如果没子项,不用计算
+        if (node.source.children.length > 0) return [];//如果不是清单叶子节点,不用计算
+        let labourTotal = 0,materialTotal=0,machineTotal=0;
+        let process = getDecimal("process");
+        let td = getDecimal("ration.totalPrice");
+        let gd = getDecimal('glj.quantity');
+        let preID="",serialNo=1;
+        for(let rationNode of node.children){
+            rationCodeMap[rationNode.data.code] = rationNode;
+            if(rationNode.data.type == rationType.ration || rationNode.data.type == rationType.volumePrice ){//先只汇总定额和量价类型,不考虑自动生成的
+                //计算人工费,材料费,机械费
+                if(rationNode.data.feesIndex){
+                    let labour = rationNode.data.feesIndex.labour && rationNode.data.feesIndex.labour.totalFee?parseFloat(rationNode.data.feesIndex.labour.totalFee):0;
+                    let material = rationNode.data.feesIndex.material && rationNode.data.feesIndex.material.totalFee?parseFloat(rationNode.data.feesIndex.material.totalFee):0;
+                    let machine = rationNode.data.feesIndex.machine && rationNode.data.feesIndex.machine.totalFee?parseFloat(rationNode.data.feesIndex.machine.totalFee):0;
+                    labourTotal = scMathUtil.roundForObj(labourTotal + labour,getDecimal("process"));
+                    materialTotal = scMathUtil.roundForObj(materialTotal + material,getDecimal("process"));
+                    machineTotal = scMathUtil.roundForObj(machineTotal + machine,getDecimal("process"));
+                }
+            }
+            if(rationNode.data.type != rationType.itemIncrease ){//计录除了子目增加节点外最后的节点ID,和nexeID
+                preID = rationNode.data.ID;
+                serialNo = rationNode.data.serialNo;
+            }
+        }
+        FeeMap['人工费'] = labourTotal;
+        FeeMap['材料费'] = materialTotal;
+        FeeMap['机械费'] = machineTotal;
+        //ZMZJF_1
+        let s_in = 0;//序列号增长
+        for(let i = 0; i < itemIncreaseSetting.setting.length;i++){
+            let s = itemIncreaseSetting.setting[i];
+            if(s.scope&&s.scope[node.data.ID]){
+                let feeIndexArry = s.base.split("+");
+                let total = 0;
+                for(let index of feeIndexArry){
+                    total = scMathUtil.roundForObj(total + FeeMap[index],process);
+                }
+                total = scMathUtil.roundForObj(total,td);
+                if(s.coe){
+                    let t = scMathUtil.roundForObj(total * s.coe/100,process);
+                    total =  scMathUtil.roundForObj(total + t,gd);
+                }
+                let seq = i+1;
+                let code = "ZMZJF_"+seq;
+                let ZMZJFnode = rationCodeMap[code];
+                if(total > 0) {
+                    if(ZMZJFnode){//存在的话更新其它人工费消耗量
+                        this.updateItemNode(ZMZJFnode,total,rationGLJMap,datas);
+                        if(s_in>0){
+                            datas.push({type:ModuleNames.ration,data:{ID:ZMZJFnode.data.ID,serialNo:ZMZJFnode.data.serialNo +1}});
+                        } else {//如果s_in>0时,ZMZJFnode会因为有更新而刷新,不用push到refreshNodes里
+                            refreshNodes.push(ZMZJFnode);
+                        }
+                        preID = ZMZJFnode.data.ID;
+                        serialNo = ZMZJFnode.data.serialNo;
+                    }else {//不存在的话插入新的节点
+                        s_in = s_in +1;
+                        serialNo = serialNo+1;
+                        let newRationData = this.inserNewItemNodes(node.data.ID,node.data.quantity,preID,serialNo,code,s.name,total,datas);
+                        preID = newRationData.ID;
+                    }
+                }else { //如果total小于0,但又存在的话,删除定额(同时后端处理时记得要删除定额工料机)
+                    if(ZMZJFnode){
+                        datas.push({type:ModuleNames.ration,data:{ID:ZMZJFnode.data.ID},action:"delete"});
+                        if(refreshNodes.length == 0) refreshNodes.push(node);//删除时,如果清单下没有定额更新,则刷新清单节点就行
+                    }
+                }
+            }
+        }
+        return refreshNodes;
+    },
+    updateItemNode:function (node,total,rationGLJMap,datas) {
+        if(_.isEmpty(rationGLJMap)) this.setRationGLJMap(rationGLJMap);
+        if(rationGLJMap[node.data.ID] && rationGLJMap[node.data.ID].quantity != total){
+            datas.push({type:ModuleNames.ration_glj,data:{ID:rationGLJMap[node.data.ID].ID,quantity:total}})
+        }
+    },
+    setRationGLJMap:function (rationGLJMap) {
+        let gljList =  projectObj.project.ration_glj.datas;
+        for (let g of gljList){
+            if(g.code == 'QTRGF') rationGLJMap[g.rationID] = g;
+        }
+    },
+    inserNewItemNodes:function (billsItemID,billsQuantity,preID,serialNo,code,name,total,datas) {
+        let Ration = projectObj.project.Ration;
+        let newRationData = Ration.getTempRationData(Ration.getNewRationID(), billsItemID, serialNo, rationType.itemIncrease);
+        newRationData.code = code;
+        newRationData.name=name;
+        newRationData.unit = '元';
+        newRationData.quantity = "1";
+        if(billsQuantity) newRationData.contain = scMathUtil.roundForObj(1/parseFloat(billsQuantity),getDecimal("process"))+"";
+        newRationData.quantityEXP = '1';
+        datas.push({type:ModuleNames.ration,data:newRationData,preSiblingID:preID,action:"add",parentID:billsItemID});
+        let newRationGLJ = {
+            rationID:newRationData.ID,
+            billsItemID:billsItemID,
+            shortName:projectObj.project.projectGLJ.getShortNameByID(gljType.LABOUR),
+            GLJID:-1,
+            projectID:newRationData.projectID,
+            code:'QTRGF',
+            original_code:'QTRGF',
+            name:'其它人工费',
+            specs:'',
+            unit:'元',
+            type:gljType.LABOUR,
+            basePrice:1,
+            marketPrice:1,
+            adjCoe:null,
+            from:'std',
+            repositoryId:-1,
+            quantity:total+"",
+            rationItemQuantity:total+""
+        };
+        datas.push({type:ModuleNames.ration_glj,data:newRationGLJ,action:"add"});
+        return newRationData;
     }
 };
 
@@ -88,12 +440,24 @@ let itemIncreaseFeeObj = {
 
 
 $(function () {
-   /* $("#areaIncreaseFeeConfirm").on("click",async function(e){
-        areaIncreaseFeeObj.confirmAreaIncreaseFeeSetting();
-    });*/
+
 
     $('#itemIncreaseFeeDiv').on('shown.bs.modal', function (e) {
+        itemIncreaseFeeObj.itemChange = false;
         itemIncreaseFeeObj.initSpread();
         itemIncreaseFeeObj.showDatas();
     });
+
+    $('#item_increase_scope').on('shown.bs.modal', function (e) {
+        itemIncreaseFeeObj.initScopeSpread();
+        itemIncreaseFeeObj.showScopeDatas();
+    });
+    
+    $("#select_scope_confirm").click(function () {
+        itemIncreaseFeeObj.confirmScope();
+    })
+
+    $("#itemIncreaseFeeConfirm").click(function () {
+        itemIncreaseFeeObj.confirmItemIncreaseSetting();
+    })
 });

+ 1 - 3
web/building_saas/main/js/views/project_view.js

@@ -1556,9 +1556,7 @@ var projectObj = {
                             name:"取消子目增加费",
                             icon: 'fa-sign-in',
                             callback:function(){
-                                /*colSettingObj.setVisible('areaIncreaseFee', false);
-                                colSettingObj.updateColSetting(true);
-                                areaIncreaseFeeObj.cancelAreaIncreaseFee();*/
+                                itemIncreaseFeeObj.cancelItemIncreaseFee();
                             }
                         }
                     }

+ 4 - 0
web/building_saas/main/js/views/sub_view.js

@@ -785,6 +785,10 @@ $('#linkGLJ').on('shown.bs.tab', function () {
 
 $('#linkQDJL').on('shown.bs.tab', function () {
     subObj.showQDSubTabData();
+    /*if(!subObj.inited) {
+        $("#tz_toogle").click();
+        subObj.inited = true;
+    }*/
 });
 
 $('#linkZMHS').on('shown.bs.tab', function (e) {