浏览代码

Merge branch 'master' of http://192.168.1.12:3000/SmartCost/ConstructionCost

TonyKang 7 年之前
父节点
当前提交
1624a7d014

+ 116 - 0
modules/main/controllers/quantity_detail_controller.js

@@ -0,0 +1,116 @@
+/**
+ * Created by zhang on 2017/11/24.
+ */
+
+var quantity_detail_data = require('../facade/quantity_detail_facade');
+let logger = require("../../../logs/log_helper").logger;
+module.exports={
+    save:save,
+    update:update,
+    updateRegex:updateRegex,
+    insertRecode:insertRecode,
+    deleteRecode:deleteRecode,
+    swapRow:swapRow
+}
+
+async function save(req, res) {
+    let result={
+        error:0
+    }
+    try {
+        let data = req.body.data;
+        data = JSON.parse(data);
+        let datas= await quantity_detail_data.saveQuantityDetail(data);
+        result.data=datas;
+    }catch (err){
+        logger.err(err);
+        result.error=1;
+        result.message = err.message;
+    }
+    res.json(result);
+}
+
+async function update(req, res) {
+    let result={
+        error:0
+    }
+    try {
+        let data = req.body.data;
+        data = JSON.parse(data);
+        let datas= await quantity_detail_data.update(data);
+        result.data=datas;
+    }catch (err){
+        logger.err(err);
+        result.error=1;
+        result.message = err.message;
+    }
+    res.json(result);
+}
+
+async function updateRegex(req, res) {
+    let result={
+        error:0
+    }
+    try {
+        let data = req.body.data;
+        data = JSON.parse(data);
+        let datas= await quantity_detail_data.updateRegex(data);
+        result.data=datas;
+    }catch (err){
+        logger.err(err);
+        result.error=1;
+        result.message = err.message;
+    }
+    res.json(result);
+}
+
+async function insertRecode(req, res) {
+    let result={
+        error:0
+    }
+    try {
+        let data = req.body.data;
+        data = JSON.parse(data);
+        let datas= await quantity_detail_data.insertRecode(data);
+        result.data=datas;
+    }catch (err){
+        logger.err(err);
+        result.error=1;
+        result.message = err.message;
+    }
+    res.json(result);
+}
+
+async function deleteRecode(req, res) {
+    let result={
+        error:0
+    }
+    try {
+        let data = req.body.data;
+        data = JSON.parse(data);
+        let datas= await quantity_detail_data.deleteRecode(data);
+        result.data=datas;
+    }catch (err){
+        logger.err(err);
+        result.error=1;
+        result.message = err.message;
+    }
+    res.json(result);
+}
+
+async function swapRow(req, res) {
+    let result={
+        error:0
+    }
+    try {
+        let data = req.body.data;
+        data = JSON.parse(data);
+        let datas= await quantity_detail_data.swapRow(data);
+        result.data=datas;
+    }catch (err){
+        logger.err(err);
+        result.error=1;
+        result.message = err.message;
+    }
+    res.json(result);
+}

+ 17 - 2
modules/main/facade/decimal_facade.js

@@ -2,10 +2,11 @@
  * Created by zhang on 2017/11/22.
  */
 let projectsModel = require("../../pm/models/project_schema");
-
+let _ = require('lodash');
 
 module.exports ={
-    getProjectDecimal:getProjectDecimal
+    getProjectDecimal:getProjectDecimal,
+    getBillsQuantityDecimal:getBillsQuantityDecimal
 }
 
 async function getProjectDecimal(projectID) {
@@ -15,4 +16,18 @@ async function getProjectDecimal(projectID) {
         decimal = project.property.decimal
     }
     return decimal;
+}
+
+async function getBillsQuantityDecimal(projectID,unit) {
+    let decimal = null;
+    let project =await projectsModel.findOne({ID:projectID});
+    if(project){
+        let billsQuantityDecimal = project.property.billsQuantityDecimal;
+        let el = _.find(billsQuantityDecimal,{'unit':unit});
+        if(!el){
+            el = billsQuantityDecimal[0];
+        }
+        decimal = el.decimal
+    }
+    return decimal;
 }

+ 216 - 297
modules/ration_glj/facade/quantity_detail_facade.js

@@ -15,6 +15,7 @@ const uuidV1 = require('uuid/v1');
 let ration_model = mongoose.model('ration');
 let bill_model=mongoose.model("bills");
 const scMathUtil = require('../../../public/scMathUtil').getUtil();
