zhangweicheng 6 anni fa
parent
commit
ac45bd7b3c

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

@@ -39,6 +39,8 @@ module.exports = {
         // Project.getFilterData(data.project_id, ['bills', 'projectGLJ'], function (err, result) {
         //     console.log(result);
         // });
+        //test
+        project_facade.getBudgetSummayDatas([517,521]);
         Project.getData(data.project_id, function (err, message, result) {
             if (!err) {
                 callback(req, res, err, message, result);

+ 1 - 1
modules/main/facade/decimal_facade.js

@@ -7,7 +7,7 @@ let _ = require('lodash');
 
 module.exports ={
     getProjectDecimal:getProjectDecimal,
-    getBillsQuantityDecimal:getBillsQuantityDecimal
+    getBillsQuantityDecimal:getBillsQuantityDecimal,
 }
 
 async function getProjectDecimal(projectID,proj) {

+ 254 - 27
modules/main/facade/project_facade.js

@@ -1,6 +1,18 @@
 /**
  * Created by zhang on 2018/1/26.
  */
+
+module.exports = {
+    markUpdateProject:markUpdateProject,
+    removeProjectMark:removeProjectMark,
+    updateNodes:updateNodes,
+    calcInstallationFee:calcInstallationFee,
+    saveProperty: saveProperty,
+    getDefaultColSetting: getDefaultColSetting,
+    markProjectsToChange:markProjectsToChange,
+    getBudgetSummayDatas:getBudgetSummayDatas
+};
+
 let mongoose = require('mongoose');
 let logger = require("../../../logs/log_helper").logger;
 let  projectsModel = mongoose.model('projects');
@@ -17,17 +29,12 @@ let ration_glj_facade = require("../../ration_glj/facade/ration_glj_facade");
 const uuidV1 = require('uuid/v1');
 const gljUtil = require('../../../public/gljUtil');
 let stdColSettingModel = mongoose.model('std_main_col_lib');
+let decimal_facade = require('../../main/facade/decimal_facade');
+const scMathUtil = require('../../../public/scMathUtil').getUtil();
+import fixedFlag from  '../../common/const/bills_fixed';
+const projectDao = require('../../pm/models/project_model').project;
+
 
-module.exports = {
-    markUpdateProject:markUpdateProject,
-    removeProjectMark:removeProjectMark,
-    updateNodes:updateNodes,
-    calcInstallationFee:calcInstallationFee,
-    saveProperty: saveProperty,
-    getDefaultColSetting: getDefaultColSetting,
-    markProjectsToChange:markProjectsToChange,
-    getBudgetSummayDatas:getBudgetSummayDatas
-};
 
 async function calcInstallationFee(data) {
     let result={};
@@ -275,41 +282,261 @@ async function getDefaultColSetting(libID){
 }
 
 async function getBudgetSummayDatas(projectIDs){
-    let projects = [];
-    for(let ID of projectIDs){
-        projects.push(await getBillsByProjectID(ID)) ;
+    try {
+        let projects = [];
+        let names = [];
+        let decimal = null;
+        for(let ID of projectIDs){
+            projects.push(await getBillsByProjectID(ID)) ;
+        }
+        if(projects.length == 0){
+            return [];
+        }
+        let mp = projects[0];
+        names.push(mp.name);
+        for(let i = 1;i<projects.length;i++){
+            names.push(projects[i].name);
+            decimal = await mergeProject(mp.roots,projects[i].roots)
+        }
+        let SummaryAuditDetail = getReportData(names,mp.roots,decimal);
+        let parentProject = await projectsModel.findOne({ID:mp.ParentID});
+        let result = {
+            prj: {},
+            SummaryAudit:{
+                "name": parentProject?parentProject.name:"",
+                "编制": mp.author,
+                "复核": mp.auditor
+            },
+            SummaryAuditDetail:SummaryAuditDetail
+        }
+        console.log(JSON.stringify(result));
+        return result;
+    }catch (e){
+        console.log(e)
+    }
+}
+
+
+function getReportData(nameList,items,decimal) {
+    let datas = [],totalItem = null;
+    setChildrenDatas(items,datas);
+    for(let d of datas){
+        if(d.billsTtlPrices){
+            d['各项费用比例'] = scMathUtil.roundForObj(d.billsTtlPrices/totalItem.billsTtlPrices * 100,2)
+        }
+        d['prjNames'] = nameList;
+    }
+    return datas;
+
+
+    function setChildrenDatas(children,arr) {
+        for(let c of children){
+            arr.push(getBillDatas(c));
+            setChildrenDatas(c.children,arr);
+        }
+    }
+
+    function getBillDatas(bills) {
+        let tem = {
+            billsName:bills.name,
+            billsCode:bills.code,
+            billsUnit:bills.unit,
+            billsTtlAmt:bills.quantity,
+            billsPrices:[],
+            billsMemos:bills.remark
+        };
+        let total = 0;
+        for(let n of nameList){
+            if(bills.prices[n]){
+                let p =  scMathUtil.roundForObj(bills.prices[n],decimal.bills.totalPrice);
+                tem.billsPrices.push(p);
+                total = scMathUtil.roundForObj(p+total,decimal.process);
+            }else {
+                tem.billsPrices.push(0);
+            }
+        }
+        tem.billsTtlPrices = scMathUtil.roundForObj(total,decimal.bills.totalPrice);
+
+        if(tem.billsTtlAmt) tem['技术经济指标'] = scMathUtil.roundForObj(tem.billsTtlPrices/tem.billsTtlAmt,2);
+        if(bills.flag == fixedFlag.TOTAL_COST) totalItem = tem;
+        return tem
     }
 
+}
+
 
+async function mergeProject(main,sub) {//合并两个项目
+    let decimal = await decimal_facade.getProjectDecimal(main[0].projectID);
+    let project =  await projectsModel.findOne({ID:main[0].projectID});
+    let notMatchList = [];
+    for(let s of sub){
+       //先找有没有相同的大项费用
+       let same = findTheSameItem(main,s);
+       same?await mergeItem(same,s,decimal,project._doc):notMatchList.push(s);//如果找到,则合并,找不到就放在未匹配表
+    }
+    for(let n of notMatchList){
+        main.push(n);
+    }
 
+    return decimal;
+}
+
+async function mergeItem(a,b,decimal,project) {
+    let bqDecimal = await decimal_facade.getBillsQuantityDecimal(a.projectID,a.unit,project);
+    a.quantity = a.quantity?scMathUtil.roundForObj(a.quantity,bqDecimal):0;
+    b.quantity = b.quantity?scMathUtil.roundForObj(b.quantity,bqDecimal):0;
+    a.quantity = scMathUtil.roundForObj(a.quantity+b.quantity,decimal.process);
+    for(let name in b.prices){
+        a.prices[name] = b.prices[name];
+    }
+    await mergeChildren(a,b,decimal,project);
+}
+
+async function mergeChildren(a,b,decimal,project) {
+    let notMatchList = [];
+    if(a.children.length > 0 && b.children.length ==0){
+        return;
+    }else if(a.children.length == 0 && b.children.length > 0){
+        a.children = b.children;
+        return;
+    }
+    //=============剩下的是两者都有的情况
+    for(let s of b.children){
+        let same = findTheSameItem(a.children,s);
+        same?await mergeItem(same,s,decimal,project):notMatchList.push(s);//如果找到,则合并,找不到就放在未匹配表
+    }
+    for(let n of notMatchList){
+        let match = false;//符合插入标记
+       //对于未匹配的子项,如果是固定清单:第100章至700章清单的子项,要匹配名字中的数字来做排充
+        if(a.flag == fixedFlag.ONE_SEVEN_BILLS){
+            for(let i = 0;i< a.children.length;i++){
+                let m_name = a.children[i].name.replace(/[^0-9]/ig,"");
+                let s_name = n.name.replace(/[^0-9]/ig,"");
+                m_name = parseFloat(m_name);
+                s_name = parseFloat(s_name);
+                if(m_name&&s_name){
+                    if(m_name == s_name){
+                        await mergeItem(a.children[i],n,project);
+                        match = true;
+                        break;
+                    }
+                    if(m_name > s_name){//主节点名字中的数字大于被插节点,则被插节点放在主节点前面
+                        a.children.splice(i,0,n);
+                        match = true;
+                        break;
+                    }
+                }
+            }
+        }else {//其它的子项按编号进行排序
+            for(let i = 0;i< a.children.length ; i++){
+                let m_code = a.children[i].code;
+                let s_code = n.code;
+                if(m_code && s_code && m_code!=""&&s_code!=""){
+                    if(m_code > s_code){
+                        a.children.splice(i,0,n);
+                        match = true;
+                        break;
+                    }
+                }
+            }
+        }
+        if(match == false)a.children.push(n) //没有插入成功,直接放到最后面
+    }
+}
+
+
+function findTheSameItem(main,item) {//编号名称单位三个相同,认为是同一条清单
+    return _.find(main,function (tem) {
+        return isEqual(tem.code,item.code)&&isEqual(tem.name,item.name)&&isEqual(tem.unit,item.unit);
+    })
+
+
+}
+
+
+function isEqual(a,b) {//粗略匹配,null undefind "" 认为相等
+    return getValue(a)==getValue(b);
+    function getValue(t) {
+        if(t==null||t==undefined||t=="") return null;
+        return t;
+    }
 }
 
 async function getBillsByProjectID(projectID){
-    let items = [],roots=[],parentMap={};
+    let roots=[],parentMap={};
     let bills =  await bill_model.model.find({projectID: projectID}, '-_id');//取出所有清单
     let project = await projectsModel.findOne({ID:projectID});
-    let projectName = project?project.name:"";
+    if(!project) throw new Error(`找不到项目:${projectID}`);
+    let projectName = project.name;
+    let author='';//编制人
+    let auditor='';//审核人
+    if(project.property&&project.property.projectFeature){
+        for(let f of project.property.projectFeature){
+            if(f.key == 'author') author = f.value;
+            if(f.key == 'auditor') auditor = f.value;
+        }
+    }
    for(let b of  bills){
-       items.push(b._doc);
-       if(b.parentID == -1) roots.push(b._doc);
-       parentMap[b.parentID]?parentMap[b.parentID].push[b._doc]:parentMap[b.parentID]=[b._doc];
-   }//设置子节点+排序
+       let commonFee =_.find(b._doc.fees,{"fieldName":"common"});
+       let prices = {};
+       if(commonFee&&commonFee.totalFee) prices[projectName] =  commonFee.totalFee;
+       let flagIndex = _.find(b._doc.flags,{'fieldName':'fixed'});
+       let doc = {ID:b.ID,name:b.name,code:b.code,unit:b.unit,projectID:b.projectID, ParentID:b.ParentID,NextSiblingID:b.NextSiblingID,quantity:b.quantity,prices:prices,flag:flagIndex?flagIndex.flag:-99,remark:b.remark};//选取有用字段
+       if(b.ParentID == -1) roots.push(doc);
+       parentMap[b.ParentID]?parentMap[b.ParentID].push(doc):parentMap[b.ParentID]=[doc];
+   }//设置子节点
    for(let r of roots){
-        setChildren(r,parentMap)
+        setChildren(r,parentMap,1);
    }
+    roots = sortChildren(roots);
+    return {name:projectName,roots:roots,author:author,auditor:auditor,ParentID:project.ParentID}
 }
 
-function setChildren(bill,parentMap) {
+function setChildren(bill,parentMap,level) {
     let children = parentMap[bill.ID];
-    let childrenMap = {};
-    let firstNode = null;
     if(children){
         for(let c of children){
-            childrenMap[c.ID] = c;
-            setChildren(c,parentMap)
+            setChildren(c,parentMap,level+1)
         }
-
-
         bill.children = children;
+    }else {
+        bill.children = [];
     }
 }
+
+function sortChildren(lists) {
+    let IDMap ={},nextMap = {}, firstNode = null,newList=[];
+    for(let l of lists){
+        if(l.children&&l.children.length > 0) l.children = sortChildren(l.children);//递规排序
+        IDMap[l.ID] = l;
+        if(l.NextSiblingID!=-1) nextMap[l.NextSiblingID] = l;
+    }
+    for(let t of lists){
+        if(!nextMap[t.ID]){ //如果在下一节点映射没找到,则是第一个节点
+            firstNode = t;
+            break;
+        }
+    }
+    if(firstNode){
+        newList.push(firstNode);
+        delete IDMap[firstNode.ID];
+        setNext(firstNode,newList);
+    }
+    //容错处理,如果链断了的情况,直接添加到后面
+    for(let key in IDMap){
+        if(IDMap[key]) newList.push(IDMap[key])
+    }
+    return newList;
+
+    function setNext(node,array) {
+       if(node.NextSiblingID != -1){
+           let next = IDMap[node.NextSiblingID];
+           if(next){
+               array.push(next);
+               delete IDMap[next.ID];
+               setNext(next,array);
+           }
+       }
+    }
+
+}

+ 0 - 2
public/web/gljUtil.js

@@ -357,7 +357,6 @@ let gljUtil = {
             obj[key] = n;
         });
     },
-
     getTotalQuantity:function(glj,ration,rd,gd){
         if(ration){
             let quantity = ration.quantity;
@@ -367,7 +366,6 @@ let gljUtil = {
             return scMathUtil.roundToString(quantity * glj.quantity, gd);
         }
     },
-
     fixedFlag : {
         // 分部分项工程
         SUB_ENGINERRING: 1,