/** * Created by Mai on 2017/4/1. */ var Bills = { createNew: function (project) { var billsTreeSetting = { id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true }; // 用户定义private方法 var tools = { coverseTreeUpdateData: function (datas, projectID) { var updateDatas = []; datas.forEach(function (data) { var updateData = {}; data.data.projectID = projectID; if (data.type === idTree.updateType.new) { updateData.updateType = 'ut_create'; updateData.updateData = data.data; } else if (data.type === idTree.updateType.update) { updateData.updateType = 'ut_update'; updateData.updateData = data.data; } else if (data.type === idTree.updateType.delete) { updateData.updateType = 'ut_delete'; updateData.updateData = data.data; } updateDatas.push(updateData); }); return updateDatas; }, formatBillsUpdateData: function (data) { let uData = JSON.parse(JSON.stringify(data)); delete uData.feesIndex; delete uData.flagsIndex; if (uData.quantity) { uData.quantity = uData.quantity.toFixed(2); } if (uData.fees) { for (let fee of uData.fees) { if(fee.unitFee)fee.unitFee = fee.unitFee.toFixed(2); if(fee.totalFee)fee.totalFee = fee.totalFee.toFixed(2); if(fee.tenderUnitFee)fee.tenderUnitFee = fee.tenderUnitFee.toFixed(2); if(fee.tenderTotalFee)fee.tenderTotalFee = fee.tenderTotalFee.toFixed(2); } } return uData; } }; // 所有通过this访问的属性,都不应在此单元外部进行写入操作 var bills = function (proj) { this.project = proj; this.datas = null; this.tree = idTree.createNew(billsTreeSetting); var sourceType = ModuleNames.bills; this.getSourceType = function () { return sourceType; } proj.registerModule(ModuleNames.bills, this); }; // 从后台获取数据 /*bills.prototype.pullData = function (){ this.project.pullData( '/bills/getData', {projectID: this.project.ID}, function(result){ if (result.error ===0){ this.loadDatas(result.data); } else { // to do: ?错误处理需要细化 alert(result.message); } }, function (){}// to do: 错误处理需要细化 ) };*/ // prototype用于定义public方法 bills.prototype.loadData = function (datas) { parseIDs(datas); this.datas = datas; // generate Fees & Flags Index, For View & Calculate this.datas.forEach(function (data) { if (data.quantity) { data.quantity = parseFloat(data.quantity); } data.feesIndex = getFeeIndex(data.fees); data.flagsIndex = {}; if (data.flags) { data.flags.forEach(function (flag) { data.flagsIndex[flag.fieldName] = flag; }); } }); // datas load to Tree this.tree.loadDatas(this.datas); }; bills.prototype.addDatasToList = function (new_datas) { let me = this; if(me.datas && Array.isArray(me.datas)){ for(let d of new_datas){ me.datas.push(d); } } }; bills.prototype.setMaxID = function (ID) { this.tree.maxNodeID(ID); }; // 提交数据后的错误处理方法 bills.prototype.doAfterUpdate = function(err, data){ // console.log(data) if(data.quantityRefresh){ 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; }); this.datas[dataIndex][fieldName] = data[fieldName]; if(fieldName=='quantity'){ this.datas[dataIndex]['isFromDetail']=1 } var controller = projectObj.mainController; var selected = controller.sheet.getSelections(); var col = _.findIndex(project.projSetting.main_tree_col.cols,function (col) { return col.data.field ==fieldName; }); controller.sheet.getCell(selected[0].row,col).value(data[fieldName]); }; bills.prototype.getCounterData = function (count) { var updateData = {'projectID': this.project.ID()}; if (count) { updateData[this.getSourceType()] = this.tree.maxNodeID() + count; } else { updateData[this.getSourceType()] = this.tree.maxNodeID() + 1; } return updateData; }; bills.prototype.insertSpecialBill=function(parentId, nextSiblingId,isUserAdd,type){ var insertData = this.tree.getInsertData(parentId, nextSiblingId, true); var that = this, newData = null; insertData.forEach(function (data) { if (data.type === idTree.updateType.new) { if(isUserAdd==true){//如果是用户新增的 data.data.isAdd = 1; } data.data.type = type; newData = data.data; } }); this.project.pushNow('insertBills', [this.getSourceType(), this.project.projCounter()], [ tools.coverseTreeUpdateData(insertData, this.project.ID()), this.getCounterData()]); //project.pushNow('insertBills', ModuleNames.bills, tools.coverseTreeUpdateData(insertData)); this.datas.push(newData); return this.tree.insertByData(newData,parentId, nextSiblingId, true); }; bills.prototype.insertBills = function (parentId, nextSiblingId) { var insertData = this.tree.getInsertData(parentId, nextSiblingId, true); var that = this, newData = null; insertData.forEach(function (data) { if (data.type === idTree.updateType.new) { data.data.type = billType.BILL; newData = data.data; } }); this.project.pushNow('insertBills', [this.getSourceType(), this.project.projCounter()], [ tools.coverseTreeUpdateData(insertData, this.project.ID()), this.getCounterData()]); //project.pushNow('insertBills', ModuleNames.bills, tools.coverseTreeUpdateData(insertData)); this.datas.push(newData); return this.tree.insertByData(newData,parentId, nextSiblingId, true); }; bills.prototype.insertStdBills = function (parentId, nextSiblingId, stdBillsData) { var insertData = this.tree.getInsertData(parentId, nextSiblingId, true); var newData = null, that = this; insertData.forEach(function (data) { if (data.type === idTree.updateType.new) { data.data.code = that.newFormatCode(stdBillsData.code); data.data.name = stdBillsData.name; data.data.unit = stdBillsData.unit; // 工程量计算规则 data.data.ruleText = stdBillsData.ruleText; // 说明(清单备注) data.data.comments = stdBillsData.comments; //zhong 特征及内容 data.data.jobContent = stdBillsData.jobContent; data.data.itemCharacter = stdBillsData.itemCharacter; data.data.jobContentText = stdBillsData.jobContentText; data.data.itemCharacterText = stdBillsData.itemCharacterText; data.data.programID = stdBillsData.engineering; data.data.type = stdBillsData.type;//插入清单类型 //Vincent data.data.billsLibId = stdBillsData.billsLibId;//添加清单库ID data.data.economicType = stdBillsData.economicType;//工程经济指标类别 data.data.quantityIndexType = stdBillsData.quantityIndexType;//工程经济指标类别 data.data.quantityIndexUnit = stdBillsData.quantityIndexUnit;//工程经济指标类别 data.data.quantityIndexCoe = stdBillsData.quantityIndexCoe;//工程经济指标类别 //zhong newData = data.data; } }); this.project.pushNow('insertStdBills', [this.getSourceType(), this.project.projCounter()], [ tools.coverseTreeUpdateData(insertData, this.project.ID()), this.getCounterData()]); this.datas.push(newData); return this.tree.insertByData(newData, parentId, nextSiblingId, true); }; // 已经有数据,更新前端缓存及节点,不进行通信 bills.prototype.addNewDataSimply = function (newData) { const newNodes = []; const controller = projectObj.mainController; this.addDatasToList(newData); newData.forEach(item => { // 插入清单树 const newSource = projectObj.project.Bills.tree.insertByData(item, item.ParentID, item.NextSiblingID, true); // 插入主树 const newNode = project.mainTree.insert(item.ParentID, item.NextSiblingID, newSource.data.ID); newNode.source = newSource; newNode.sourceType = projectObj.project.Bills.getSourceType(); newNode.data = newSource.data; controller.sheet.addRows(newNode.serialNo(), 1); // controller.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center); newNodes.push(newNode); }); TREE_SHEET_HELPER.refreshTreeNodeData(controller.setting, controller.sheet, newNodes, false); return newNodes; } bills.prototype.deleteBills = function (node) { let deleteNode = function (node) { this.project.Ration.deleteByBills([node]); // this.project.VolumePrice.deleteByBills([node]); return this.tree.delete(node); } var deleteData = this.tree.getDeleteData(node); var ration_glj =projectObj.project.ration_glj; // let modules =[ModuleNames.bills, ModuleNames.ration, ModuleNames.ration_glj, ModuleNames.volume_price]; let modules =[ModuleNames.bills, ModuleNames.ration, ModuleNames.ration_glj]; let deleteDatas=[tools.coverseTreeUpdateData(deleteData, this.project.ID()), this.project.Ration.getDeleteDataByBill([node]), ration_glj.getDeleteDataByBills(deleteData), // this.project.VolumePrice.getDeleteDataByBills([node]) ]; project.ration_glj.deleteByBills(deleteData); project.quantity_detail.deleteByBills(deleteData); project.pushNow('deleteBills', modules, deleteDatas); this.datas.splice(this.datas.indexOf(node.data), 1); 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={}; let newParent=null; let me = this; if(node){ if(node.children.length>0){//有子项 if(node.preSibling){//有前兄弟,则子项变成前兄弟的子项 if(node.preSibling.children.length>0){//前兄弟有子项, let preNode = node.preSibling.children[node.preSibling.children.length-1]; updateData[preNode.data.ID]={ NextSiblingID:node.children[0].data.ID }; updateNode[preNode.data.ID] = preNode; } for(let i=0;i0){ for(let c of node.children){ getLeaves(c,children) } }else { children.push(node); } } } }; bills.prototype.getRootNode = function (node) { if(node.parent){ return this.getRootNode(node.parent); }else { return node; } }; bills.prototype.isFBFX = function (node) {//判读是否属于分部分项部分 let rootNode = this.getRootNode(node); if(this.flagEquals(rootNode,fixedFlag.SUB_ENGINERRING)){ return true; }else { return false; } }; bills.prototype.isFXorBX=function (node) {//是分项或者补项 if(node.sourceType == projectObj.project.Bills.getSourceType()){ return node.data.type == billType.FX || node.data.type == billType.BX; } return false; }; bills.prototype.nodeFlagCheck = function (node,fixedFlag) {//按flag判断节点是否属于该类型(包括子节点) let me = this; let flagCheck = function (checkNode) { if(me.flagEquals(checkNode,fixedFlag)){ return true; }else { if(checkNode.parent){ return flagCheck(checkNode.parent); }else { return false; } } }; return flagCheck(node); }; bills.prototype.flagEquals = function (node,fixedFlag) { if(isFlag(node.data)&&node.data.flagsIndex.fixed.flag==fixedFlag){ return true; } return false }; bills.prototype.getNodeByFlag = function(node,flag){//取节点类型,返回本身或父项节点 if(node){ if(isFlag(node.data)&&node.data.flagsIndex.fixed.flag==flag){ return node; }else { return this.getNodeByFlag(node.parent,flag); } }else { return null; } }; bills.prototype.isTopThreeNode = function (node) {//是否为前三项,即大项1、2、3项 return this.flagEquals(node,fixedFlag.SUB_ENGINERRING)||this.flagEquals(node,fixedFlag.MEASURE)||this.flagEquals(node,fixedFlag.OTHER)//是大项1、2、3项的编号设置为只读 }; bills.prototype.isEngineerEst = function (node) {//判断是否是“专业工程暂估价”节点或者子项 return this.nodeFlagCheck(node,fixedFlag.ENGINEERING_ESITIMATE); //return node && isFlag(node.data)&&node.data.flagsIndex.fixed.flag==fixedFlag.ENGINEERING_ESITIMATE; }; bills.prototype.isTotalService = function (node) {//判断是否是“总承包服务费”节点 return this.nodeFlagCheck(node,fixedFlag.TURN_KEY_CONTRACT); }; bills.prototype.isClaimVisa = function (node) {//判断是否是“签证及索赔计价”节点 return this.nodeFlagCheck(node,fixedFlag.CLAIM_VISA); }; bills.prototype.isMeasure = function (node) {//判读是否属于措施项目部分 let rootNode = this.getRootNode(node); if(this.isMeasureNode(rootNode)){ return true; }else { return false; } }; bills.prototype.isMeasureNode=function(node){//判读是否就是措施项目节点 return isFlag(node.data)&&node.data.flagsIndex.fixed.flag==fixedFlag.MEASURE }; bills.prototype.hasFlags = function (node) { return isFlag(node.data); }; bills.prototype.isBX = function (node) {//判读是否属于补项 if(node && node.sourceType == ModuleNames.bills&&node.data.type==billType.BX){ return true; } return false; }; bills.prototype.isTechMeasure = function (node) {//判读是否属于技术措施项目部分 let techMeasureCheck = function (checkNode) { if(isFlag(checkNode.data)&&checkNode.data.flagsIndex.fixed.flag==fixedFlag.CONSTRUCTION_TECH){ return true; }else { if(checkNode.parent){ return techMeasureCheck(checkNode.parent); }else { return false; } } } return techMeasureCheck(node); }; bills.prototype.isEngineeringCost = function (node) {//判断这个节点是否是工程造价节点 if(isFlag(node.data)&&node.data.flagsIndex.fixed.flag==fixedFlag.ENGINEERINGCOST){ return true; }else { return false; } }; bills.prototype.calcEngineeringCostNode=function(controller){ let roots = controller.tree.roots; for(let root of roots){ if(project.Bills.isEngineeringCost(root)==true){ project.calcProgram.calcAndSave(root); break; } } }; bills.prototype.getEngineeringCostNode=function(controller){//取工程造价节点 let roots = controller.tree.roots; for(let root of roots){ if(project.Bills.isEngineeringCost(root)==true){ return root; } } }; bills.prototype.getEngineeringCost = function () {//取项目工程造价; let node = this.getEngineeringCostNode(projectObj.mainController); let totalFee = node && node.data.feesIndex && node.data.feesIndex.common?node.data.feesIndex.common.totalFee:0; return totalFee; }; bills.prototype.getFBFXNode = function (controller) {//取分部分项工程节点 let roots = controller.tree.roots; for(let root of roots){ if(isFlag(root.data)&&root.data.flagsIndex.fixed.flag==fixedFlag.SUB_ENGINERRING){ return root; } } }; bills.prototype.getMeasureNode = function (controller) {//取措施项目工程节点 let roots = controller.tree.roots; for(let root of roots){ if(isFlag(root.data)&&root.data.flagsIndex.fixed.flag==fixedFlag.MEASURE){ return root; } } }; 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.getOrgNode=function () {//取组织措施项目节点 let items = projectObj.project.mainTree.items;//所有节点; let orgNode = null; for(let item of items){ if(isFlag(item.data)&&item.data.flagsIndex.fixed.flag==fixedFlag.CONSTRUCTION_ORGANIZATION){ orgNode = item; break; } } return orgNode; }; bills.prototype.deleteSelectedNode=function(){//删除选中单行时的节点 let controller = projectObj.mainController, project = projectObj.project; let selected = controller.tree.selected, parent = selected.parent; if (selected) { if (selected.sourceType === project.Bills.getSourceType()) { if (cbTools.isUsedByFormula(selected)){ alert('该清单行被其它公式结点引用,不允许删除!'); return; } project.Bills.deleteBills(selected.source); controller.delete(); } else if (selected.sourceType === project.Ration.getSourceType()) { project.Ration.delete(selected.source); controller.delete(); }else if(selected.sourceType==ModuleNames.ration_glj){ project.ration_glj.updataOrdelete(selected.source); } if(project.Bills.isFBFX(selected)) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算 project.installation_fee.calcInstallationFee(function (isChange) { if(isChange){ project.calcProgram.calcAllNodesAndSave(); }else { if(parent){ projectObj.converseCalculateBills(parent); }else { //删除的是大项费用要重新计算工程造价节点 project.Bills.calcEngineeringCostNode(controller); } project.projectGLJ.loadData(); } }); }else { if(parent){ projectObj.converseCalculateBills(parent); }else { //删除的是大项费用要重新计算工程造价节点 project.Bills.calcEngineeringCostNode(controller); } project.projectGLJ.loadData(); } } }; bills.prototype.deleteSelectedNodes=function(isDeleteChild = false, parentNode = null) {//删除选中多行时的节点 let controller = projectObj.mainController, project = projectObj.project; let selected = controller.tree.selected, parent = selected.parent; let me = this; let idTreeMap = {}; let mainTreeMap = {}; let mainNodes = []; let idTreeNodes=[]; let updateData={}; let includeRootNode=false; let parentNodes = []; let selection = projectObj.mainSpread.getActiveSheet().getSelections()[0]; for(let i =0;i 0)) return; let me = this; let firstChild = node.firstChild(); calcTools.forceSelect(firstChild, node.children.length); me.deleteSelectedNodes(true, node); }; bills.prototype.setNodeToMapAndArray=function (node,map,array) { let nodeID = node.getID(); if(map[nodeID]==undefined||map[nodeID]==null){ newMap(node,node.parent,map,array) } function newMap(node,parent,map,array) { let nodeID =node.getID(); if(parent==null){//说明已经是最顶层了 map[nodeID]=node; array.push(node); }else { let parentID = parent.getID(); if(map[parentID]==undefined||map[parentID]==null){ newMap(node,parent.parent,map,array); } } } }; bills.prototype.deleteAllSubNodes = function(){ let controller = projectObj.mainController, project = projectObj.project; let Bill = project.Bills; let FBFX = Bill.getFBFXNode(controller);//取分部分项工程节点; let deleteRootNodes = _.clone(FBFX.children); let deleteRootNodes_id = _.clone(FBFX.source.children); let sels = controller.sheet.getSelections(); controller.tree.m_delete(deleteRootNodes); this.tree.m_delete(deleteRootNodes_id); TREE_SHEET_HELPER.massOperationSheet(controller.sheet, function () { let rowCount = 0; for(let node of deleteRootNodes){ rowCount = rowCount+node.posterityCount() + 1; } controller.sheet.deleteRows(1, rowCount); let index = sels[0]?sels[0].row:1; //controller.setTreeSelected(controller.tree.items[1]); }); cbTools.refreshFormulaNodes(); }; bills.prototype.getAllBXs = function () { return _.filter(this.datas,{"type":billType.BX}); }; bills.prototype.getAutoParentNode = function (type) {//取需自动生成清单的父节点 let controller = projectObj.mainController; let parentNode; if(type == '措施费用'){ parentNode = this.getTechNode(); }else { let rootNode = this.getFBFXNode(controller); parentNode =getLeaveBill(rootNode.source); if(parentNode.data.type == billType.FX||parentNode.data.type == billType.BX){//如果是分项或补项的话,取父节点 parentNode = parentNode.parent; } } return parentNode; function getLeaveBill(node) { if(node.children.length>0){ return getLeaveBill(node.children[node.children.length-1]); }else { return node; } } }; bills.prototype.getNewInstallBillData = function (code,billID,feeType) { let parentNode = this.getAutoParentNode(feeType); 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; }; //取需要父项汇总需要用到的子项(固定清单材料(工程设备)暂估价比较特殊,不进行父项汇总) bills.prototype.getGatherNodes = function (node) { let rst = []; for (let child of node.source.children) { if (cbTools.isFlag(child.data) && child.data.flagsIndex.fixed.flag === fixedFlag.MATERIAL_PROVISIONAL) { continue; } rst.push(child); } return rst; }; return new bills(project); } }; function isDef(v) { return v !== undefined && v !== null; } function isFlag(v) { return this.isDef(v.flagsIndex) && this.isDef(v.flagsIndex.fixed) && this.isDef(v.flagsIndex.fixed.flag); } function getRootFixedNode(node) { let parent = node.parent; if(isFlag(node.data) && (node.data.flagsIndex.fixed.flag === fixedFlag.SUB_ENGINERRING || node.data.flagsIndex.fixed.flag === fixedFlag.MEASURE || node.data.flagsIndex.fixed.flag === fixedFlag.OTHER || node.data.flagsIndex.fixed.flag === fixedFlag.CHARGE || node.data.flagsIndex.fixed.flag === fixedFlag.TAX)){ return node; } else { if(!parent){ return node; } else { return getRootFixedNode(parent); } } } //转换ID '-1' to -1 function parseIDs(datas){ for(let data of datas){ if(isDef(data.ID) && data.ID === '-1'){ data.ID = -1; } if(isDef(data.ParentID) && data.ParentID === '-1'){ data.ParentID = -1; } if(isDef(data.NextSiblingID) && data.NextSiblingID === '-1'){ data.NextSiblingID = -1; } } }