+let decimal_facade = require('./decimal_facade');
 
 module.exports={
     save:save,
@@ -22,58 +23,143 @@ module.exports={
     deleteByRation:deleteByRation,
     deleteByBill:deleteByBill,
     quantityEditChecking:quantityEditChecking,
+    saveQuantityDetail:saveQuantityDetail,
+    update:update,
+    updateRegex:updateRegex,
+    insertRecode:insertRecode,
+    deleteRecode:deleteRecode,
+    swapRow:swapRow
 };
 
 let operationMap={
-    'ut_create':create_quantity_detail,
     'ut_update':update_quantity_detail,
-    'ut_delete':delete_quantity_detail
 };
 
 let updateFunctionMap = {
-    'normalUpdate':normalUpdate,
-    'updateQuantityRegex':updateQuantityRegex,
     'insertRecode':insertRecode
 }
 
-function create_quantity_detail(user_id,datas) {
-    return function (callback) {
-        let doc = datas.doc;
-        doc.ID = uuidV1();
-        if(doc.hasOwnProperty('regex')){
-            insertRecodeWithReg(doc).then(function (resultObject) {
-                if(resultObject.err){
-                    callback(null,{
-                        moduleName:consts.projectConst.QUANTITY_DETAIL,
-                        err:{
-                            message:result.err.message
-                        }
-                    });
-                } else {
-                    callback(null,resultObject.return_list);
-                }
-            })
-        }else {
-            createNormalRecode(doc,callback)
-        }
+async function saveQuantityDetail(datas) {
+    console.log(datas);
+    let doc = datas;
+    doc.ID = uuidV1();
+    if(doc.refreshQuantity==false){ //如果选择了不替换工程量,则清空
+        await cleanQuantityDetail(doc);
+        return
+    }
+    if(doc.hasOwnProperty('regex')){
+       return await insertRecodeWithReg(doc);
+    }else {
+        return await createNormalRecode(doc);
+    }
+}
 
+async function update(datas) {
+    let doc = datas.doc;
+    if(doc.hasOwnProperty('isSummation')){
+        return await doIsSummationUpdate(datas.query,doc);
+    }else {
+       await quantity_detail_model.update(datas.query,doc);
+       return datas;
     }
 }
 
-function insertRecode(user_id,datas) {
-    return function (callback) {
-        let doc = datas.doc;
-        doc.ID = uuidV1();
-        doInsertRecode(doc).then(function (result) {
-            //console.log(result);
-            if(result.err){
-                callback(result.err,'')
-            }else {
-                callback(null,result.returndata)
-            }
+async function swapRow(datas) {
+    for(let task of datas){
+        await update(task);
+    }
+    return {refreshList:datas};
+}
+
+async function updateRegex(datas) {
+    let resultObjec ={};
 
-        })
+    let detailList = [];
+    let node ={};
+    let decimal =await decimal_facade.getProjectDecimal(datas.query.projectID);
+    if(datas.query.hasOwnProperty('rationID')){
+        detailList = await quantity_detail_model.find({'projectID':datas.query.projectID,'rationID':datas.query.rationID}).sort('seq').exec();
+        node.type = consts.projectConst.RATION;
+        node.ID = datas.query.rationID;
+    }else {
+        detailList = await quantity_detail_model.find({'projectID':datas.query.projectID,'billID':datas.query.billID}).sort('seq').exec();
+        node.type = consts.projectConst.BILLS;
+        node.ID=datas.query.billID;
     }
+    let regex;
+    let result;
+    if(datas.doc.regex==null){
+        result=0;
+        datas.doc.referenceIndexs=[];
+    }else {
+        regex = datas.doc.regex.toUpperCase();
+        let referenceIndexs = datas.doc.referenceIndexs;
+        result = getEvalResult(referenceIndexs,detailList,regex,decimal);
+    }
+    detailList[datas.query.index].result =result;
+    detailList[datas.query.index].regex=datas.doc.regex;
+    detailList[datas.query.index].referenceIndexs =datas.doc.referenceIndexs;
+    let updateTasks =[];
+    datas.doc.result=result;
+    updateTasks.push({
+        query:{
+            ID:datas.query.ID,
+            projectID:datas.query.projectID
+        },
+        doc:datas.doc
+    })
+    updateReferenceRecode(datas.query.index+1,detailList,updateTasks);
+    await quantity_detail_model.bulkWrite(generateUpdateTaks(updateTasks));
+    resultObjec.refreshList=updateTasks;
+    if(datas.query.refreshQuantity==true){
+        let data = {};
+        data.quantity = await summateResults(datas.query,detailList,decimal);
+        data.isFromDetail = 1;
+        node.data = data;
+        resultObjec.node = node;
+    }
+    return resultObjec;
+
+}
+
+
+async function cleanQuantityDetail(doc) {
+    let query = {
+        projectID:doc.projectID
+    }
+    if(doc.hasOwnProperty('rationID')){
+        query.rationID = doc.rationID;
+    }else {
+        query.billID = doc.billID;
+    }
+    await quantity_detail_model.deleteMany(query);
+}
+
+
+async function insertRecode(doc){
+    let query = {
+        projectID:doc.projectID,
+        seq : { $gte: doc.seq }
+    }
+    if(doc.hasOwnProperty('rationID')){
+        query.rationID = doc.rationID;
+    }else {
+        query.billID = doc.billID;
+    }
+    let quantity_detail_List = await getDatailList(doc,{data:{}});
+    let update_task = getUpdateReferenceTask(quantity_detail_List,doc.seq,1);
+    await quantity_detail_model.update(query,{$inc:{seq:1}},{multi: true});
+    if(update_task.length>0){
+        await quantity_detail_model.bulkWrite(generateUpdateTaks(update_task));
+    }
+    doc.ID = uuidV1();
+    let newrecode = await quantity_detail_model.create(doc);
+    let data={
+        doc:newrecode,
+        resort:true,
+        update_task:update_task
+    }
+    return data;
 }
 
 async function doInsertRecode(doc) {
@@ -150,229 +236,78 @@ function getUpdateReferenceTask(quantity_detail_List,seq,re) {
 }
 
 
-function createNormalRecode(doc,callback) {
-    quantity_detail_model.create(doc,(err,result)=>{
-        if(err){
-            callback(err,null);
-        }else {
-            console.log(result);
-            let returndata ={
-                updateTpye:commonConsts.UT_CREATE,
-                moduleName:consts.projectConst.QUANTITY_DETAIL,
-                data:result
-            }
-            callback(null,returndata)
-        }
-    });
+async function createNormalRecode(doc) {
+    let result ={};
+    result.newRecord= await quantity_detail_model.create(doc);
+    return result;
 }
 
 
 async function insertRecodeWithReg (doc) {
-    let returnObjec={
-        err:null,
-        return_list:[]
-    }
+    let returnObjec={}
     try {
-        let returnData={
-            moduleName:'',
-            data:{
-                updateTpye:commonConsts.UT_UPDATE,
-            }
-        }
+        let decimal =await decimal_facade.getProjectDecimal(doc.projectID);
         let regex = doc.regex.toUpperCase();
         let referenceIndexs = doc.referenceIndexs;
-        let detailList = await getDatailList(doc,returnData);
-        doc.result =getEvalResult(referenceIndexs,detailList,regex);
+        let detailList = await getDatailList(doc,returnObjec);
+        doc.result =getEvalResult(referenceIndexs,detailList,regex,decimal);
         let refreshQuantity =false;
         if(doc.refreshQuantity==true){
             refreshQuantity = true;
         }
         delete doc.refreshQuantity;
-        let newRecode = await quantity_detail_model.create(doc) ;
-        detailList.push(newRecode);
+        let newRecord = await quantity_detail_model.create(doc) ;
+        detailList.push(newRecord);
         if(refreshQuantity==true){
-            returnData.data.quantity = await summateResuts(doc,detailList);
-            returnData.data.quantityRefresh = true;
-            returnObjec.return_list.push(returnData);
+            let data = {};
+            data.quantity = await summateResults(doc,detailList,decimal);
+            data.isFromDetail = 1;
+            returnObjec.node.data = data;
         }
-        returnObjec.return_list.push({
-            updateTpye:commonConsts.UT_CREATE,
-            moduleName:consts.projectConst.QUANTITY_DETAIL,
-            data:newRecode
-        });
+        returnObjec.newRecord = newRecord;
         return returnObjec;
     }catch (error){
-        returnObjec.err = new Error('输入的表达式有误,请重新输入!');
-        console.log(error)
-        return returnObjec;
-    }
-
-
-}
-
-
-
-function normalUpdate(user_id,datas) {
-    return function(callback) {
-        if(datas.doc.hasOwnProperty('isSummation')){
-            doIsSummationUpdate(datas.query,datas.doc).then(function (sresult) {
-                let returndata ={
-                    moduleName:consts.projectConst.QUANTITY_DETAIL,
-                    data:{
-                        updateTpye:commonConsts.UT_UPDATE,
-                        query:datas.query,
-                        doc:datas.doc
-                    }
-                }
-                let retrunArr = [];
-                retrunArr.push(returndata);
-                if(sresult){
-                    retrunArr.push(sresult);
-                }
-                callback(null,retrunArr);
-            })
-        }else {
-            updateRecored(datas.query,datas.doc,callback);
-        }
-    }
-}
-function updateQuantityRegex(user_id,datas) {
-    return function(callback){
-        doRegexUpdate(datas).then(function (result) {
-            if(result.err){
-                callback(null,{
-                    moduleName:consts.projectConst.QUANTITY_DETAIL,
-                    err:{
-                        message:result.err.message
-                    }
-                });
-            }else {
-                callback(null,result.rList);
-            }
-
-        })
+        console.log(error);
+        throw new Error('输入的表达式有误,请重新输入!');
     }
 }
 
 async function doIsSummationUpdate(query,doc) {
-    try {
-        let returnData={
-            moduleName:'',
-            data:{
-                updateTpye:commonConsts.UT_UPDATE,
-            }
-        }
-        let  refreshQuantity=false;
-        if(query.refreshQuantity==true){
-            refreshQuantity=true;
-        }
-        delete query.refreshQuantity;
-        let updateDoc = await quantity_detail_model.update(query,doc);
-        let detailList = await getDatailList(query,returnData);
-        if(refreshQuantity==true){
-            let quantity = await summateResuts(query,detailList);
-            returnData.data.quantity = quantity;
-            returnData.data.quantityRefresh = true;
-            return returnData;
-        }else {
-            return null;
-        }
-    }catch (error){
-        console.log(error)
+    let returnObjec={query:query,doc:doc};
+    let decimal =await decimal_facade.getProjectDecimal(query.projectID);
+    let  refreshQuantity=false;
+    if(query.refreshQuantity==true){
+        refreshQuantity=true;
     }
+    delete query.refreshQuantity;
+    await quantity_detail_model.update(query,doc);
+    let detailList = await getDatailList(query,returnObjec);
+    if(refreshQuantity==true){
+        let data = {};
+        data.quantity = await summateResults(query,detailList,decimal);
+        data.isFromDetail = 1;
+        returnObjec.node.data = data;
+    }
+    return returnObjec;
 }
 
 async function getDatailList(query,resultObject) {
     let detailList = [];
+    let node={};
     if(query.hasOwnProperty('rationID')){
         detailList = await quantity_detail_model.find({'projectID':query.projectID,'rationID':query.rationID}).sort('seq').exec();
-        resultObject.moduleName = consts.projectConst.RATION;
-        resultObject.data.rationID=query.rationID;
-
+        node.type = consts.projectConst.RATION;
+        node.ID = query.rationID;
     }else {
         detailList = await quantity_detail_model.find({'projectID':query.projectID,'billID':query.billID}).sort('seq').exec();
-        resultObject.moduleName = consts.projectConst.BILLS;
-        resultObject.data.billID=query.billID;
+        node.type = consts.projectConst.BILLS;
+        node.ID=query.billID;
     }
+    resultObject.node = node;
     return detailList;
 }
 
 
-async function doRegexUpdate(datas) {
-    let resultObjec ={
-        err:null,
-        rList:[]
-    }
-    try {
-        let detailList = [];
-        let quantityResult ={
-            moduleName:'',
-            data:{
-                updateTpye:commonConsts.UT_UPDATE,
-                quantityRefresh:true
-            }
-        }
-        if(datas.query.hasOwnProperty('rationID')){
-            detailList = await quantity_detail_model.find({'projectID':datas.query.projectID,'rationID':datas.query.rationID}).sort('seq').exec();
-            quantityResult.moduleName = consts.projectConst.RATION;
-            quantityResult.data.rationID = datas.query.rationID;
-        }else {
-            detailList = await quantity_detail_model.find({'projectID':datas.query.projectID,'billID':datas.query.billID}).sort('seq').exec();
-            quantityResult.data.billID = datas.query.billID;
-            quantityResult.moduleName = consts.projectConst.BILLS;
-        }
-        let regex;
-        let result;
-        if(datas.doc.regex==null){
-            result=0
-            datas.doc.referenceIndexs=[];
-        }else {
-            regex = datas.doc.regex.toUpperCase();
-            let referenceIndexs = datas.doc.referenceIndexs;
-            result =getEvalResult(referenceIndexs,detailList,regex);
-        }
-        detailList[datas.query.index].result =result;
-        detailList[datas.query.index].regex=datas.doc.regex;
-        detailList[datas.query.index].referenceIndexs =datas.doc.referenceIndexs;
-        let updateTasks =[];
-        datas.doc.result=result;
-        updateTasks.push({
-            query:{
-                ID:datas.query.ID,
-                projectID:datas.query.projectID
-            },
-            doc:datas.doc
-        })
-        updateReferenceRecode(datas.query.index+1,detailList,updateTasks);
-        let updateEdit = await quantity_detail_model.bulkWrite(generateUpdateTaks(updateTasks));
-        resultObjec.rList.push(gernerateResultList(updateTasks));
-        if(datas.query.refreshQuantity==true){
-            quantityResult.data.quantity = await summateResuts(datas.query,detailList);
-            resultObjec.rList.push(quantityResult);
-        }
-        return resultObjec;
-    }catch (error){
-        console.log(error);
-        resultObjec.err=error;
-        return resultObjec
-
-    }
-}
-
-function gernerateResultList(updateTasks) {
-    let returndata ={
-        moduleName:consts.projectConst.QUANTITY_DETAIL,
-        data:{
-            updateTpye:commonConsts.UT_UPDATE,
-            refreshList:updateTasks
-        }
-    }
-    return returndata;
-
-}
-
-
-
 function updateReferenceRecode(index,detailList,updateTasks) {
     for(let d of detailList){
         if(_.includes(d.referenceIndexs,index)){
@@ -394,34 +329,52 @@ function updateReferenceRecode(index,detailList,updateTasks) {
 }
 
 
-async function summateResuts (query,detailList) {
+async function summateResults (query,detailList,decimal) {
     let quantity = 0;
+     decimal = decimal?decimal:await decimal_facade.getProjectDecimal(query.projectID);
     for(let d of detailList){
         if(d.isSummation==1){
-            let result = d.result==null||d.result==undefined?0:d.result
+            let result = d.result==null||d.result==undefined?0:d.result;
             quantity+=result;
         }
     }
-    quantity = quantity.toFixed(4);
     if(query.hasOwnProperty('rationID')){
+        let ration = await  ration_model.findOne({'ID':query.rationID,'projectID':query.projectID,deleteInfo: null});
+        quantity = getQuantityByUnit(quantity,ration.unit);
+        quantity = scMathUtil.roundTo(quantity, -decimal.ration.quantity);
         await ration_model.update({'ID':query.rationID,'projectID':query.projectID,deleteInfo: null},{quantity:quantity,isFromDetail:1});
     }else {
+        let bill = await bill_model.findOne({'ID':query.billID,'projectID':query.projectID,deleteInfo: null});
+        decimal = await decimal_facade.getBillsQuantityDecimal(query.projectID,bill.unit);
+        quantity = getQuantityByUnit(quantity,bill.unit);
+        quantity = scMathUtil.roundTo(quantity, -decimal);
         await bill_model.update({'ID':query.billID,'projectID':query.projectID,deleteInfo: null},{quantity:quantity,isFromDetail:1});
     }
     return quantity
 }
 
+function getQuantityByUnit(quantity,unit) {
+    if(unit){
+        let times = parseInt(unit);
+        if(isNaN(times)){
+            times = 1
+        }
+        quantity = quantity/times;
+    }
+    return quantity;
+}
 
 
-function  getEvalResult(referenceIndexs,detailList,regex) {
+ function  getEvalResult(referenceIndexs,detailList,regex,decimal={}) {
     try {
+        decimal = decimal.quantity_detail?decimal.quantity_detail:4;
         for(let i of referenceIndexs){
             regex = replaceReference(i,detailList,regex)
         }
         console.log('replace all C reference -----'+regex);
         regex =replaceSqr(regex);
         console.log('replace all sqar reference -----'+regex);
-        return scMathUtil.roundTo(eval(regex), -4);
+        return scMathUtil.roundTo(eval(regex), -decimal);
     }catch (error){
         console.log(error);
         throw new Error('输入的表达式有误,请重新输入!');
@@ -492,26 +445,6 @@ function converSqrByArr (sqararr,text) {
     return temp;
 };
 
-
-function updateRecored(query,doc,callback) {
-    quantity_detail_model.update(query,doc,(err,result)=>{
-        if(err){
-            callback(err,'');
-        }else {
-            let returndata ={
-                moduleName:consts.projectConst.QUANTITY_DETAIL,
-                data:{
-                    updateTpye:commonConsts.UT_UPDATE,
-                    query:query,
-                    doc:doc
-                }
-            }
-            callback(null,returndata);
-        }
-    })
-}
-
-
 function update_quantity_detail(user_id,datas) {
     if(datas.updateFunction){
         return updateFunctionMap[datas.updateFunction](user_id,datas);
@@ -520,57 +453,43 @@ function update_quantity_detail(user_id,datas) {
     }
 }
 
-function delete_quantity_detail(user_id,datas) {
-    return function (callback) {
-        doQuantityDelete(datas.doc).then(function (result) {
-            if(result.err){
-                callback(result.err,'')
-            }else {
-                callback(null,result.returndata)
-            }
-        });
-    }
-}
 
-async function doQuantityDelete(doc) {;
-    let result={
-        err:null
+async function deleteRecode(doc) {
+    let resultObject = {};
+    let decimal =await decimal_facade.getProjectDecimal(doc.projectID);
+
+    let query = {
+        projectID:doc.projectID,
+        seq : { $gt: doc.seq }
     }
-    try{
-        let query = {
-            projectID:doc.projectID,
-            seq : { $gt: doc.seq }
-        }
-        if(doc.hasOwnProperty('rationID')){
-            query.rationID = doc.rationID;
-        }else {
-            query.billID = doc.billID;
-        }
-        let quantity_detail_List = await getDatailList(doc,{data:{}});
-        let update_task = getUpdateReferenceTask(quantity_detail_List,doc.seq,-1);
-        await quantity_detail_model.update(query,{$inc:{seq:-1}},{multi: true});
-        if(update_task.length>0){
-            await quantity_detail_model.bulkWrite(generateUpdateTaks(update_task));
-        }
-        await quantity_detail_model.deleteOne({ID:doc.ID,projectID:doc.projectID});
-        let returndata ={
-            moduleName:consts.projectConst.QUANTITY_DETAIL,
-            data:{
-                doc:doc,
-                resort:true,
-                update_task:update_task,
-                updateTpye:commonConsts.UT_DELETE
-            }
-        };
-        result.returndata =returndata
-        return result;
-    }catch (error){
-        console.log(error)
-        result.err;
-        return result
+    if(doc.hasOwnProperty('rationID')){
+        query.rationID = doc.rationID;
+    }else {
+        query.billID = doc.billID;
     }
+    let quantity_detail_List = await getDatailList(doc,resultObject);
+    let update_task = getUpdateReferenceTask(quantity_detail_List,doc.seq,-1);
+    await quantity_detail_model.update(query,{$inc:{seq:-1}},{multi: true});
+    if(update_task.length>0){
+        await quantity_detail_model.bulkWrite(generateUpdateTaks(update_task));
+    }
+    await quantity_detail_model.deleteOne({ID:doc.ID,projectID:doc.projectID});
+    _.remove(quantity_detail_List,{ID:doc.ID,projectID:doc.projectID});
+
+    let n_data = {};//更新节点信息
+    n_data.quantity = await summateResults(query,quantity_detail_List,decimal);
+    n_data.isFromDetail = 1;
+    resultObject.node.data = n_data;
+
+    let r_data ={
+            doc:doc,
+            resort:true,
+            update_task:update_task,
+            updateTpye:commonConsts.UT_DELETE
+        };
+    resultObject.data = r_data;
 
-
+    return resultObject;
 }
 
 

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

@@ -11,7 +11,7 @@ let counter = require("../../../public/counter/counter.js");
 let consts = require('./project_consts');
 let projectConsts = consts.projectConst;
 let commonConsts = consts.commonConst;
-let quantity_detial = require('../../ration_glj/facade/quantity_detail_facade');
+let quantity_detial = require('../facade/quantity_detail_facade');
 
 
 let billsSchema = new Schema({

+ 1 - 1
modules/main/models/project.js

@@ -7,7 +7,7 @@ var GLJData = require('./glj');
 var ration_glj_data = require('../../ration_glj/facade/ration_glj_facade');
 var ration_coe_data = require('../../ration_glj/facade/ration_coe_facade');
 var ration_ass_data = require('../../ration_glj/facade/ration_ass_facade');
-var quantity_detail_data = require('../../ration_glj/facade/quantity_detail_facade');
+var quantity_detail_data = require('../facade/quantity_detail_facade');
 var fee_rate_data = require('../../fee_rates/facade/fee_rates_facade');
 let projCounter = require('./proj_counter_model');
 let projSetting = require('./proj_setting_model');

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

@@ -11,7 +11,7 @@ let counter = require("../../../public/counter/counter.js");
 let consts = require('./project_consts');
 let projectConsts = consts.projectConst;
 let commonConsts = consts.commonConst;
-let quantity_detial = require('../../ration_glj/facade/quantity_detail_facade');
+let quantity_detial = require('../facade/quantity_detail_facade');
 
 var rationAssItemSchema = mongoose.Schema({
     name: String,

+ 20 - 0
modules/main/routes/quantity_detail_route.js

@@ -0,0 +1,20 @@
+/**
+ * Created by zhang on 2017/11/24.
+ */
+
+let express = require('express');
+let qdController = require('../controllers/quantity_detail_controller');
+
+module.exports = function (app) {
+
+    var qdRouter = express.Router();
+
+
+    qdRouter.post('/save', qdController.save);
+    qdRouter.post('/update',qdController.update);
+    qdRouter.post('/updateRegex',qdController.updateRegex);
+    qdRouter.post('/insertRecode',qdController.insertRecode);
+    qdRouter.post('/deleteRecode',qdController.deleteRecode);
+    qdRouter.post('/swapRow',qdController.swapRow);
+    app.use('/quantity_detail',qdRouter);
+}

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

@@ -16,7 +16,7 @@ let ration_coe_facade = require('./ration_coe_facade');
 let ration_coe = mongoose.model('ration_coe');
 let std_ration_lib_ration_items = mongoose.model('std_ration_lib_ration_items');
 let glj_calculate_facade = require('./glj_calculate_facade');
-let quantity_detail_facade = require('./quantity_detail_facade');
+let quantity_detail_facade = require('../../main/facade/quantity_detail_facade');
 let logger = require("../../../logs/log_helper").logger;
 import stdgljutil  from "../../../public/cache/std_glj_type_util";
 import EngineeringLibModel from "../../users/models/engineering_lib_model";

+ 31 - 24
web/building_saas/glj/js/project_glj.js

@@ -22,6 +22,7 @@ let mixRatioConnectData = [];
 let mixRatioMap={};
 // 单价文件相关
 let usedUnitPriceInfo = {};
+let usedTenderList = [];
 let otherFileData = {};
 let currentTag = '';
 let isChanging = false;
@@ -162,12 +163,15 @@ $(document).ready(function () {
             // 从其他项目中复制
             changeUnitPriceId = $("#other-file").val();
         }
+        $('#change-dj').modal("hide");
+        $.bootstrapLoading.start();
         $.ajax({
             url: '/glj/change-file',
             type: 'post',
             data: {project_id: scUrlUtil.GetQueryString('project'), change_id: changeUnitPriceId, type: type},
             error: function() {
                 isChanging = false;
+                $.bootstrapLoading.end();
             },
             beforeSend: function() {
                 isChanging = true;
@@ -177,20 +181,16 @@ $(document).ready(function () {
                 if (response.err === 1) {
                     let msg = response.msg !== undefined ? response.msg : '未知错误';
                     alert(msg);
+                    $.bootstrapLoading.end();
                     return false;
                 }
                 projectObj.project.projectGLJ.loadData(function () {
                     let projectGLJ = projectObj.project.projectGLJ;
-                    let data = projectGLJ.datas;
                     projectGLJ.loadCacheData();
-                    let usedTenderList = data.usedTenderList !== undefined ? data.usedTenderList : [];
-                    let  usedUnitPriceInfo = data.constData.usedUnitPriceInfo !== undefined ?
-                        data.constData.usedUnitPriceInfo : {};
-
-                    unitPriceFileInit(usedUnitPriceInfo.name, usedTenderList);
-
+                    unitPriceFileInit();
+                    gljOprObj.refreshView();
+                    $.bootstrapLoading.end();
                 });
-                $('#change-dj').modal("hide");
             }
         });
     });
@@ -204,6 +204,14 @@ $(document).ready(function () {
             $("#notify").slideUp('fast');
         });
     });
+
+    $('#pop-dj').popover({
+            placement:"bottom",
+            html:true,
+            trigger:"hover | focus",
+            content: getUsedTenderInfo
+        }
+    );
 });
 
 /**
@@ -226,14 +234,10 @@ function init() {
                 data.constData.ownCompositionTypes : canNotChangeTypeId;
             GLJTypeConst = data.constData.GLJTypeConst !== undefined ? JSON.parse(data.constData.GLJTypeConst) : GLJTypeConst;
 
-            let usedTenderList = data.usedTenderList !== undefined ? data.usedTenderList : [];
-            usedUnitPriceInfo = data.constData.usedUnitPriceInfo !== undefined ?
-                data.constData.usedUnitPriceInfo : {};
-
             // 连接socket服务器
             socketInit();
 
-            unitPriceFileInit(usedUnitPriceInfo.name, usedTenderList);
+            unitPriceFileInit();
 
             setTimeout(spreadInit, 1);
         } else {
@@ -290,17 +294,19 @@ function spreadInit() {
  * @param {Array} data
  * @return {void}
  */
-function unitPriceFileInit(name, data) {
-    $("#used-name").text(name);
-    let usedCount = data.length <= 0 ? 1 : data.length;
+function unitPriceFileInit() {
+    let projectGLJ = projectObj.project.projectGLJ;
+    let data = projectGLJ.datas;
+     usedTenderList = data.usedTenderList !== undefined ? data.usedTenderList : [];
+    usedUnitPriceInfo = data.constData.usedUnitPriceInfo !== undefined ?
+        data.constData.usedUnitPriceInfo : {};
+    $("#used-name").text(usedUnitPriceInfo.name);
+    let usedCount = usedTenderList.length <= 0 ? 1 : usedTenderList.length;
     $("#used-count").text(usedCount);
-    $('#pop-dj').popover({
-            placement:"bottom",
-            html:true,
-            trigger:"hover | focus",
-            content: data.join('<br>')
-        }
-    );
+}
+
+function getUsedTenderInfo() {
+   return usedTenderList.join("<br>");
 }
 
 /**
@@ -371,4 +377,5 @@ function filterProjectGLJ(jsonData) {
         jsonData = tmpData;
     }
     return jsonData;
-}
+}
+

+ 1 - 1
web/building_saas/main/js/calc/calc_fees.js

@@ -70,7 +70,7 @@ let calcFees = {
     getFee: function (data, fullField) {
         let fields = fullField.split('.'), value = data;
         for (let field of fields) {
-            if (value[field]) {
+            if (value[field]!=undefined||value[field]!=null) {
                 value = value[field];
             } else {
                 return 0;

+ 8 - 14
web/building_saas/main/js/controllers/project_controller.js

@@ -59,20 +59,16 @@ ProjectController = {
             } else if (false) {
                 alert('当前清单已有公式计算,不能套用定额。');
             } else {
-                let firstChild = selected.firstChild();
-                if (firstChild && firstChild.sourceType === project.VolumePrice.getSourceType()) {
-                    alert('当前位置已有量价,不能套用定额。');
+                if (std) {
+                    newSource = project.Ration.insertStdRation(selected.source.getID(), null, std);
+                    project.ration_glj.addRationGLJ(newSource,std);
                 } else {
-                    if (std) {
-                        newSource = project.Ration.insertStdRation(selected.source.getID(), null, std);
-                        project.ration_glj.addRationGLJ(newSource,std);
-                    } else {
-                        newSource = project.Ration.insertRation(selected.source.getID());
-                    }
+                    newSource = project.Ration.insertRation(selected.source.getID());
                 }
+
                 newNode = project.mainTree.insert(selected.getID(), selected.tree.rootID());
             }
-        } else if (selected.sourceType === project.Ration.getSourceType()) {
+        } else if (selected.sourceType === project.Ration.getSourceType() || selected.sourceType === project.VolumePrice.getSourceType()) {
             if (std) {
                 newSource = project.Ration.insertStdRation(selected.source[project.masterField.ration], selected.source, std);
                 project.ration_glj.addRationGLJ(newSource,std);
@@ -80,9 +76,7 @@ ProjectController = {
                 newSource = project.Ration.insertRation(selected.source[project.masterField.ration], selected.source);
             }
             newNode = project.mainTree.insert(selected.getParentID(), selected.getNextSiblingID());
-        } else if (selected.sourceType === project.VolumePrice.getSourceType()) {
-            alert('当前位置已有量价,不能套用定额。');
-        }
+        };
         if (newNode) {
             newNode.source = newSource;
             newNode.sourceType = project.Ration.getSourceType();
@@ -117,7 +111,7 @@ ProjectController = {
         if (selected.sourceType === project.Bills.getSourceType() && selected.source.children.length === 0) {
             newSource = project.VolumePrice.insertVolumePrice(selected.source.getID());
             newNode = project.mainTree.insert(selected.getID(), selected.tree.rootID());
-        } else if (selected.sourceType === project.VolumePrice.getSourceType()) {
+        } else if (selected.sourceType === project.Ration.getSourceType() || selected.sourceType === project.VolumePrice.getSourceType()) {
             newSource = project.VolumePrice.insertVolumePrice(selected.source[project.masterField.volumePrice], selected.source);
             newNode = project.mainTree.insert(selected.getParentID(), selected.getNextSiblingID());
         }

+ 8 - 6
web/building_saas/main/js/models/calc_program.js

@@ -582,6 +582,7 @@ class CalcProgram {
 
         // 汇总定额或子清单的费用类别
         if (treeNode.calcType == treeNodeCalcType.ctGatherRations || treeNode.calcType == treeNodeCalcType.ctGatherBills){
+            treeNode.data.programID = null;
             initFees(treeNode);
 
             let objsArr = (treeNode.calcType == treeNodeCalcType.ctGatherRations) ? project.Ration.getRationsByNode(treeNode) : treeNode.children;
@@ -612,7 +613,7 @@ class CalcProgram {
             treeNode.data.calcTemplate = {"calcItems": rst};
         }
         else{
-            // 叶子清单的缺省计算程序需要提供总金额作为计算基数(不需要工料机),然后每条按比例(费率)计算,不需要工料机明细。
+            // 叶子清单的公式计算:使用缺省清单计算程序需要提供总金额作为计算基数(不需要工料机),然后每条按比例(费率)计算,不需要工料机明细。
             if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue){
                 delete treeNode.data.gljList;
 
@@ -626,16 +627,16 @@ class CalcProgram {
                 treeNode.data.marketTotalFee = (muf * q).toDecimal(me.digit);
                 treeNode.data.gljList = me.project.ration_glj.getGljArrByRation(treeNode.data.ID);
                 if (treeNode.data.programID == undefined){
-                    treeNode.data.programID = 1;
+                    treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
                 };
             }
             else if (treeNode.calcType == treeNodeCalcType.ctBillCalcProgram) {
                 let rations = project.Ration.getBillsSortRation(treeNode.source.getID());
                 treeNode.data.gljList = project.ration_glj.getGatherGljArrByRations(rations);
 
-                if (treeNode.data.programID == undefined){
-                    treeNode.data.programID = 1;
-                };
+                if (treeNode.data.programID == undefined || treeNode.data.programID == defaultBillTemplate.ID){
+                    treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
+                }
             };
 
             let template = me.compiledTemplates[treeNode.data.programID];
@@ -734,7 +735,8 @@ class CalcProgram {
                     programID: node.data.programID,
                     marketUnitFee: node.data.marketUnitFee,
                     marketTotalFee: node.data.marketTotalFee,
-                    fees: node.data.fees
+                    fees: node.data.fees,
+                    isFromDetail:node.data.isFromDetail
                 };
                 let newData = {'updateType': 'ut_update', 'updateData': data};
                 me.project.push(node.sourceType, [newData]);

+ 84 - 62
web/building_saas/main/js/models/quantity_detail.js

@@ -48,13 +48,10 @@ var quantity_detail = {
                 _.forEach(data.update_task,function (item) {
                     me.refreshEachItme(item.query,item.doc);
                 })
-                gljOprObj.detailData.push(data.doc);
                 this.datas.push(data.doc);
             }else {
                 this.datas.push(data);
-                gljOprObj.detailData.push(data);
             }
-            gljOprObj.detailData=_.sortBy(gljOprObj.detailData,'seq');
             this.refreshSheetData();
         };
         quantity_detail.prototype.resortData=function(data,req){
@@ -106,28 +103,13 @@ var quantity_detail = {
                 me.refreshEachItme(item.query,item.doc);
             });
             _.remove(this.datas,{ID:data.doc.ID});
-            _.remove(gljOprObj.detailData,{ID:data.doc.ID});
             this.refreshSheetData();
         };
         quantity_detail.prototype.refreshSheetData=function () {
-            sheetCommonObj.showData(gljOprObj.detailSheet,gljOprObj.detailSetting,gljOprObj.detailData);
-        };
-        quantity_detail.prototype.getUpdateData=function(type,query,doc,callfunction){
-            var updateData = [];
-            var newobj = {
-                'updateType': type,
-                'query': query,
-            }
-            if(doc){
-                newobj['doc']=doc;
-            }
-            if(callfunction){
-                newobj['updateFunction']=callfunction;
-            }
-            updateData.push(newobj);
-            return updateData;
+            gljOprObj.showQuantityDetailData();
         };
         quantity_detail.prototype.saveQuantityDetail=function (args,dataCode) {
+            var me = this;
             var doc={};
             var selected = projectObj.project.mainTree.selected;
             if(selected.sourceType==ModuleNames.ration){
@@ -152,13 +134,25 @@ var quantity_detail = {
                 }
 
             }
-            var updateData
-            if(args.hasOwnProperty("insertRecode")){
-                updateData = this.getUpdateData('ut_update',null,doc,'insertRecode');
+            var url="";
+            $.bootstrapLoading.start();
+            if(args.hasOwnProperty("insertRecode")){//右键插入或者是通过直接编辑保存
+                url = "/quantity_detail/insertRecode";
             }else{
-                updateData = this.getUpdateData('ut_create',null,doc);
+                url = "/quantity_detail/save";
+            }
+            var callback = function (data) {
+                if(doc.refreshQuantity==false){//清空数据
+                    me.cleanQuantityDetail();
+                }else {
+                    data.newRecord?me.refreshAfterSave(data.newRecord):me.refreshAfterSave(data);
+                    data.node?gljOprObj.refreshTreeNode(data.node):"";
+                }
+                $.bootstrapLoading.end();
             }
-            project.pushNow('saveQuantityDetail',[this.getSourceType()],updateData);
+            CommonAjax.post(url,doc,callback,function () {
+                $.bootstrapLoading.end();
+            });
         };
         quantity_detail.prototype.insertQuantityDetail = function (row) {
             var args = {
@@ -169,20 +163,27 @@ var quantity_detail = {
                 args.insertRecode = true;
             }
             this.saveQuantityDetail(args,'isSummation');
-
         };
 
         quantity_detail.prototype.deleteQuantityDetail = function (row) {
+           var me = this;
            var deleteable = this.checkReference(row);
            if(deleteable){
                var recode = gljOprObj.detailData[row];
-               var updateData = this.getUpdateData('ut_delete',null,recode);
-               project.pushNow('deleteQuantityDetail',[this.getSourceType()],updateData);
+               $.bootstrapLoading.start();
+               var callback=function (result) {
+                   me.refreshAfterDelete(result.data);
+                   result.node?gljOprObj.refreshTreeNode(result.node):"";
+                   $.bootstrapLoading.end();
+               }
+               CommonAjax.post("/quantity_detail/deleteRecode",recode,callback,function () {
+                   $.bootstrapLoading.end();
+               });
            }else {
                alert("当前行已被引用,不可删除。");
            }
-
         };
+
         quantity_detail.prototype.checkReference = function (row) {
             var deleteable = true;
            for(var i =0;i<gljOprObj.detailData.length;i++){
@@ -231,13 +232,7 @@ var quantity_detail = {
                     update_task.push({query:{ID:item.ID,projectID:item.projectID},doc:{regex:regex,referenceIndexs:item.referenceIndexs}});
                 }
             })
-
-            var updateData=[];
-            update_task.forEach(function (task) {
-                updateData.push({'updateType': 'ut_update', 'query': task.query,'doc':task.doc});
-            })
-            project.pushNow('updateQuantityDetail',[this.getSourceType()],[updateData]);
-
+            me.commonUpdate("/quantity_detail/swapRow",update_task);
         };
         quantity_detail.prototype.replaceAll=function(FindText, RepText,str) {
             let regExp = new RegExp(FindText, "g");
@@ -281,8 +276,7 @@ var quantity_detail = {
                 }
             }
             if(needupdate){
-                var updateData = this.getUpdateData('ut_update',query,doc,'updateQuantityRegex');
-                project.pushNow('updateQuantityDetail',[this.getSourceType()],updateData);
+                this.commonUpdate("/quantity_detail/updateRegex",{query:query,doc:doc});
             }else {
                 var sheet = subSpread.getActiveSheet();
                 sheet.getCell(args.row,args.col).value(gljOprObj.detailData[args.row].regex);
@@ -312,9 +306,21 @@ var quantity_detail = {
             };
             this.normalUpdate(query,doc);
         };
+        quantity_detail.prototype.commonUpdate = function (url,postData) {
+            var me = this;
+            $.bootstrapLoading.start();
+            var callback = function (data) {
+                me.refreshAfterUpdate(data);
+                data.node?gljOprObj.refreshTreeNode(data.node):"";
+                $.bootstrapLoading.end();
+            }
+            CommonAjax.post(url,postData,callback,function () {
+                $.bootstrapLoading.end();
+            });
+        };
         quantity_detail.prototype.normalUpdate=function(query,doc){
-            var updateData = this.getUpdateData('ut_update',query,doc);
-            project.pushNow('updateQuantityDetail',[this.getSourceType()],updateData);
+            var url = "/quantity_detail/update";
+            this.commonUpdate(url,{query:query,doc:doc});
         };
         quantity_detail.prototype.regexChecking=function(text){
             var regex=/^[0-9Cc\+\-\*\^/\(\)\.]*$/g;
@@ -447,32 +453,48 @@ var quantity_detail = {
                 this.datas = newList;
             }
         };
+        quantity_detail.prototype.cleanQuantityDetail = function (node,needSave) {
+           node =node?node:projectObj.project.mainTree.selected;
+           var query={projectID:node.data.projectID};
+            if(node.sourceType === project.Bills.getSourceType()){
+                query.billID = node.data.ID;
+                this.deleteByBills([{type:'delete',data:node.data}]);
+            }else if(node.sourceType === project.Ration.getSourceType()){
+                this.deleteByRation(node.data);
+                query.rationID = node.data.ID;
+            }
+            if(needSave===true){
+                query.refreshQuantity=false;
+                CommonAjax.post("/quantity_detail/save",query);
+            }
+            gljOprObj.detailData=[];
+            sheetCommonObj.showData(gljOprObj.detailSheet,gljOprObj.detailSetting,[]);
+
+        };
+
         quantity_detail.prototype.quantityEditChecking = function(value,node,fieldName){
             var validate = true;
-            if (value && value != calcFees.getFee(node.data, fieldName)){
-                if(fieldName=='quantity'){
-                   if(node.data.hasOwnProperty('isFromDetail')&&node.data.isFromDetail==1){
-                       var c = confirm('已有工程量明细,是否清空明细表,采用手工输入的表达式?')
-                        if(c){
-                            node.data.isFromDetail=0;
-                            if(node.sourceType === project.Bills.getSourceType()){
-                                this.deleteByBills([{type:'delete',data:node.data}]);
-                            }else if(node.sourceType === project.Ration.getSourceType()){
-                                this.deleteByRation(node.data);
-                            }
-                            gljOprObj.detailData=[];
-                            sheetCommonObj.showData(gljOprObj.detailSheet,gljOprObj.detailSetting,[]);
-
-                            validate = true;
-                        }else {
-                            validate = false;
-                        }
-                   }
-                }
+            if(fieldName=='quantity'){
+               if(node.data.hasOwnProperty('isFromDetail')&&node.data.isFromDetail==1){
+                   var c = confirm('已有工程量明细,是否清空明细表,采用手工输入的表达式?')
+                    if(c){
+                        validate = true;
+                    }else {
+                        validate = false;
+                    }
+               }
             }
             return validate;
-
-        }
+        };
+        quantity_detail.prototype.getDecimal=function (node) {
+            var decimal = 3;
+            if(node.sourceType === project.Bills.getSourceType()){
+                decimal = billsQuanDecimal.decimal(node.data.unit);
+            }else {
+                decimal = decimalObj.ration.quantity
+            }
+            return;
+        };
         return new quantity_detail(project);
     }
 

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

@@ -154,7 +154,7 @@ var Ration = {
         ration.prototype.getInsertRationData = function (billsID, preRation) {
             var br = this.getBillsSortRation(billsID);
             var updateData = [];
-            if (preRation) {
+            if (preRation && br.indexOf(preRation) > -1) {  // CSL, 2017-11-28  如果preIndex是-1,表明preRation 是量价。
                 var preIndex = br.indexOf(preRation), i;
                 updateData.push({updateType: 'ut_create', updateData: this.getTempRationData(this.maxRationID() + 1, billsID, preIndex < br.length - 1 ? br[preIndex + 1].serialNo : br[preIndex].serialNo + 1)});
                 for (i = preIndex + 1; i < br.length; i++) {

+ 4 - 2
web/building_saas/main/js/models/volume_price.js

@@ -51,6 +51,8 @@ var VolumePrice = {
             getTempVolumePrice (newID, billsID, serialNo) {
                 var newData = {'ID': newID, 'serialNo': serialNo, projectID: tools.owner.ID()};
                 newData[project.masterField.volumePrice] = billsID;
+                newData.type = '材料';
+                newData.programID = projectInfoObj.projectInfo.property.engineering;
                 return newData;
             };
             getBillsSortVolumePrice (billsID) {
@@ -75,7 +77,7 @@ var VolumePrice = {
             getInsertVolumePriceData (billsID, pre) {
                 let bv = this.getBillsSortVolumePrice(billsID);
                 let updateData = [];
-                if (pre) {
+                if (pre && bv.indexOf(pre) > -1) {
                     let preIndex = bv.indexOf(pre), i;
                     updateData.push({updateType: 'ut_create', updateData: this.getTempVolumePrice(this.maxID() + 1, billsID, preIndex < bv.length - 1 ? bv[preIndex + 1].serialNo : bv[preIndex].serialNo + 1)});
                     for (i = preIndex + 1; i < bv.length; i++) {
@@ -90,7 +92,7 @@ var VolumePrice = {
                 tools.owner.pushNow('insertVolumePrice', [this.getSourceType(), this.getProject().projCounter()], [this.getInsertVolumePriceData(billsID, pre), this.getCounterData()]);
 
                 let bv = this.getBillsSortVolumePrice(billsID), newVP = null;
-                if (pre) {
+                if (pre && bv.indexOf(pre) > -1) {
                     let preIndex = bv.indexOf(pre);
                     newVP = this.getTempVolumePrice(this.getNewID(), billsID, preIndex < bv.length - 1 ? bv[preIndex + 1].serialNo : bv[preIndex].serialNo + 1);
                     this.datas.push(newVP);

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

@@ -232,7 +232,7 @@ let calcProgramObj = {
             projectObj.project.calcProgram.calculate(treeNode);
             projectObj.project.calcProgram.saveNode(treeNode);
         };
-        me.datas = treeNode.data.calcTemplate.calcItems;
+        me.datas = treeNode.data.calcTemplate ? treeNode.data.calcTemplate.calcItems : [];
         sheetCommonObj.initSheet(me.sheet, me.setting, me.datas.length);
         sheetCommonObj.showData(me.sheet, me.setting, me.datas);
 

+ 28 - 0
web/building_saas/main/js/views/glj_view.js

@@ -671,6 +671,7 @@ var gljOprObj = {
     },
     showQuantityDetailData:function (node) {
         var details=[];
+        node =node?node:projectObj.project.mainTree.selected;
         var quantity_detail =projectObj.project.quantity_detail;
         if(node.sourceType==ModuleNames.ration){
             details=_.filter(quantity_detail.datas,{'rationID':node.data.ID});
@@ -996,6 +997,33 @@ var gljOprObj = {
     refreshView:function () {
         this.showRationGLJData();
     },
+    //
+    refreshTreeNode:function (obj) {
+    if(!obj){
+        return;
+    }
+    var objectArray =[];
+    var nodes =[];
+    if(obj instanceof Array){
+        objectArray.concat(obj);
+    }else {
+        objectArray.push(obj);
+    }
+    for(let o of objectArray ){
+        var node = _.find(projectObj.project.mainTree.items,function (n) {
+            return n.sourceType==o.type&&n.data.ID==o.ID;
+        })
+        if(node){
+            for (var k in o.data){
+                node.data[k] = o.data[k];
+            }
+            nodes.push(node);
+        }
+    }
+
+    projectObj.mainController.refreshTreeNode(nodes);
+
+    },
     getTreeNodeCellType:function (data) {
         var ns = GC.Spread.Sheets;
         var rectW = 10;

+ 19 - 4
web/building_saas/main/js/views/main_tree_col.js

@@ -31,6 +31,15 @@ let MainTreeCol = {
             return node.sourceType !== projectObj.project.VolumePrice.getSourceType();
         },
 
+        calcProgramName: function (node) {
+            if (
+                node.sourceType === projectObj.project.VolumePrice.getSourceType() ||
+                node.sourceType === projectObj.project.Ration.getSourceType() ||
+                (node.sourceType === projectObj.project.Bills.getSourceType() && node.source.children && node.source.children.length === 0 && projectObj.project.projSetting.billsCalcMode === billsPrice)
+            ) return false
+            else return true;
+        },
+
         bills: function (node) {
             return node.sourceType === projectObj.project.Bills.getSourceType();
         },
@@ -85,10 +94,16 @@ let MainTreeCol = {
             return feeRateObject.getFeeRateEditCellType();
         },
 
-        calcProgramName: function () {
-            var names = new GC.Spread.Sheets.CellTypes.ComboBox();
-            names.items(projectObj.project.calcProgram.compiledTemplateNames);
-            return names;
+        calcProgramName: function (node) {
+            if (
+                node.sourceType === projectObj.project.VolumePrice.getSourceType() ||
+                node.sourceType === projectObj.project.Ration.getSourceType() ||
+                (node.sourceType === projectObj.project.Bills.getSourceType() && node.source.children && node.source.children.length === 0 && projectObj.project.projSetting.billsCalcMode === billsPrice)
+            ) {
+                var names = new GC.Spread.Sheets.CellTypes.ComboBox();
+                names.items(projectObj.project.calcProgram.compiledTemplateNames);
+                return names;
+            }
         },
 
         type: function (node) {

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

@@ -21,7 +21,7 @@ let projFeatureView = {
         },
         combos: [
             {row: 1, key: 'projType', items: ['住宅', '公共建筑', '厂房', '办公楼']},
-            {row: 2, key: 'structureType', items: ['排架结构', '框架结构']},
+            {row: 2, key: 'structureType', items: ['排架结构', '框架结构', '现浇、框架结构', '预制、砖混结构', '外砖内模', '内浇外挂', '钢结构']},
             {row: 3, key: 'baseType', items: ['带基', '框排架柱距6m以内', '框排架柱距6m以外', '满基筏式', '满基板式', '满基箱式', '独立基础']},
             {row: 4, key: 'buildingFeature', items: ['点式', '凹式', '凸式', 'Y式', '其他']}
         ],

+ 25 - 33
web/building_saas/main/js/views/project_view.js

@@ -108,7 +108,7 @@ var projectObj = {
                 value = null;
             }
         }
-        if (value) {
+        if (value!=undefined||value!=null) {
             if (colSetting.data.decimal) {
                 value = value.toDecimal(colSetting.data.decimal);   
             }
@@ -268,12 +268,18 @@ var projectObj = {
                 project.FeeRate.updateFeeRateFromBills(value,node,fieldName);
             }
             else if (fieldName === 'quantity' || fieldName === 'marketUnitFee' || fieldName === 'programID' || fieldName === 'type'){
-                if (fieldName === 'quantity' && project.quantity_detail.quantityEditChecking(value,node,fieldName)) {
-                    if (value) {value = value.toDecimal(projectObj.project.Decimal.common.quantity)};
+                if (fieldName === 'quantity') {
+                    if (value) {value = value.toDecimal(project.quantity_detail.getDecimal(node))};
+                   if(project.quantity_detail.quantityEditChecking(value,node,fieldName)){
+                       node.data.isFromDetail=0;
+                       project.quantity_detail.cleanQuantityDetail(node,true);
+                   }else {
+                       projectObj.mainController.refreshTreeNode([node]);
+                       return;
+                   }
                 } else if (fieldName === 'marketUnitFee') {
                     if (value) {value = parseFloat(value).toDecimal(projectObj.project.Decimal.common.unitFee)};
-                };
-
+                }
                 node.changed = true;
                 node.data[fieldName] = value;
                 project.calcProgram.calculate(node);
@@ -414,20 +420,13 @@ var projectObj = {
                     disabled: function () {
                         var selected = project.mainTree.selected;
                         if (selected) {
-                            if (selected.sourceType === project.Ration.getSourceType()) {
-                                return false;
-                            } else if (selected.sourceType === project.Bills.getSourceType()) {
-                                if (selected.source.children.length === 0) {
-                                    return selected.children.length !== 0 ? selected.firstChild().sourceType !== project.Ration.getSourceType() : false;
-                                } else {
-                                    return true;
-                                }
-                            } else if (selected.sourceType === project.VolumePrice.getSourceType()) {
-                                return true;
-                            };
-                        } else {
-                            return true;
-                        }
+                            if (            // CSL, 2017-11-28
+                                selected.sourceType === project.Ration.getSourceType() ||
+                                selected.sourceType === project.VolumePrice.getSourceType() ||
+                                (selected.sourceType === project.Bills.getSourceType() && selected.source.children.length === 0)
+                               ) return false
+                            else return true
+                        } else return true
                     },
                     callback: function (key, opt) {
                         ProjectController.addRation(project, controller);
@@ -439,20 +438,13 @@ var projectObj = {
                     disabled: function () {
                         var selected = project.mainTree.selected;
                         if (selected) {
-                            if (selected.sourceType === project.Ration.getSourceType()) {
-                                return true;
-                            } else if (selected.sourceType === project.Bills.getSourceType()) {
-                                if (selected.source.children.length === 0) {
-                                    return selected.children.length !== 0 ? selected.firstChild().sourceType !== project.VolumePrice.getSourceType() : false;
-                                } else {
-                                    return true;
-                                }
-                            } else if (selected.sourceType === project.VolumePrice.getSourceType()) {
-                                return false;
-                            };
-                        } else {
-                            return true;
-                        }
+                            if (            // CSL, 2017-11-28
+                            selected.sourceType === project.Ration.getSourceType() ||
+                            selected.sourceType === project.VolumePrice.getSourceType() ||
+                            (selected.sourceType === project.Bills.getSourceType() && selected.source.children.length === 0)
+                            ) return false
+                            else return true
+                        } else return true
                     },
                     callback: function (key, opt) {
                         ProjectController.addVolumePrice(project, controller);

+ 5 - 1
web/building_saas/pm/js/pm_main.js

@@ -82,8 +82,12 @@ let ProjTreeSetting = {
                 tdBindEvent: function (td, node) {
                     if (node.data.projType === projectType.tender) {
                         $('a:eq(1)', td).bind('click', function () {
+                            let newTab = window.open('about:blank');
                             BeforeOpenProject(node.id(), {'fullFolder': GetFullFolder(node.parent)}, function () {
-                                window.location.href = '/main?project=' + node.id();
+                                let mainUrl = '/main?project=' + node.id();
+                                CommonAjax.get(mainUrl, [], function () {
+                                    newTab.location.href = mainUrl;
+                                });
                             });
                             return false;
                         });