Browse Source

Merge branch 'master' of http://192.168.1.41:3000/SmartCost/YangHuCost

zhangweicheng 5 năm trước cách đây
mục cha
commit
c53936129a

+ 2 - 1
modules/all_models/projects.js

@@ -38,7 +38,8 @@ const ProjectSchema = new Schema({
     },
     "changeMark":String,//更新标记  feeRate:费率文件发生了改变,unitFile 单件文件发生了改变
     "remark":String, //备注
-    "fileVer": String
+    "fileVer": String,  // 创建时程序版本号
+    "lastFileVer": String  // 最新打开并计算时的程序版本号
 });
 
 mongoose.model(collectionName, ProjectSchema, collectionName);

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

@@ -39,14 +39,14 @@ module.exports = {
         // Project.getFilterData(data.project_id, ['bills', 'projectGLJ'], function (err, result) {
         //     console.log(result);
         // });
-        //test
+        const isReport = false;
         Project.getData(data.project_id, function (err, message, result) {
             if (!err) {
                 callback(req, res, err, message, result);
             } else {
                 callback(req, res, err, message, null);
             }
-        }, req.session.sessionUser.id);
+        }, isReport, req.session.sessionUser.id);
     },
     markUpdateProject:async function (req,res) {
         let result={

+ 1 - 0
modules/main/facade/ration_facade.js

@@ -972,6 +972,7 @@ async function getMixRatioInfo(projectID,projectGLJMap,newProjectGLJList,mixRati
 
 }
 
+
 function getStdGlj(sub,stdGLJMap,cptGLJMap,newGLJ,ext) {
     let std_glj = null;
     if(sub.type == 'complementary'){//有可能来自标准工料机库或补充工料机库

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

@@ -32,10 +32,24 @@ class billsModel extends baseModel {
         super(bills);
     };
 
-    getData (projectID, callback) {
+    getData (projectID, callback, isReport = false) {
         //已经改成真删除了 {'$or': [{projectID: projectID, deleteInfo: null}, {projectID: projectID, 'deleteInfo.deleted': {$in: [null, false]}}]}
         this.model.find({projectID: projectID}, '-_id', function(err, datas){
             if (!err) {
+                if (isReport){   // 调价中间件机制
+                    for (let i = 0; i < datas.length; i++) {
+                       let fees = datas[i]._doc.fees;
+                       if (fees){
+                           for (let i = 0; i < fees.length; i++) {
+                               let doc = fees[i]._doc;
+                               if (doc){
+                                   if (doc.tenderTotalFee) doc.totalFee = doc.tenderTotalFee;
+                                   if (doc.tenderUnitFee) doc.unitFee = doc.tenderUnitFee;
+                               }
+                           }
+                       }
+                    }
+                };
                 callback(0, projectConsts.BILLS, datas);
             } else {
                 callback(1, projectConsts.BILLS, null);

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

@@ -99,7 +99,7 @@ Project.prototype.save = function(datas, callback){
     me.datas = [];
 };
 
-Project.prototype.getData = function(projectID, callback, userID){
+Project.prototype.getData = function(projectID, callback, isReport, userID){
     var functions = [];
     var itemName;
     let firstTime = +new Date();
@@ -108,7 +108,7 @@ Project.prototype.getData = function(projectID, callback, userID){
             return function (cb) {
                 moduleMap[itemName].getData(projectID, function(err, moduleName, data){
                     cb(err, {moduleName: moduleName, data: data})
-                }, userID)
+                }, isReport, userID)
             }
         })(itemName))
     }
@@ -132,7 +132,7 @@ Project.prototype.getFilterData = function (projectID, filter, callback) {
             if (moduleMap[moduleName]) {
                 moduleMap[moduleName].getData(projectID, function (err, name, data) {
                     cb(err, {'moduleName': name, 'data': data})
-                });
+                }, true);     // 所有报表只显示调价后的数据,这里传入一个标记true,子方法会将调价后的值赋给调价前的字段,这样报表可以不用动。
             } else if (moduleName === projectConsts.PROJECTGLJ) {
                 try {
                     if (isNaN(projectID) || projectID <= 0) {

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

@@ -17,9 +17,29 @@ class rationModel extends baseModel {
         super(ration);
     }
 
-    getData (projectID, callback) {
+    getData (projectID, callback, isReport = false) {
         ration.find({projectID: projectID}, '-_id', function(err, datas){//{'$or': [{projectID: projectID, deleteInfo: null}, {projectID: projectID, 'deleteInfo.deleted': {$in: [null, false]}}]}
             if (!err) {
+                if (isReport){  // 调价中间件机制
+                    for (let i = 0; i < datas.length; i++) {
+                        let coe = datas[i]._doc.rationQuantityCoe;
+                        if ((!coe) || (coe == '0')) coe = 1;
+                        //如有调价,则需要改动
+                        datas[i]._doc.quantity = parseFloat(datas[i]._doc.quantity) * parseFloat(coe);
+                        datas[i]._doc.contain = parseFloat(datas[i]._doc.contain) * parseFloat(coe);
+
+                        let fees = datas[i]._doc.fees;
+                        if (fees){
+                            for (let i = 0; i < fees.length; i++) {
+                                let doc = fees[i]._doc;
+                                if (doc){
+                                    if (doc.tenderTotalFee) doc.totalFee = doc.tenderTotalFee;
+                                    if (doc.tenderUnitFee) doc.unitFee = doc.tenderUnitFee;
+                                }
+                            }
+                        }
+                    }
+                };
                 callback(0, projectConsts.RATION, datas);
             } else {
                 callback(1, '', null);

+ 169 - 170
modules/pm/controllers/pm_controller.js

@@ -34,14 +34,14 @@ let consts = require('../../main/models/project_consts');
 let rp = require('request-promise');
 const commonUtil = require('../../../public/common_util');
 //统一回调函数
-let callback = function(req, res, err, message, data){
-    res.json({error: err, message: message, data: data});
+let callback = function (req, res, err, message, data) {
+    res.json({ error: err, message: message, data: data });
 };
 
 
 module.exports = {
     checkRight: function (req, res) {
-        if(typeof req.body.data === 'object'){
+        if (typeof req.body.data === 'object') {
             req.body.data = JSON.stringify(req.body.data);
         }
         let data = JSON.parse(req.body.data);
@@ -60,7 +60,7 @@ module.exports = {
             let shareInfo = null;
             let isOpenShareProject = false;
             //判断是否是打开分享的项目,分享项目shareInfo不为null
-            if(userId !== result.userID){
+            if (userId !== result.userID) {
                 shareInfo = await pm_facade.getShareInfo(userId, result.ID);
                 isOpenShareProject = true;
             }
@@ -74,7 +74,7 @@ module.exports = {
             callback(false);
         });
     },
-    getProjects: async function(req, res){
+    getProjects: async function (req, res) {
          await ProjectsData.getUserProjects(req.session.sessionUser.id, req.session.sessionCompilation._id, function(err, message, projects){
             if (projects) {
                 callback(req, res, err, message, projects);
@@ -84,8 +84,8 @@ module.exports = {
         });
     },
     updateProjects: async function (req, res) {
+        let data = JSON.parse(req.body.data);
         try {
-            let data = JSON.parse(req.body.data);
             await ProjectsData.updateUserProjects(req.session.sessionUser.id, req.session.sessionCompilation._id, req.session.sessionCompilation, data.updateData, function (err, message, data) {
                 if (err === 0) {
                     callback(req, res, err, message, data);
@@ -99,7 +99,7 @@ module.exports = {
         }
     },
     // CSL, 2017-12-14 该方法用于项目属性:提交保存混合型数据,这些数据来自不同的表,包括projects.property、ration、bills、labour_coes.
-    updateMixDatas: async function(req, res){
+    updateMixDatas: async function (req, res) {
         let datas = JSON.parse(req.body.data).mixDataArr;
         let functions = [];
 
@@ -109,7 +109,7 @@ module.exports = {
             }
         };
 
-        function updateLC(){
+        function updateLC() {
             return function (cb) {
                 datas.labourCoes.updateData.projectID = datas.projectID;
                 labourCoe.save(datas.labourCoes.updateData, cb);
@@ -117,84 +117,84 @@ module.exports = {
         };
 
         // 项目属性
-        if (Object.keys(datas.properties).length > 0){
+        if (Object.keys(datas.properties).length > 0) {
             //基本信息特殊处理,更新建设项目
-            if(datas.properties['property.basicInformation']){
+            if (datas.properties['property.basicInformation']) {
                 let constructionProject = await pm_facade.getConstructionProject(datas.projectID);
-                if(constructionProject){
-                    functions.push(updateFunc(projectModel, {ID: constructionProject.ID}, {'property.basicInformation': datas.properties['property.basicInformation']}));
+                if (constructionProject) {
+                    functions.push(updateFunc(projectModel, { ID: constructionProject.ID }, { 'property.basicInformation': datas.properties['property.basicInformation'] }));
                 }
                 delete datas.properties['property.basicInformation'];
             }
-            functions.push(updateFunc(projectModel, {ID: datas.projectID}, datas.properties));
+            functions.push(updateFunc(projectModel, { ID: datas.projectID }, datas.properties));
         };
 
         //选项
-        if(datas.options && datas.options.updateData){
-            functions.push(updateFunc(optionModel, {user_id: req.session.sessionUser.id, compilation_id: req.session.sessionCompilation._id}, {'options.GENERALOPTS': datas.options.updateData}));
+        if (datas.options && datas.options.updateData) {
+            functions.push(updateFunc(optionModel, { user_id: req.session.sessionUser.id, compilation_id: req.session.sessionCompilation._id }, { 'options.GENERALOPTS': datas.options.updateData }));
         }
 
         // 人工系数
-        if (datas.labourCoes&&datas.labourCoes.updateData){
+        if (datas.labourCoes && datas.labourCoes.updateData) {
             functions.push(updateLC());
         };
 
         // 清单:每文档doc只存储一条清单,每条清单都必须定位一次文档,无法合并处理
-        if (datas.bills.length > 0){
-            for (let bill of datas.bills){
-                functions.push(updateFunc(billsModel, {projectID: datas.projectID, ID: bill.ID, deleteInfo: null}, bill));
+        if (datas.bills && datas.bills.length > 0) {
+            for (let bill of datas.bills) {
+                functions.push(updateFunc(billsModel, { projectID: datas.projectID, ID: bill.ID, deleteInfo: null }, bill));
             };
         };
 
         // 定额:每文档doc只存储一条定额,每条定额都必须定位一次文档,无法合并处理
-        if (datas.rations.length > 0){
-            for (let ration of datas.rations){
-                functions.push(updateFunc(rationsModel, {projectID: datas.projectID, ID: ration.ID, deleteInfo: null}, ration));
+        if (datas.rations && datas.rations.length > 0) {
+            for (let ration of datas.rations) {
+                functions.push(updateFunc(rationsModel, { projectID: datas.projectID, ID: ration.ID, deleteInfo: null }, ration));
             };
         };
 
-        asyncTool.parallel(functions, function(err, result){
+        asyncTool.parallel(functions, function (err, result) {
             {
                 if (!err) {
-                    res.json({error: 0, message: err, data: result});
+                    res.json({ error: 0, message: err, data: result });
                 } else {
-                    res.json({error: 1, message: err, data: null});
+                    res.json({ error: 1, message: err, data: null });
                 }
             }
         });
     },
-    updateFiles: async function(req, res){
+    updateFiles: async function (req, res) {
         let data = JSON.parse(req.body.data);
         let updateDatas = data.updateDatas;
         await ProjectsData.udpateUserFiles(req.session.sessionUser.id, updateDatas, function (err, message, data) {
             callback(req, res, err, message, data);
         });
     },
-    defaultSettings: async function(req, res){
-        try{
+    defaultSettings: async function (req, res) {
+        try {
             let data = JSON.parse(req.body.data);
             let projectID = data.projectID;
             let defaultSettingSc = await ProjectsData.defaultSettings(req.session.sessionUser.id, req.session.sessionCompilation, projectID);
-            if(!defaultSettingSc){
+            if (!defaultSettingSc) {
                 throw '恢复失败';
             }
-            res.json({error: 0, message: '恢复成功', data: null});
+            res.json({ error: 0, message: '恢复成功', data: null });
         }
-        catch(error){
+        catch (error) {
             console.log(error);
-            res.json({error: 1, message: error, data: null});
-        }
-    },
- /*   copyProjects: function (req, res) {
-        let data = JSON.parse(req.body.data);
-        ProjectsData.copyUserProjects(req.session.sessionUser.id, req.session.sessionCompilation._id, data.updateData, function (err, message, data) {
-            if (err === 0) {
-                callback(req, res, err, message, data);
-            } else {
-                callback(req, res, err, message, null);
-            }
-        });
-    },*/
+            res.json({ error: 1, message: error, data: null });
+        }
+    },
+    /*   copyProjects: function (req, res) {
+           let data = JSON.parse(req.body.data);
+           ProjectsData.copyUserProjects(req.session.sessionUser.id, req.session.sessionCompilation._id, data.updateData, function (err, message, data) {
+               if (err === 0) {
+                   callback(req, res, err, message, data);
+               } else {
+                   callback(req, res, err, message, null);
+               }
+           });
+       },*/
     rename: function (req, res) {
         let data = JSON.parse(req.body.data);
         ProjectsData.rename(req.session.sessionUser.id, req.session.sessionCompilation._id, data, function (err, message) {
@@ -202,8 +202,8 @@ module.exports = {
         });
     },
     //project getData接口
-    getData: function(projectID, callback, userID) {
-        projectModel.findOne({$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], ID: projectID}, '-_id').then(async function (project) {
+    getData: function (projectID, callback, isReport, userID) {
+        projectModel.findOne({ $or: [{ deleteInfo: null }, { 'deleteInfo.deleted': false }], ID: projectID }, '-_id').then(async function (project) {
             if (!project) {
                 callback('', consts.projectConst.PROJECT_INFO, {});
             }
@@ -212,10 +212,10 @@ module.exports = {
                 await engineeringLibModel.getEngineering(project.property.engineering_id) : null;
             let projInfo = project._doc;
             if (engineeringInfo !== null) {
-                if(engineeringInfo.billsGuidance_lib){
-                    for(let billsGuidanceLib of engineeringInfo.billsGuidance_lib){
-                        let stdBillsGuidanceLib = await stdBillsGuidanceLibModel.findOne({ID: billsGuidanceLib.id});
-                        if(stdBillsGuidanceLib){
+                if (engineeringInfo.billsGuidance_lib) {
+                    for (let billsGuidanceLib of engineeringInfo.billsGuidance_lib) {
+                        let stdBillsGuidanceLib = await stdBillsGuidanceLibModel.findOne({ ID: billsGuidanceLib.id });
+                        if (stdBillsGuidanceLib) {
                             billsGuidanceLib.type = stdBillsGuidanceLib.type ? stdBillsGuidanceLib.type : 1;
                         }
                     }
@@ -244,10 +244,10 @@ module.exports = {
             callback(err, consts.projectConst.PROJECT_INFO, {});
         });
     },
-    getProject: function(req, res){
+    getProject: function (req, res) {
         let data = JSON.parse(req.body.data);
         let projectID = data.proj_id;
-        ProjectsData.getUserProject(req.session.sessionUser.id, data.proj_id, async function(err, message, data){
+        ProjectsData.getUserProject(req.session.sessionUser.id, data.proj_id, async function (err, message, data) {
             if (err === 0) {
                 let engineeringLibModel = new EngineeringLibModel();
                 let engineeringInfo = data !== null && data.property.engineering_id !== undefined ?
@@ -255,10 +255,10 @@ module.exports = {
                 let strData = JSON.stringify(data);
                 let projInfo = JSON.parse(strData);
                 if (engineeringInfo !== null) {
-                    if(engineeringInfo.billsGuidance_lib){
-                        for(let billsGuidanceLib of engineeringInfo.billsGuidance_lib){
-                            let stdBillsGuidanceLib = await stdBillsGuidanceLibModel.findOne({ID: billsGuidanceLib.id});
-                            if(stdBillsGuidanceLib){
+                    if (engineeringInfo.billsGuidance_lib) {
+                        for (let billsGuidanceLib of engineeringInfo.billsGuidance_lib) {
+                            let stdBillsGuidanceLib = await stdBillsGuidanceLibModel.findOne({ ID: billsGuidanceLib.id });
+                            if (stdBillsGuidanceLib) {
                                 billsGuidanceLib.type = stdBillsGuidanceLib.type ? stdBillsGuidanceLib.type : 1;
                             }
                         }
@@ -292,12 +292,11 @@ module.exports = {
         });
     },
     // 项目管理首页
-    index: async function(request, response) {
-        // 上线后删除,处理旧的分享数据
-        // await pm_facade.prepareShareList();
+    index: async function (request, response) {
+        //await pm_facade.prepareShareList();
         // 获取编办信息
         let sessionCompilation = request.session.sessionCompilation;
-        if (sessionCompilation === undefined ||sessionCompilation ===null) {
+        if (sessionCompilation === undefined || sessionCompilation === null) {
             return response.redirect('/logout');
         }
         let compilationModel = new CompilationModel();
@@ -306,7 +305,6 @@ module.exports = {
         request.session.sessionCompilation = compilationData;
         sessionCompilation = request.session.sessionCompilation;
         //更新用户的使用过的费用定额列表
-        //是否第一次进入该费用定额
         let isFirst = await pm_facade.isFirst(request.session.sessionUser.id, compilationData._id.toString());
         // 清单计价
         let billValuation = sessionCompilation.bill_valuation !== undefined ?
@@ -321,7 +319,7 @@ module.exports = {
             sessionCompilation.ration_valuation : [];
         rationValuation = await engineeringLibModel.getLib(rationValuation);
         let absoluteUrl = compilationData.overWriteUrl ? request.app.locals.rootDir + compilationData.overWriteUrl : request.app.locals.rootDir;
-        let overWriteUrl = fs.existsSync(absoluteUrl) && fs.statSync(absoluteUrl).isFile()? compilationData.overWriteUrl : null;
+        let overWriteUrl = fs.existsSync(absoluteUrl) && fs.statSync(absoluteUrl).isFile() ? compilationData.overWriteUrl : null;
         //欢迎页显示控制
         let [isShow,context,showTime] = await pm_facade.getWelcomeInfo(sessionCompilation._id,request.session.sessionUser,request.session.compilationVersion.includes('学习'));
         const unreadShareList = await pm_facade.getUnreadShareListByCompilation(request.session.sessionUser.id, sessionCompilation._id);
@@ -348,7 +346,7 @@ module.exports = {
         response.render('building_saas/pm/html/project-management.html', renderData);
     },
     //第一次进入该费用定额时准备的初始数据
-    prepareInitialData: async function(request, response) {
+    prepareInitialData: async function (request, response) {
         try {
             const data = {
                 userID: request.session.sessionUser.id,
@@ -357,19 +355,19 @@ module.exports = {
             };
             await redirectToImportServer(data, 'prepareInitialData', request);
             callback(request, response, 0, 'success', null);
-        } catch(err) {
+        } catch (err) {
             console.log(err);
             callback(request, response, 1, err.toString(), null);
         }
     },
     // 获取单价文件列表
-    getUnitFileList: async function(request, response) {
+    getUnitFileList: async function (request, response) {
         let data = request.body.data;
         try {
             data = JSON.parse(data);
             let projectId = data.parentID !== undefined ? data.parentID : 0;
             if (isNaN(projectId) && projectId <= 0) {
-                throw {msg: 'id数据有误!', err: 1};
+                throw { msg: 'id数据有误!', err: 1 };
             }
             /*// 获取对应建设项目下所有的单位工程id
             let idList = await ProjectsData.getTenderByProjectId(projectId);
@@ -381,7 +379,7 @@ module.exports = {
             let unitPriceFileData = await unitPriceFileModel.getDataByRootProject(projectId);
 
             if (unitPriceFileData === null) {
-                throw {msg: '不存在对应单价文件', err: 0};
+                throw { msg: '不存在对应单价文件', err: 0 };
             }
 
             // 整理数据
@@ -401,17 +399,17 @@ module.exports = {
             callback(request, response, error.err, error.msg, responseData);
         }
     },
-    getFeeRateFileList:async function(request, response) {
+    getFeeRateFileList: async function (request, response) {
         let data = request.body.data;
         try {
             data = JSON.parse(data);
             let projectId = data.parentID !== undefined ? data.parentID : 0;
             if (isNaN(projectId) && projectId <= 0) {
-                throw {msg: 'id数据有误!', err: 1};
+                throw { msg: 'id数据有误!', err: 1 };
             }
             // 获取对应建设项目下所有的单位工程id
             let feeRateFileList = await fee_rate_facade.getFeeRatesByProject(projectId);
-            callback(request, response, 0, '',feeRateFileList );
+            callback(request, response, 0, '', feeRateFileList);
         } catch (error) {
             console.log(error);
             let responseData = error.err === 1 ? null : [];
@@ -452,45 +450,45 @@ module.exports = {
         }
     },
 
-    getGCDatas: async function(request, response) {
+    getGCDatas: async function (request, response) {
         let userID = request.session.sessionUser.id;
         let compilatoinId = request.session.sessionCompilation._id;
         let rst = [];
         let _projs = Object.create(null), _engs = Object.create(null), prefix = 'ID_';
-        try{
+        try {
             let gc_unitPriceFiles = await ProjectsData.getGCFiles(fileType.unitPriceFile, userID);
             let gc_feeRateFiles = await ProjectsData.getGCFiles(fileType.feeRateFile, userID);
             let gc_tenderFiles = await ProjectsData.getGCFiles(projType.tender, userID);
-            for(let i = 0, len = gc_unitPriceFiles.length; i < len; i++){
+            for (let i = 0, len = gc_unitPriceFiles.length; i < len; i++) {
                 let gc_uf = gc_unitPriceFiles[i];
                 let theProj = _projs[prefix + gc_uf.root_project_id] || null;
-                if(!theProj){
+                if (!theProj) {
                     let tempProj = await ProjectsData.getProjectsByIds(userID, compilatoinId, [gc_uf.root_project_id]);
-                    if(tempProj.length > 0 && tempProj[0].projType !== projType.folder){
+                    if (tempProj.length > 0 && tempProj[0].projType !== projType.folder) {
                         theProj = _projs[prefix + gc_uf.root_project_id] = tempProj[0]._doc;
                         buildProj(theProj);
                     }
                 }
-                if(theProj){
+                if (theProj) {
                     theProj.unitPriceFiles.push(gc_uf);
                 }
             }
-            for(let i = 0, len = gc_feeRateFiles.length; i < len; i++){
+            for (let i = 0, len = gc_feeRateFiles.length; i < len; i++) {
                 let gc_ff = gc_feeRateFiles[i];
                 let theProj = _projs[prefix + gc_ff.rootProjectID] || null;
-                if(!theProj){
+                if (!theProj) {
                     let tempProj = await ProjectsData.getProjectsByIds(userID, compilatoinId, [gc_ff.rootProjectID]);
-                    if(tempProj.length > 0 && tempProj[0].projType !== projType.folder){
+                    if (tempProj.length > 0 && tempProj[0].projType !== projType.folder) {
                         theProj = _projs[prefix + gc_ff.rootProjectID] = tempProj[0]._doc;
                         buildProj(theProj);
                     }
                 }
-                if(theProj) {
+                if (theProj) {
                     theProj.feeRateFiles.push(gc_ff);
                 }
             }
-            if(gc_tenderFiles.length > 0){
-                for(let i = 0, len = gc_tenderFiles.length; i < len; i++){
+            if (gc_tenderFiles.length > 0) {
+                for (let i = 0, len = gc_tenderFiles.length; i < len; i++) {
                     let gc_t = gc_tenderFiles[i];
                     let theProj = _projs[prefix + gc_t.ParentID] || null;
                     if(!theProj){
@@ -505,22 +503,22 @@ module.exports = {
                     }
                 }
             }
-            for(let i in _projs){
+            for (let i in _projs) {
                 rst.push(_projs[i]);
             }
-            function buildProj(proj){
+            function buildProj(proj) {
                 proj.children = [];
                 proj.unitPriceFiles = [];
                 proj.feeRateFiles = [];
             }
             callback(request, response, 0, 'success', rst);
         }
-        catch (error){
+        catch (error) {
             callback(request, response, true, error, null);
         }
     },
 
-    recGC: function(request, response){
+    recGC: function (request, response) {
         let userID = request.session.sessionUser.id,
             compilationId = request.session.sessionCompilation._id;
         let data = JSON.parse(request.body.data);
@@ -528,76 +526,76 @@ module.exports = {
         ProjectsData.recGC(userID, compilationId, nodes, function (err, msg, data) {
             callback(request, response, err, msg, data);
         });
-   },
+    },
 
-    delGC: async function(request, response){
+    delGC: async function (request, response) {
         let data = JSON.parse(request.body.data);
         let delDatas = data.delDatas;
         let bulkProjs = [], bulkUFs = [], bulkFFs = [];
-        try{
-            for(let data of delDatas){
-                if(data.updateType === 'Project'){
-                    bulkProjs.push({updateOne: {filter: {ID: data.ID}, update: {'deleteInfo.completeDeleted': true}}});
+        try {
+            for (let data of delDatas) {
+                if (data.updateType === 'Project') {
+                    bulkProjs.push({ updateOne: { filter: { ID: data.ID }, update: { 'deleteInfo.completeDeleted': true } } });
                 }
-                else if(data.updateType === fileType.unitPriceFile){
-                    bulkUFs.push({updateOne: {filter: {id: data.ID}, update: {'deleteInfo.completeDeleted': true}}});
+                else if (data.updateType === fileType.unitPriceFile) {
+                    bulkUFs.push({ updateOne: { filter: { id: data.ID }, update: { 'deleteInfo.completeDeleted': true } } });
                 }
-                else{
-                    bulkFFs.push({updateOne: {filter: {ID: data.ID}, update: {'deleteInfo.completeDeleted': true}}});
+                else {
+                    bulkFFs.push({ updateOne: { filter: { ID: data.ID }, update: { 'deleteInfo.completeDeleted': true } } });
                 }
             }
-            if(bulkProjs.length > 0){
+            if (bulkProjs.length > 0) {
                 await projectModel.bulkWrite(bulkProjs);
             }
-            if(bulkUFs.length > 0){
+            if (bulkUFs.length > 0) {
                 await unitPriceFileModel.bulkWrite(bulkUFs);
             }
-            if(bulkFFs.length > 0){
+            if (bulkFFs.length > 0) {
                 await feeRateFileModel.bulkWrite(bulkFFs);
             }
             callback(request, response, 0, 'success', null);
-        } catch(err){
+        } catch (err) {
             callback(request, response, 1, err, null);
         }
     },
-    moveProject:async function(req,res){
-        let result={
-            error:0
+    moveProject: async function (req, res) {
+        let result = {
+            error: 0
         };
         try {
             let data = req.body.data;
-            let rdata= await pm_facade.moveProject(data);
-            result.data= rdata;
-        }catch (err){
+            let rdata = await pm_facade.moveProject(data);
+            result.data = rdata;
+        } catch (err) {
             console.log(err);
-            result.error=1;
+            result.error = 1;
             result.message = err.message;
         }
         res.json(result);
     },
-    copyProjects:async function (req, res) {
-        let result={
-            error:0
+    copyProjects: async function (req, res) {
+        let result = {
+            error: 0
         };
         try {
-            let data = {dataString:req.body.data,userID:req.session.sessionUser.id,compilationID:req.session.sessionCompilation._id};
-            result = await redirectToImportServer(data,"copyProject",req);
-        }catch (err){
+            let data = { dataString: req.body.data, userID: req.session.sessionUser.id, compilationID: req.session.sessionCompilation._id };
+            result = await redirectToImportServer(data, "copyProject", req);
+        } catch (err) {
             console.log(err);
-            result.error=1;
+            result.error = 1;
             result.message = err.message;
         }
         res.json(result);
     },
-    projectShareInfo: async function(req, res){
-        try{
+    projectShareInfo: async function (req, res) {
+        try {
             const data = JSON.parse(req.body.data);
-            const shareList = await pm_facade.getShareList({projectID: data.projectID});
+            const shareList = await pm_facade.getShareList({ projectID: data.projectID });
             const shareInfoMap = await pm_facade.getShareInfoMap(null, shareList);
             const shareInfo = shareInfoMap[data.projectID] || [];
             callback(req, res, 0, 'success', shareInfo);
         }
-        catch (err){
+        catch (err) {
             callback(req, res, 1, err, null);
         }
     },
@@ -704,7 +702,7 @@ module.exports = {
             const rstTask = [
                 pm_facade.getRecentShareList(userID, count),
                 userModelObj.getContacts(userID)
-            ]
+            ];
             // 获取需要广播推送的单位工程
             // shareData数组的形式是以前需求需要,现在的需求下,shareData数组必定只有一个元素
             const emitTenders = await pm_facade.getShareInfoAfterChangePermission(permissionType, shareData[0].userID, projectID);
@@ -720,20 +718,20 @@ module.exports = {
             callback(req, res, 1, String(err), null);
         }
     },
-    receiveProjects: async function(req, res) {
+    receiveProjects: async function (req, res) {
         try {
-            let rst = {grouped: [], ungrouped: [], summaryInfo: null};
+            let rst = { grouped: [], ungrouped: [], summaryInfo: null };
             let userID = req.session.sessionUser.id;
             const shareList = await pm_facade.getShareList({ receiver: userID });
             const receiveProjectIDs = shareList.map(item => item.projectID);
             const compilation = req.session.sessionCompilation._id;
-            const notDeleted = [{deleteInfo: null}, {'deleteInfo.deleted': false}];
-            const receiveProjects = await projectModel.find({ID: {$in: receiveProjectIDs}, compilation, $or: notDeleted}, '-_id').lean();
+            const notDeleted = [{ deleteInfo: null }, { 'deleteInfo.deleted': false }];
+            const receiveProjects = await projectModel.find({ ID: { $in: receiveProjectIDs }, compilation, $or: notDeleted }, '-_id').lean();
             //设置原项目用户信息
             const shareInfoMap = await pm_facade.getShareInfoMap(null, shareList);
-            if(receiveProjects.length > 0){
+            if (receiveProjects.length > 0) {
                 let orgUserIDs = [];
-                for(let proj of receiveProjects){
+                for (let proj of receiveProjects) {
                     orgUserIDs.push(proj.userID);
                     if (proj.projType === projType.tender) {
                         // 设置项目类别
@@ -747,14 +745,14 @@ module.exports = {
                 }
                 orgUserIDs = Array.from(new Set(orgUserIDs));
                 let userObjIDs = [];
-                for(let uID of orgUserIDs){
+                for (let uID of orgUserIDs) {
                     userObjIDs.push(mongoose.Types.ObjectId(uID));
                 }
-                let orgUsersInfo = await userModel.find({_id: {$in : userObjIDs}});
+                let orgUsersInfo = await userModel.find({ _id: { $in: userObjIDs } });
                 //建设项目
                 let consProjIDs = [],
                     ungroupedTenders = [];
-                for(let proj of receiveProjects){
+                for (let proj of receiveProjects) {
                     // 设置分享信息
                     proj.shareInfo = shareInfoMap[proj.ID] || [];
                     if (proj.projType === projType.project) {
@@ -787,9 +785,9 @@ module.exports = {
                     }
                     //设置项目类型为来自别人分享
                     proj.shareType = 'receive';
-                    for(let userData of orgUsersInfo){
-                        if(proj.userID == userData._id.toString()){
-                            let userInfo = {name: userData.real_name, mobile: userData.mobile, company: userData.company, email: userData.email};
+                    for (let userData of orgUsersInfo) {
+                        if (proj.userID == userData._id.toString()) {
+                            let userInfo = { name: userData.real_name, mobile: userData.mobile, company: userData.company, email: userData.email };
                             proj.userInfo = userInfo;
                         }
                     }
@@ -797,17 +795,17 @@ module.exports = {
                 consProjIDs = Array.from(new Set(consProjIDs));
                 let summaryInfo = await pm_facade.getSummaryInfo(consProjIDs);
                 let tendersFeeInfo = await pm_facade.getTendersFeeInfo(ungroupedTenders);
-                rst.summaryInfo = {grouped: summaryInfo, ungrouped: tendersFeeInfo};
+                rst.summaryInfo = { grouped: summaryInfo, ungrouped: tendersFeeInfo };
             }
             callback(req, res, 0, 'success', rst);
         }
-        catch (err){
+        catch (err) {
             console.log(err);
             callback(req, res, 1, err, null);
         }
     },
     getProjectsByQuery: async function (req, res) {
-        try{
+        try {
             let data = JSON.parse(req.body.data);
             let compilation = req.session.sessionCompilation._id;
             let query = data.query;
@@ -816,57 +814,58 @@ module.exports = {
             let projects = await projectModel.find(query, options);
             callback(req, res, 0, 'success', projects);
         }
-        catch (err){
+        catch (err) {
             callback(req, res, 1, err, null);
         }
     },
-    getSummaryInfo: async function(req, res){
-        try{
+    getSummaryInfo: async function (req, res) {
+        try {
             let data = JSON.parse(req.body.data);
             let summaryInfo = await pm_facade.getSummaryInfo(data.projectIDs);
             callback(req, res, 0, 'success', summaryInfo);
         }
-        catch (err){
+        catch (err) {
             callback(req, res, 1, err, null);
         }
     },
-    changeFile:async function(req,res){
-        try{
+    changeFile: async function (req, res) {
+        try {
             let data = JSON.parse(req.body.data);
             console.log(data);
-            await pm_facade.changeFile(data.projects,data.user_id,data.fileID,data.name,data.from,data.type);
+            await pm_facade.changeFile(data.projects, data.user_id, data.fileID, data.name, data.from, data.type);
             callback(req, res, 0, 'success', []);
         }
-        catch (err){
+        catch (err) {
             console.log(err);
             callback(req, res, 1, err, null);
         }
     },
-    exportProject:async function(req,res){
-        let result={
-            error:0
+    exportProject: async function (req, res) {
+        let result = {
+            error: 0
         };
         try {
-            let data = {dataString:req.body.data,userID:req.session.sessionUser.id};
-            result = await redirectToImportServer(data,"exportProject",req);
-        }catch (err){
+            let data = { dataString: req.body.data, userID: req.session.sessionUser.id };
+            result = await redirectToImportServer(data, "exportProject", req);
+        } catch (err) {
             console.log(err);
-            result.error=1;
+            result.error = 1;
             result.message = err.message;
         }
         res.json(result);
+
     },
-    importProject:async function(req,res){
+    importProject: async function (req, res) {
         let data = JSON.parse(req.body.data);
-        let result={
-            error:0
+        let result = {
+            error: 0
         };
         try {
             data.session = req.session;
             result = await redirectToImportServer(data,"importProject",req);
-        }catch (err){
+        } catch (err) {
             console.log(err);
-            result.error=1;
+            result.error = 1;
             result.message = err.message;
         }
         res.json(result);
@@ -886,31 +885,31 @@ module.exports = {
       }
       res.json(result);
     },
-    importProcessChecking:async function (req,res) {
-        let result={
-            error:0
+    importProcessChecking: async function (req, res) {
+        let result = {
+            error: 0
         };
-        try{
+        try {
             let data = JSON.parse(req.body.data);
             data.userID = req.session.sessionUser.id;
             data.compilationID = req.session.sessionCompilation._id;
             result.data = await pm_facade.importProcessChecking(data);
-        } catch (err){
+        } catch (err) {
             console.log(err);
-            result.error=1;
+            result.error = 1;
             result.message = err.message;
         }
         res.json(result);
     },
-    getUploadToken:function (req,res) {
-        let result={
-            error:0
+    getUploadToken: function (req, res) {
+        let result = {
+            error: 0
         };
         try {
-            result =pm_facade.uploadToken();
-        }catch (err){
+            result = pm_facade.uploadToken();
+        } catch (err) {
             console.log(err);
-            result.error=1;
+            result.error = 1;
             result.message = err.message;
         }
         res.json(result);
@@ -918,15 +917,15 @@ module.exports = {
 };
 
 
-async function redirectToImportServer(data,action,req) {
-    let importURL = config.getImportURL(process.env.NODE_ENV,req.headers.origin);
+async function redirectToImportServer(data, action, req) {
+    let importURL = config.getImportURL(process.env.NODE_ENV, req.headers.origin);
     let options = {
         method: 'POST',
         uri: `http://${importURL}/import/${action}`,
         body: data,
-        timeout:220000,
+        timeout: 220000,
         json: true
     };
-    console.log("post import data to:"+options.uri);
+    console.log("post import data to:" + options.uri);
     return await rp.post(options);
 }

+ 2 - 0
modules/pm/facade/pm_facade.js

@@ -103,6 +103,7 @@ const moment = require('moment-timezone');
 const { fixedFlag, SharePermissionChangeType } = require('../../../public/common_constants');
 const notDeleted = [{deleteInfo: null}, {'deleteInfo.deleted': false}];
 let cipher = require('../../../public/cipher');
+let index = require("../../system_setting/model/index");
 const compilationModel = mongoose.model('compilation');
 let qiniu = require("qiniu");
 let fs = require("fs");
@@ -465,6 +466,7 @@ async function copyExample(userID, compilation, projIDs,nameMap){
         data.createDateTime = newDate;
         data.userID = userID;
         data.compilation = compilation;
+        data.fileVer = await index.getVersion();
         data.shareInfo = [];
         if (data.projType !== projectType.tender) {
             let newData = _.cloneDeep(data);

+ 4 - 4
modules/pm/models/project_model.js

@@ -46,6 +46,8 @@ let gljFacade = require('../../glj/facade/glj_facade');
 let logger = require("../../../logs/log_helper").logger;
 let BillsModel = require("../../main/models/bills").model;
 let _ = require('lodash');
+let index = require("../../system_setting/model/index");
+
 
 let Projects = mongoose.model('projects');
 let mainColLibModel = mongoose.model('std_main_col_lib');
@@ -55,8 +57,6 @@ let optionModel = mongoose.model('options');
 function ProjectsDAO() {
 }
 
-let G_FILE_VER = '1.0.1';
-
 ProjectsDAO.prototype.getUserProjects = async function (userId, compilation, callback) {
     try {//
         let projects = await Projects.find({
@@ -143,7 +143,7 @@ ProjectsDAO.prototype.updateUserProjects = async function (userId, compilationId
                 data.updateData['userID'] = userId;
                 data.updateData['compilation'] = compilationId;
                 data.updateData['createDateTime'] = new Date();
-                data.updateData['fileVer'] = G_FILE_VER;
+                data.updateData['fileVer'] = await index.getVersion();
                 if(data.updateData.projType === projectType.project){
                     //设置建设项目基本信息,多个单位工程共用
                     data.updateData.property.basicInformation = basicInformation;
@@ -367,7 +367,7 @@ ProjectsDAO.prototype.copyUserProjects = function (userId, compilationId, datas,
                 data.updateData['userID'] = userId;
                 data.updateData['compilation'] = compilationId;
                 data.updateData['createDateTime'] = new Date();
-                data.updateData['fileVer'] = G_FILE_VER;
+                data.updateData['fileVer'] = index.getVersion();
                 let newProject = new Projects(data.updateData);
                 newProject['srcProjectId'] = data.srcProjectId;
                 newProject.save(function (err, result) {

+ 63 - 16
modules/ration_glj/facade/ration_glj_facade.js

@@ -101,11 +101,11 @@ async function getQuantityByProjectGLJ(condition) {
         'deleteInfo': null
     };
 
-    /* $and: [
-     {'projectID': condition.projectID},
-     {'ID': {$in: rationList}},
-     {'deleteInfo': null}
-     ]*/
+   /* $and: [
+        {'projectID': condition.projectID},
+        {'ID': {$in: rationList}},
+        {'deleteInfo': null}
+    ]*/
     let rations = await ration.find(rationQuery, ['ID', 'quantity']);
     let rationsTime = +new Date();
     console.log("取定额消耗量时间-----"+(rationsTime - getQuantity));
@@ -151,7 +151,7 @@ function get_lib_glj_info(ration_glj) {
                 ration_glj.repositoryId = glj.repositoryId;
                 ration_glj.adjCoe = glj.adjCoe;
                 getInfoFromProjectGLJ(ration_glj).then(function (info) {
-                    if (info&&info.length>0) {
+                    if (info &&info.length>0) {
                         let tem = {};
                         tem.newRecode = createNewRecord(info[0]);
                         tem.showData = info[0];
@@ -341,13 +341,13 @@ function delete_ration_glj(user_id, datas) {
         deleteByID(datas, callback);
         //callback(new Error("删除子数据失败!"),null)
         //这个方法已经不用,先注释,稳定后再删除
-        /* if (datas.deleteType == "RATION") {
-         deleteByRation(datas, callback);
-         } else if (datas.deleteType == "BILL") {
-         deleteByBill(user_id, datas, callback);
-         } else {
-         deleteByID(datas, callback);
-         }*/
+       /* if (datas.deleteType == "RATION") {
+            deleteByRation(datas, callback);
+        } else if (datas.deleteType == "BILL") {
+            deleteByBill(user_id, datas, callback);
+        } else {
+            deleteByID(datas, callback);
+        }*/
     }
 }
 
@@ -674,6 +674,8 @@ function getGLJSearchInfo(ration_glj) {
         purchaseStorageRate:ration_glj.purchaseStorageRate,
         offSiteTransportLossRate:ration_glj.offSiteTransportLossRate,
         handlingLossRate:ration_glj.handlingLossRate,
+        is_adjust_price:0,
+        is_main_material:1,
         from: ration_glj.from ? ration_glj.from : 'std'//std:标准工料机库, cpt:补充工料机库
     };
     let glj_type_object = glj_type_util.getStdGljTypeCacheObj();
@@ -726,8 +728,8 @@ async function addGLJ(rgList,compilation) {
         rationID: rgList[0].rationID
     });
     let result = {
-        projectGLJList:projectGLJList,
         newRecodes: newRecodes,
+        projectGLJList:projectGLJList,
         showData: rgList,
         adjustState: stateResult.adjustState
     };
@@ -738,7 +740,6 @@ async function insertAddTypeGLJ(rgList,compilation,needInsert=true) {
     let newRecodes = [],GLJMap=null;
     let projectGLJList = [];
     let [unitFileId,ext] = await  prepareExtData(rgList[0].projectID,compilation);
-
     for (let g of rgList) {
         let projectGljModel = new GLJListModel();
         let result = await projectGljModel.addList(getGLJSearchInfo(g),unitFileId,ext);
@@ -1178,11 +1179,57 @@ async function testError() {
     throw  new Error('test Error');
 }
 
-function getData(projectID, callback) {
+function getData(projectID, callback, isReport) {
     ration_glj.find({'projectID': projectID}, (err, datas) => {
         if (err) {
             callback(1, '', null);
         } else {
+            if (isReport) {  // 调价中间件机制
+                ration.find({'projectID': projectID}, ['ID', 'code', 'name', 'quantityCoe', 'quantity', 'rationQuantityCoe'],
+                    function cbData(err, rations) {
+                        if (!err) {
+                            for (let i = 0; i < datas.length; i++) {
+                                let glj = datas[i]._doc;
+                                let ration = findRation(rations, glj.rationID);
+                                let coe = 1;
+                                if (ration && ration.quantityCoe){
+                                    if ([gljType.LABOUR].includes(glj.type)){
+                                        if (ration.quantityCoe._doc.labour)
+                                            coe = ration.quantityCoe._doc.labour;
+                                    }
+                                    else if (
+                                        [gljType.GENERAL_MATERIAL,
+                                        gljType.CONCRETE,
+                                        gljType.MORTAR,
+                                        gljType.MIX_RATIO,
+                                        gljType.COMMERCIAL_CONCRETE,
+                                        gljType.COMMERCIAL_MORTAR,
+                                        gljType.OTHER_MATERIAL].includes(glj.type)){
+                                        if (ration.quantityCoe._doc.material)
+                                            coe = ration.quantityCoe._doc.material;
+                                    }
+                                    else if ([gljType.GENERAL_MACHINE,
+                                        gljType.MACHINE_COMPOSITION,
+                                        gljType.MACHINE_LABOUR].includes(glj.type)){
+                                        if (ration.quantityCoe._doc.machine)
+                                            coe = ration.quantityCoe._doc.machine;
+                                    }
+                                    else if ([gljType.MAIN_MATERIAL].includes(glj.type)){
+                                        if (ration.quantityCoe._doc.main)
+                                            coe = ration.quantityCoe._doc.main;
+                                    }
+                                    else if ([gljType.EQUIPMENT].includes(glj.type)){
+                                        if (ration.quantityCoe._doc.equipment)
+                                            coe = ration.quantityCoe._doc.equipment;
+                                    };
+
+                                };
+                                if ((!coe) || (coe == '0')) coe = 1;
+                                glj.quantity = glj.quantity * coe;
+                            }
+                        }
+                    });
+            };
             callback(0, consts.projectConst.RATION_GLJ, datas);
         }
     })

+ 8 - 4
public/gljUtil.js

@@ -31,16 +31,16 @@ function calcProjectGLJQuantity(projectGLJDatas,rationGLJDatas,rationDatas,bills
     gljNodeUtil.calcProjectGLJQuantity(projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal,_,scMathUtil);
 }
 
-function getGLJPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio=false) {
-    return gljNodeUtil.getGLJPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+function getGLJPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio=false,tenderCoe, isReport) {
+    return gljNodeUtil.getGLJPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,tenderCoe, isReport);
 }
 
 function setMaterialCalcRationFee(ration,ration_gljs,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,_,scMathUtil) {
     return gljNodeUtil.setMaterialCalcRationFee(ration,ration_gljs,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,_,scMathUtil);
 }
 
-function getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio=false) {
-    return gljNodeUtil.getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+function getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio=false,tenderCoe) {
+    return gljNodeUtil.getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,tenderCoe);
 }
 
 function getBasePrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio=false) {
@@ -84,4 +84,8 @@ function getCCSProjectGLJ(unitFileID,project_id) {
 
 function getBaseCCSMixRatio(unitFileID,consumption,connect_key) {
     return gljNodeUtil.getBaseCCSMixRatio(unitFileID,consumption,connect_key)
+}
+
+function getTenderPriceCoe(glj,tproperty){
+  return gljNodeUtil.getTenderPriceCoe(glj,tproperty);
 }

+ 92 - 42
public/web/gljUtil.js

@@ -4,7 +4,7 @@
 
 
 let gljUtil = {
-    calcProjectGLJQuantity:function (projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal,_,scMathUtil,isTender) {
+    calcProjectGLJQuantity:function (projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal,_,scMathUtil,isReport) {
         let project_gljs = projectGLJDatas.gljList, mixRatioMap = projectGLJDatas.mixRatioMap, com_electrovalence = projectGLJDatas.com_electrovalence;
         let rations = rationDatas;
         let rationMap = _.indexBy(rations,'ID');
@@ -15,7 +15,7 @@ let gljUtil = {
         let materialCalcMap={};
         //养护没有分部分项消耗量这一说的所以不用管
 
-        let qField = isTender==true?"tenderQuantity":"quantity";
+        let qField = "quantity";
         let mField = "materialQuantity"; //材料计算的工料机消耗量
 
         let elecIndex = "";//记住电的标识
@@ -26,8 +26,9 @@ let gljUtil = {
             pglj[qField] = 0;
             pglj[mField] = 0;
             let gljGroup = rationGljGroup[pglj.id]?rationGljGroup[pglj.id]:[];//定额工料机没有,有可能是定额类型的工料机
-            let result = this.getQuantityPerGLJ(gljGroup,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil,isTender);
+            let result = this.getQuantityPerGLJ(gljGroup,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil);
             pglj[qField] = result.quantity;
+            pglj.tenderQuantity = result.tenderQuantity;
             quantityMap[pg_index] = pglj;
             if(pglj.code == gljUtil.getElecCode() && pglj.name == '电' && pglj.unit == "kW·h") elecIndex = pg_index;
             if(pglj.unit_price.calcMaterial == 1) materialCalcMap[pg_index] = true;
@@ -41,7 +42,9 @@ let gljUtil = {
                 let p_glj = quantityMap[pkey];
                 if(m_glj&&p_glj&&!gljUtil.isConcreteType(p_glj.type) ){//混凝土、砂浆、配合比组成物的消耗量在定额下已经有体现了,不用再计算进去
                     let quantity = scMathUtil.roundForObj(parseFloat(p_glj[qField])*parseFloat(m.consumption),q_decimal);
+                    let tenderQuantity = scMathUtil.roundForObj(parseFloat(p_glj.tenderQuantity)*parseFloat(m.consumption),q_decimal);
                     m_glj[qField] =  scMathUtil.roundForObj(parseFloat(m_glj[qField])+quantity,q_decimal);
+                    m_glj.tenderQuantity =  scMathUtil.roundForObj(parseFloat(m_glj.tenderQuantity)+tenderQuantity,q_decimal);
                 }
             }
         }
@@ -53,17 +56,21 @@ let gljUtil = {
           offSiteTransportLossRate = offSiteTransportLossRate/100;
           pglj.transportLossQuantity =  scMathUtil.roundForObj(pglj.quantity*offSiteTransportLossRate,q_decimal);
           pglj.quantity = scMathUtil.roundForObj(pglj.quantity +  pglj.transportLossQuantity ,q_decimal);
+          pglj.tenderTransportLossQuantity =  scMathUtil.roundForObj(pglj.tenderQuantity*offSiteTransportLossRate,q_decimal);
+          pglj.tenderQuantity = scMathUtil.roundForObj(pglj.tenderQuantity +  pglj.tenderTransportLossQuantity ,q_decimal);
+	      if (isReport)
+	          pglj.quantity = pglj.tenderQuantity;
         }
         //材料计算中,工料机的消耗量
 
         //材料计算中,有可能A包含B,B包含C。。。。。等情况,为避免循环计算,只多计算一次,不做再深的嵌套处理
         // 1.先计算做为父工料机的材料计算消耗量
-        if(projectGLJDatas.freightList) this.setMaterialCalcQuantity(quantityMap,materialCalcMap,true,projectGLJDatas.freightList,q_decimal,_,scMathUtil,isTender); //运费计算中工料机的消耗量
-        if(projectGLJDatas.originalList) this.setMaterialCalcQuantity(quantityMap,materialCalcMap,true,projectGLJDatas.originalList,q_decimal,_,scMathUtil,isTender);//原价计算中工料机的消耗量
+        if(projectGLJDatas.freightList) this.setMaterialCalcQuantity(quantityMap,materialCalcMap,true,projectGLJDatas.freightList,q_decimal,_,scMathUtil); //运费计算中工料机的消耗量
+        if(projectGLJDatas.originalList) this.setMaterialCalcQuantity(quantityMap,materialCalcMap,true,projectGLJDatas.originalList,q_decimal,_,scMathUtil);//原价计算中工料机的消耗量
 
         // 2.再计算做为子工料机的材料计算消耗量
-        if(projectGLJDatas.freightList) this.setMaterialCalcQuantity(quantityMap,materialCalcMap,false,projectGLJDatas.freightList,q_decimal,_,scMathUtil,isTender); //运费计算中工料机的消耗量
-        if(projectGLJDatas.originalList) this.setMaterialCalcQuantity(quantityMap,materialCalcMap,false,projectGLJDatas.originalList,q_decimal,_,scMathUtil,isTender);//原价计算中工料机的消耗量
+        if(projectGLJDatas.freightList) this.setMaterialCalcQuantity(quantityMap,materialCalcMap,false,projectGLJDatas.freightList,q_decimal,_,scMathUtil); //运费计算中工料机的消耗量
+        if(projectGLJDatas.originalList) this.setMaterialCalcQuantity(quantityMap,materialCalcMap,false,projectGLJDatas.originalList,q_decimal,_,scMathUtil);//原价计算中工料机的消耗量
 
 
         //因为材料计算里自采材料产生的消耗量和进行材料计算的父工料机的消耗量有关,所以材料计算中的组成物的消耗量要在上一步的组成物计算完后,再计算自采材料里组成物的消耗量,所认两个组成物计算不能合并,而且乘的值也不同
@@ -110,8 +117,8 @@ let gljUtil = {
         }
         
     },
-    setMaterialCalcQuantity:function (quantityMap,materialCalcMap,isParent,calcList,q_decimal,_,scMathUtil,isTender) {
-        let qField = isTender==true?"tenderQuantity":"quantity";
+    setMaterialCalcQuantity:function (quantityMap,materialCalcMap,isParent,calcList,q_decimal,_,scMathUtil) {
+        let qField = "quantity";
         let p_decimal = 6; //自采定额这里计算结果都看成是中间过程,取6位小数
         for(let t of calcList){
             if(quantityMap[t.connect_key] && quantityMap[t.connect_key][qField] > 0){
@@ -159,34 +166,42 @@ let gljUtil = {
        // 场外运输损耗率%+(装卸总次数-1)*每增加一次装卸损耗率%
         return (offSiteTransportLossRate + (totalLoadingTimes - 1) * handlingLossRate);
     },
-    getQuantityPerGLJ : function (ration_glj_list,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil,isTender) {
+    getQuantityPerGLJ : function (ration_glj_list,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil) {
         let result={};
         let quantity_sum=0;//工料机汇总消耗量
+        let tender_qantity_sum = 0;
         for(let rg of ration_glj_list){
             let tem_ration = rationMap[rg.rationID];
             let r_quantity = tem_ration?scMathUtil.roundForObj(tem_ration.quantity,q_decimal):0;
             let glj_quantity = scMathUtil.roundForObj(rg.quantity, q_decimal);
+            let tender_r_quantity = r_quantity;
+            let tender_glj_quantity = glj_quantity;
             if(!r_quantity){
                 continue;
             }
-            if(isTender == true){
-                glj_quantity = this.getRationGLJTenderQuantity(rg,tem_ration,q_decimal,scMathUtil);
-                r_quantity = this.getRationTenderQuantity(tem_ration,q_decimal,scMathUtil);
+            if(!pglj.is_adjust_price){
+                tender_glj_quantity = this.getRationGLJTenderQuantity(rg,tem_ration,q_decimal,scMathUtil);
+                tender_r_quantity = this.getRationTenderQuantity(tem_ration,q_decimal,scMathUtil);
             }
             let total = scMathUtil.roundForObj(glj_quantity*r_quantity, q_decimal);
+            let tender_total = scMathUtil.roundForObj(tender_glj_quantity*tender_r_quantity, q_decimal);
             quantity_sum = scMathUtil.roundForObj(quantity_sum+total,q_decimal);
+            tender_qantity_sum = scMathUtil.roundForObj(tender_qantity_sum+tender_total,q_decimal);
         }
         for(let ra of rations){//计算定额类型工料机的消耗量
             if(ra.type == this.rationType.gljRation&&ra.projectGLJID===pglj.id){
                 let r_quantity = scMathUtil.roundForObj(ra.quantity,q_decimal);
                 r_quantity = r_quantity?r_quantity:0;
-                if(isTender == true){
-                    r_quantity = this.getRationTenderQuantity(ra,q_decimal,scMathUtil);
+                let tender_r_quantity = r_quantity;
+                if(!pglj.is_adjust_price){
+                  tender_r_quantity = this.getRationTenderQuantity(ra,q_decimal,scMathUtil);
                 }
                 quantity_sum = scMathUtil.roundForObj(quantity_sum+r_quantity,q_decimal);
+                tender_qantity_sum = scMathUtil.roundForObj(tender_qantity_sum+tender_r_quantity,q_decimal);
             }
         }
         result.quantity = quantity_sum;
+        result.tenderQuantity = tender_qantity_sum;
         return result;
     },
     getRationGLJTenderQuantity:function (ration_glj,ration,q_decimal,scMathUtil) {
@@ -200,18 +215,28 @@ let gljUtil = {
         let typeString = ration_glj.type +"";
         let coeField = "";
         for(let key in coeMap){
-            if(typeString.indexOf(key)!= -1){
-                coeField = coeMap[key];
+            if(typeString.indexOf(key) == 0){
+              coeField = coeMap[key];
+              break;
             }
         }
-        let coe = ration.quantityCoe&&this.isNotEmpty(ration.quantityCoe[coeField])?ration.quantityCoe[coeField]:1;
-        coe = parseFloat(coe);
+        let coe = 1;
+        if (!calcTools.isTenderProjectGLJ(ration_glj)){
+            coe = 1;
+        }
+        else{
+            coe = ration.quantityCoe&&this.isNotEmpty(ration.quantityCoe[coeField])?ration.quantityCoe[coeField]:1;
+            coe = parseFloat(coe);
+        }
+
+        if (coe == 0) coe = 1;
         let glj_quantity = scMathUtil.roundForObj(ration_glj.quantity, q_decimal);
         return scMathUtil.roundForObj(glj_quantity * coe,q_decimal);
     },
     getRationTenderQuantity:function (ration,q_decimal,scMathUtil) {
         let rationQuantityCoe = this.isNotEmpty(ration.rationQuantityCoe)?ration.rationQuantityCoe:1;
         rationQuantityCoe = parseFloat(rationQuantityCoe);
+        if (rationQuantityCoe == 0) rationQuantityCoe = 1;
         let r_quantity = ration?scMathUtil.roundForObj(ration.quantity,q_decimal):0;
         return scMathUtil.roundForObj(r_quantity * rationQuantityCoe,q_decimal);
     },
@@ -259,9 +284,14 @@ let gljUtil = {
     getFlag:function (b) {
         return _.find(b.flags,{"fieldName":"fixed"});
     },
-    getGLJPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,ext) {
+    getGLJPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,ext,tenderCoe, isReport) {
         let result = {};
-        result.marketPrice = this.getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,null,ext);
+        if(isReport){
+            result.marketPrice = this.getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,tenderCoe,ext);
+        }else {
+            result.marketPrice = this.getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+            result.tenderPrice = this.getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,tenderCoe);
+        }
         if(this.calcPriceDiff(glj,calcOptions)==true){//计取价差
             result.basePrice = this.getBasePrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
             result.adjustPrice = this.getAdjustPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
@@ -278,6 +308,8 @@ let gljUtil = {
         let quantity_decimal = decimalObj.glj.quantity;
         let process_decimal = this.isDef(decimalObj.marketPriceProcess)?decimalObj.marketPriceProcess: decimalObj.process;//20200722  旧的项目还是默认6位,新的用两位
         let priceCoe = this.isDef(tenderCoe)?tenderCoe:1;
+        if (priceCoe == '0' || priceCoe == 0) priceCoe = 1;   // 这里加个保护
+        if (['GLF', 'LR', 'FXF'].includes(glj.code)) priceCoe = 1; // 类型是“企业管理费”、“利润”、“一般风险费”的,不应调整单价。
         if (!this.isConcreteType(glj.unit_price.type)&& this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于机械台班等有组成物的材料,价格需根据组成物计算得出(排除混凝土、配合比、砂浆这几个类型直接为0)。
             let p =0;
             for(let ratio of glj.ratio_data){
@@ -286,12 +318,15 @@ let gljUtil = {
                   return rIndex == gljUtil.getIndex(item);
                 });
                 if(tem){
-                    let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
+		            let tem_marketPrice = this.getMarketPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
                     if(ext && ext[tem.id] && this.isDef(ext[tem.id].marketPrice)){//在修改组成物的价格或消耗量时,影响了父工料机的价格,这时以父工料机的价格应当用组成物的新值来记算
-                        priceData.marketPrice = ext[tem.id].marketPrice;
-                    }
-                    let temP = scMathUtil.roundForObj(priceData.marketPrice* priceCoe * scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
-                    p = scMathUtil.roundForObj(temP + p,process_decimal);
+                        tem_marketPrice = ext[tem.id].marketPrice;
+                    };
+
+		            let temP = scMathUtil.roundForObj(
+                        scMathUtil.roundForObj(tem_marketPrice * priceCoe, price_decimal) *
+                        scMathUtil.roundForObj(ratio.consumption,quantity_decimal), process_decimal);
+                    p = scMathUtil.roundForObj(temP + p, process_decimal);
                 }
             }
             return scMathUtil.roundForObj(p,price_hasM_decimal);
@@ -309,22 +344,22 @@ let gljUtil = {
 
         if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
             //2018-09-07 需求修改,定额价不按组成物的量和价实时计算出来,直接取单价文件中的定额价
-            /*     let p =0;
-             for(let ratio of glj.ratio_data){
-             let tem =  _.find( projectGLJDatas.gljList,{
-             'code': ratio.code,
-             'name': ratio.name,
-             'specs':ratio.specs,
-             'type': ratio.type,
-             'unit': ratio.unit
-             });
-             if(tem){
-             let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
-             let temP = scMathUtil.roundForObj(priceData.basePrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
-             p = scMathUtil.roundForObj(temP + p,process_decimal);
-             }
-             }
-             return scMathUtil.roundForObj(p,price_hasM_decimal);*/
+       /*     let p =0;
+            for(let ratio of glj.ratio_data){
+                let tem =  _.find( projectGLJDatas.gljList,{
+                    'code': ratio.code,
+                    'name': ratio.name,
+                    'specs':ratio.specs,
+                    'type': ratio.type,
+                    'unit': ratio.unit
+                });
+                if(tem){
+                    let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
+                    let temP = scMathUtil.roundForObj(priceData.basePrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
+                    p = scMathUtil.roundForObj(temP + p,process_decimal);
+                }
+            }
+            return scMathUtil.roundForObj(p,price_hasM_decimal);*/
 
             return scMathUtil.roundForObj(glj.unit_price.base_price,price_hasM_decimal);
         }else {
@@ -469,6 +504,8 @@ let gljUtil = {
             quantity = (quantity == 0 || quantity == undefined || quantity == null || quantity == "") ? 0 : quantity;
             quantity = scMathUtil.roundForObj(quantity, rd);//计算前进行4舍5入
             glj.quantity = scMathUtil.roundForObj(glj.quantity, gd);
+            glj.tenderQuantity = this.getRationGLJTenderQuantity(glj, ration, gd, scMathUtil);
+
             return scMathUtil.roundToString(quantity * glj.quantity, gd);
         }
     },
@@ -518,6 +555,19 @@ let gljUtil = {
     getElecCode:function () {
         return '3005002';
     },
+    getTenderPriceCoe : function(glj,tproperty){
+        let tenderCoe = 1;
+        let property = tproperty ? tproperty : projectObj.project.property;
+        if (!glj.is_adjust_price&&property.tenderSetting && isDef(property.tenderSetting.gljPriceTenderCoe) ){
+            tenderCoe = parseFloat(property.tenderSetting.gljPriceTenderCoe);
+            if (tenderCoe == 0) tenderCoe = 1;
+        }
+        return tenderCoe;
+
+        function isDef (v) {
+            return v !== undefined && v !== null;
+        }
+    },
     setProperty:function(Obj,updateData) {
         for(let ukey in updateData){
             if(_.isObject(updateData[ukey]) && _.isObject(Obj[ukey])&&!_.isArray(updateData[ukey])){

+ 22 - 7
public/web/sheet/sheet_common.js

@@ -17,13 +17,18 @@ var sheetCommonObj = {
         spreadBook.options.showDragFillSmartTag = false;
         return spreadBook;
     },
-    initSheet: function (sheet, setting, rowCount) {
+
+    initSheet: function(sheet, setting, rowCount) {
+
         var me = this;
         var spreadNS = GC.Spread.Sheets;
+        if(setting.headRows == 2){
+            return me.buildSpanHeader(sheet, setting, rowCount);//初始化合并表格列头
+        }
         sheet.suspendPaint();
         sheet.suspendEvent();
-        if (setting.frozenCols) sheet.frozenColumnCount(setting.frozenCols);//冻结列
-        sheet.setRowCount(1, spreadNS.SheetArea.colHeader);
+        if(setting.frozenCols)  sheet.frozenColumnCount(setting.frozenCols);//冻结列s
+        sheet.setRowCount(setting.headRows ? setting.headRows : 1, spreadNS.SheetArea.colHeader);
         sheet.setColumnCount(setting.header.length, spreadNS.SheetArea.viewport);
 
         if (setting && setting.view && setting.view.colHeaderHeight) {
@@ -45,10 +50,6 @@ var sheetCommonObj = {
         sheet.showRowOutline(false);
         sheet.options.allowCellOverflow = false;
         me.buildHeader(sheet, setting);
-        if (rowCount > 0)
-            sheet.setRowCount(rowCount);
-        else
-            sheet.setRowCount(1);
         sheet.resumeEvent();
         sheet.resumePaint();
     },
@@ -62,6 +63,20 @@ var sheetCommonObj = {
         return spreadBook;
     },
 
+    buildSpanHeader:function (sheet, setting, rowCount) {
+        let temSetting = {
+            "emptyRows":0,
+            "headRows":2,
+            "headRowHeight":[21],
+            "defaultRowHeight": 21,
+            "treeCol": 0,
+            "cols":[]
+        };
+        let spanSetting =   sheetCommonObj.transferToTreeSetting(setting,temSetting);
+        TREE_SHEET_HELPER.loadSheetHeader(spanSetting,sheet,rowCount);
+
+    },
+
     buildHeader: function (sheet, setting) {
         var me = this, ch = GC.Spread.Sheets.SheetArea.colHeader;
         for (var i = 0; i < setting.header.length; i++) {

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

@@ -67,7 +67,7 @@
                 <li class="nav-item"><a data-toggle="tab" href="#fee_rates" id="tab_fee_rate" role="tab" >费率</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#divide" id="tab_divide" role="tab" style="display: none;">分摊</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#calc_program_manage" id="tab_calc_program_manage" role="tab" style="display:none">总计算程序</a></li>
-               <!-- <li class="nav-item"><a data-toggle="tab" href="#tender_price" id="tab_tender_price" role="tab">调价</a></li>-->
+                <li class="nav-item"><a data-toggle="tab" href="#tender_price" id="tab_tender_price" role="tab">调价</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#reports" role="tab" id="tab_report" onclick="rptTplObj.iniPage();">报表</a></li>
             </ul>
         </div>

+ 15 - 10
web/building_saas/main/html/tender_price.html

@@ -3,23 +3,28 @@
     <div class="btn-toolbar py-1">
         <div class="input-group input-group-sm mr-2">
             <select class="form-control form-control-sm" style="width: auto; font-size: .875rem" id="calcPriceOption">
-                <option value="coeBase">根据调整系数计算报价</option>
-                <option value="priceBase" >根据报价计算调整系数</option>
+                <option value="coeBase">按调价系数计算</option>
+                <option value="priceBase_RCJ" >按目标价调整人材机消耗</option>
+                <option value="priceBase_ZM" >按目标价调整子目工程量</option>
             </select>
         </div>
-        <div class="input-group input-group-sm mr-2" style="width:240px">
+
+        <div class="input-group input-group-sm mr-2" style="width:230px">
             <div class="input-group-prepend">
-                <span class="input-group-text" id="inputGroup-sizing-sm">工料机单价调整系数</span>
+                <span class="input-group-text" id="inputGroup-sizing-sm">人材机单价调整系数</span>
             </div>
             <input id = 'gljPriceTenderCoe' type="number" step="0.1" class="form-control" placeholder="请输入系数" value="1">
         </div>
-        <div class="btn-group mr-2">
-            <button type="button" class="btn btn-outline-primary btn-sm" id = "tenderGLJQuantity">调整工料机消耗</button>
-            <button type="button" class="btn btn-outline-primary btn-sm" id = "tenderRationQuantity">调整子目工程量</button>
-           <!-- <button type="button" class="btn btn-outline-primary btn-sm">反调单价</button>-->
-            <button type="button" class="btn btn-outline-primary btn-sm" id = "tenderPrice">调价计算</button>
-        </div>
+
+        <button type="button" class="btn btn-outline-primary btn-sm" id = "calcTender">调价计算</button>
+        <span>&nbsp</span>
         <button type="button" class="btn btn-outline-danger btn-sm" id = "cleanTender">清空调价</button>
+        <div class="form-check" style="margin-left:40px; margin-top:4px;">
+            <label class="form-check-label">
+                <input class="form-check-input" name="cbShowTenderFields" id="cbShowTenderFields" value="true" type="checkbox">
+                <span data-toggle="tooltip" data-original-title="造价书界面定额人材机的调价、人材机汇总界面的调价">显示调价后数据</span>
+            </label>
+        </div>
     </div>
 </div>
 <div class="container-fluid">

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

@@ -24,6 +24,8 @@ $(function () {
         billsLibObj.refreshBillsSpread();
         billsLibObj.refreshBillsRelaSpread();
         rationLibObj.refreshSpread();
+        if($('#linkJSCX').hasClass('active'))
+            calcProgramObj.refreshCalcProgram(projectObj.project.mainTree.selected, 2);
         //autoFlashHeight 里已经包含了 refreshSubSpread();
     });
 

+ 15 - 1
web/building_saas/main/js/models/calc_base.js

@@ -1333,6 +1333,18 @@ let cbCalctor = {
                     node.data.feesIndex.common.totalFee : 0;
         }
         return 0;
+    },
+    tenderRef: function (fExp) {
+        let ID = cbParser.getUID([fExp]);
+        if(ID.length === 1){
+            let node = cbTools.getNodeByID(ID[0]);
+            return cbTools.isDef(node) &&
+                    cbTools.isDef(node.data.feesIndex) &&
+                    cbTools.isDef(node.data.feesIndex.common) &&
+                    cbTools.isDef(node.data.feesIndex.common.tenderTotalFee) ?
+                    node.data.feesIndex.common.tenderTotalFee : 0;
+        }
+        return 0;
     }
 };
 
@@ -1402,7 +1414,9 @@ let calcBase = {
                 throw '基数计算结果不为数值';
             }
             //调价
-            let tenderCalcExp = calcExp.replace(new RegExp('base', 'g'), 'tenderBase');
+            let tenderCalcExp = calcExp
+                .replace(new RegExp('base', 'g'), 'tenderBase')
+                .replace(new RegExp('ref', 'g'), 'tenderRef')
             let tenderCalcBaseValue = eval(tenderCalcExp);
             if(!cbTools.isNum(tenderCalcBaseValue)){
                 throw '调价基数计算结果不为数值';

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 733 - 419
web/building_saas/main/js/models/calc_program.js


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

@@ -57,9 +57,12 @@ var PROJECT = {
                 }
             }
 
+            me._project.property = me._project.projectInfo.property;
             me._project.loadMainTree();
             //me.test(result[0].data[0]);
-            callback(0);
+            if (callback) {
+                callback(0);
+            }
         };
         tools.eachItem=function(item){
             if (me.modules[item.moduleName]){

+ 5 - 4
web/building_saas/main/js/models/project_glj.js

@@ -1687,13 +1687,14 @@ ProjectGLJ.prototype.getTenderMarketPrice = function (glj,isRadio) {
     let calcOptions=projectObj.project.projectInfo.property.calcOptions;
     let decimalObj = projectObj.project.projectInfo.property.decimal;
     let labourCoeDatas =  projectObj.project.labourCoe.datas;
-    let tenderCoe = 1;
-    if (projectObj.project.property.tenderSetting && gljUtil.isDef(projectObj.project.property.tenderSetting.gljPriceTenderCoe) ){
-        tenderCoe = parseFloat(projectObj.project.property.tenderSetting.gljPriceTenderCoe);
-    }
+    let tenderCoe = this.getTenderPriceCoe(glj);
     return gljUtil.getMarketPrice(glj,proGLJ.datas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,tenderCoe);
 };
 
+ProjectGLJ.prototype.getTenderPriceCoe = function(glj,tproperty){
+    return gljUtil.getTenderPriceCoe(glj,tproperty);
+};
+
 ProjectGLJ.prototype.isEstimateType = function(type){
     let typeString = type + "";
     if (typeString.startsWith("2")||typeString=='4'||typeString=='5') {//只有材料、主材、设备类型才显示是否暂估

+ 11 - 5
web/building_saas/main/js/views/calc_program_view.js

@@ -16,13 +16,15 @@ let calcProgramObj = {
             {headerName: "费率", headerWidth: CP_Col_Width.feeRate, dataCode: "feeRate", dataType: "Number"},
             // {headerName: "单价", headerWidth: CP_Col_Width.unitFee, dataCode: "unitFee", dataType: "Number"},
             {headerName: "金额", headerWidth: CP_Col_Width.totalFee, dataCode: "totalFee", dataType: "Number"},
+            //{headerName: "调后单价", headerWidth: CP_Col_Width.unitFee, dataCode: "tenderUnitFee", dataType: "Number"},
+            {headerName: "调后金额", headerWidth: CP_Col_Width.totalFee, dataCode: "tenderTotalFee", dataType: "Number"},
             {headerName: "费用类别", headerWidth:CP_Col_Width.displayFieldName, dataCode:"displayFieldName", dataType: "String", hAlign: "center"},
             {headerName: "基数说明", headerWidth: CP_Col_Width.statement, dataCode: "statement", dataType: "String"},
             {headerName: "备注", headerWidth: CP_Col_Width.memo, dataCode: "memo", dataType: "String"}
         ],
         view: {
             comboBox: [],
-            lockColumns: [0,1,2,3,4,5,6,7,8,9],
+            lockColumns: [0,1,2,3,4,5,6,7,8],
             colHeaderHeight: CP_Col_Width.colHeader,
             rowHeaderWidth: CP_Col_Width.rowHeader
         }
@@ -33,15 +35,15 @@ let calcProgramObj = {
         me.sheet = sheet;
         for (let col of me.setting.header){
             if (col.headerName == '费率') col.tofix = decimalObj.feeRate;
-            if (col.headerName == '单价') col.tofix = decimalObj.ration.unitPrice;
-            if (col.headerName == '合价') col.tofix = decimalObj.ration.totalPrice;
+            if (col.headerName == '单价' || col.headerName == '调后单价') col.tofix = decimalObj.ration.unitPrice;
+            if (col.headerName == '合价' || col.headerName == '调后合价') col.tofix = decimalObj.ration.totalPrice;
         };
         sheetCommonObj.initSheet(me.sheet, me.setting, 1);
     },
 
     // 刷新显示当前选中树结点的计算程序。
     // treeNode:末指定时默认是造价书当前选中树结点
-    // refreshKind: 1 仅刷新 2 计算并刷新但无需保存 3 计算保存并刷新
+    // refreshKind: 1 仅刷新   2 计算+刷新     3 计算+保存+刷新      4 仅计算
     refreshCalcProgram: function (treeNode, refreshKind = 1) {
         var me = this;
         me.treeNode = treeNode;
@@ -50,7 +52,7 @@ let calcProgramObj = {
             case 1:
                 // doNothing
                 break;
-            case 2:
+            case 2, 4:
                 projectObj.project.calcProgram.innerCalc(treeNode, []);
                 projectObj.project.calcProgram.rationMap = null;
                 delete treeNode.changed;
@@ -60,7 +62,11 @@ let calcProgramObj = {
                 break;
         }
 
+        if (!me.sheet) return;
         me.datas = treeNode.data.calcTemplate ? treeNode.data.calcTemplate.calcItems : [];
+        if (refreshKind === 4) {
+            return;
+        } 
         sheetCommonObj.initSheet(me.sheet, me.setting, me.datas.length);
         sheetCommonObj.showData(me.sheet, me.setting, me.datas);
         customRowHeader(me.sheet, me.datas.length);

+ 64 - 19
web/building_saas/main/js/views/glj_col.js

@@ -14,11 +14,13 @@ let gljCol = {
             {headerName: "消耗量", headerWidth: 65, dataCode: "quantity", dataType: "Number", hAlign: "right", decimalField: "glj.quantity"},
             {headerName: "定额价", headerWidth: 65, dataCode: "basePrice", dataType: "Number", hAlign: "right"},//, decimalField: "glj.unitPrice"
             {headerName: "定额消耗", headerWidth: 65, dataCode: "rationItemQuantity", dataType: "Number", hAlign: "right", decimalField: "glj.quantity"},   // dataType: "Number", formatter: "0.00"
-            {headerName: "总消耗量", headerWidth: 80, dataCode: "totalQuantity", dataType: "Number", hAlign: "right", decimalField: "glj.quantity"}
-            //{headerName: "暂估", headerWidth: 45, dataCode: "isEstimate", dataType: "String", hAlign: "center", vAlign: "center", cellType: "checkBox"}
+            {headerName: "总消耗量", headerWidth: 80, dataCode: "totalQuantity", dataType: "Number", hAlign: "right", decimalField: "glj.quantity"},
+            // {headerName: "暂估", headerWidth: 45, dataCode: "isEstimate", dataType: "String", hAlign: "center", vAlign: "center", cellType: "checkBox"},
+            {headerName: "调后市场价", headerWidth: 80, dataCode: "tenderPrice", dataType: "Number", hAlign: "right", visible: false},
+            {headerName: "调后消耗量", headerWidth: 80, dataCode: "tenderQuantity", dataType: "Number", hAlign: "right", decimalField: "glj.quantity", visible: false}
         ],
         view: {
-            lockColumns: [ "adjustPrice", "rationItemQuantity", "quantity", "totalQuantity", "isEstimate"],
+            lockColumns: [ "adjustPrice", "rationItemQuantity", "quantity", "totalQuantity", "isEstimate", "tenderPrice", "tenderQuantity"],
             rowHeaderWidth:25
         },
         getStyle:function (data) {
@@ -33,21 +35,25 @@ let gljCol = {
     },
     project_glj_setting:{
         header: [
-            {headerName: "编号", headerWidth: 80, dataCode: "code", dataType: "String"},
-            {headerName: "名称", headerWidth: 160, dataCode: "name", dataType: "String",cellType:'tipsCell'},
-            {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String"},
-            {headerName: "总消耗量", headerWidth: 90, dataCode: "quantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity'},
-            {headerName: "定额价", headerWidth: 70, dataCode: "basePrice", hAlign: "right", dataType: "Number",validator:"number"},//decimalField:'glj.unitPrice',
-            {headerName: "预算价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number"},//,decimalField:"glj.unitPrice"
-            {headerName: "规格", headerWidth: 120, dataCode: "specs", hAlign: "left", dataType: "String",cellType:'tipsCell'},
-            {headerName: "主要\n材料", headerWidth: 45, dataCode: "is_main_material", hAlign: "center", dataType: "String",cellType:'checkBox'},
-            {headerName: "新工料机", headerWidth: 50, dataCode: "is_add", hAlign: "center", dataType: "String",cellType:'checkBox'},
-            {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", dataType: "String",cellType: "checkBox",},
-            {headerName: "类型", headerWidth: 45, dataCode: "short_name", hAlign: "center", dataType: "String"},
-            {headerName: "备注", headerWidth: 100, dataCode: "remark", hAlign: "left", dataType: "String"}
+            {headerName: "编号", headerWidth: 80, dataCode: "code", dataType: "String",spanRows: [2]},
+            {headerName: "名称", headerWidth: 160, dataCode: "name", dataType: "String",cellType:'tipsCell',spanRows: [2]},
+            {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String",spanRows: [2]},
+            {headerName: "总消耗量", headerWidth: 90, dataCode: "quantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity',spanRows: [2]},
+            {headerName: "定额价", headerWidth: 70, dataCode: "basePrice", hAlign: "right", dataType: "Number",validator:"number", spanRows: [2]},
+            {headerName: "预算价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},
+            {headerName: "规格", headerWidth: 120, dataCode: "specs", hAlign: "left", dataType: "String",cellType:'tipsCell',spanRows: [2]},
+            {headerName: "主要\n材料", headerWidth: 45, dataCode: "is_main_material", hAlign: "center", dataType: "String",cellType:'checkBox',spanRows: [2]},
+            {headerName: "新工料机", headerWidth: 50, dataCode: "is_add", hAlign: "center", dataType: "String",cellType:'checkBox',spanRows: [2]},
+            {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", dataType: "String",cellType: "checkBox",spanRows: [2]},
+            {headerName: "类型", headerWidth: 45, dataCode: "short_name", hAlign: "center", dataType: "String",spanRows: [2]},
+            {headerName: "备注", headerWidth: 100, dataCode: "remark", hAlign: "left", dataType: "String",spanRows: [2]},
+            // {headerName: ["调价后","市场价"], headerWidth: 75, dataCode: "tenderPrice", hAlign: "right", dataType: "Number",validator:"number",spanCols: [2,1], visible: false},
+            // {headerName: ["","总消耗量"], headerWidth: 90, dataCode: "tenderQuantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity',spanCols: [0,1], visible: false}
+            {headerName: ["调价后\n市场价"], headerWidth: 75, dataCode: "tenderPrice", hAlign: "right", dataType: "Number",validator:"number",spanCols: [2,1], visible: false},
+            {headerName: ["调价后\n总消耗量"], headerWidth: 90, dataCode: "tenderQuantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity',spanCols: [0,1], visible: false}
         ],
         view: {
-            lockColumns: ["code","name","specs","unit","short_name","quantity","is_add"]
+            lockColumns: ["code","name","specs","unit","short_name","quantity","is_add","tenderPrice","tenderQuantity"]
         },
         getStyle:function (data,row,activeRow) {
             if(row == activeRow){//选中黄色显示
@@ -226,7 +232,7 @@ let gljCol = {
             setting.view.lockColumns = newArray;
         }
     },
-    initGljCol:function (showAdjustPrice) {
+    initGljCol:function (showAdjustPrice, showTenderFields) {
         let me = gljCol;
         if(showAdjustPrice !== true){
             me.removeCol('adjustPrice',me.ration_glj_setting);
@@ -236,12 +242,52 @@ let gljCol = {
         if(projectObj.project.projectInfo.property && projectObj.project.projectInfo.property.valuationType == "bill"){
             me.removeCol('is_adjust_price',me.project_glj_setting);
         }
-        gljOprObj.setting = me.ration_glj_setting;
+        
+	me.showTenderFields(showTenderFields, false);
+	gljOprObj.setting = me.ration_glj_setting;
         projectGljObject.projectGljSetting = me.project_glj_setting;
         projectGljObject.mixRatioSetting = me.mixRatio_Setting;
         me.setScopeFormater();
         gljOprObj.scopeSetting = me.scopeSetting;
     },
+    showTenderFields: function (showFields = false, needRefresh = false){
+        let me = gljCol;
+
+        let PGLJHeader = me.project_glj_setting.header;
+        for (let e of PGLJHeader){
+            if (e.dataCode == 'tenderPrice' || e.dataCode == 'tenderQuantity'){
+                e.visible = showFields;
+            }
+        };
+
+        let RGLJHeader = me.ration_glj_setting.header;
+        for (let e of RGLJHeader){
+            if (e.dataCode == 'tenderPrice' || e.dataCode == 'tenderQuantity'){
+                e.visible = showFields;
+            }
+        };
+
+        let CalcProgramHeader = calcProgramObj.setting.header;
+        for (let e of CalcProgramHeader){
+            if (e.dataCode == 'tenderUnitFee' || e.dataCode == 'tenderTotalFee'){
+                e.visible = showFields;
+            }
+        };
+
+        if (needRefresh){
+            if(projectGljObject.projectGljSpread) {
+                projectGljObject.projectGljSheet = projectGljObject.projectGljSpread .getSheet(0);
+                projectGljObject.initSheet(projectGljObject.projectGljSheet, projectGljObject.projectGljSetting);
+            }
+            if (subSpread) {
+                gljOprObj.refreshView();
+                calcProgramObj.refreshCalcProgram(projectObj.project.mainTree.selected);
+
+                //gljOprObj.initSheet(subSpread.getSheet(0), false);
+                //gljOprObj.initSheet(subSpread.getSheet(2), false);
+            }
+        };
+    },
     setScopeFormater:function () {
         // 综合单价、综合合价,小数部分应补0对齐。  CSL
         for(let col of this.scopeSetting.cols){
@@ -249,7 +295,6 @@ let gljCol = {
             if (col.data.field== "unitPrice")  col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.unitPrice, true);
         }
     }
-
 };
 /*
 $(function () {

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

@@ -107,11 +107,11 @@ var gljOprObj = {
     scopeSheet:null,
     scopeDatas:[],
     scopeSelectedIDMap:{},
-    initSheet: function (sheet) {
+    initSheet: function (sheet,name="ration_glj") {
         var me = this;
         me.sheet = sheet;
         sheetCommonObj.initSheet(me.sheet, me.setting, 30);
-        sheet.name('ration_glj');
+        sheet.name(name);
         me.bindSheetEvent(sheet);
         sheet.bind(GC.Spread.Sheets.Events.CellDoubleClick, me.onCellDoubleClick);
         sheet.bind(GC.Spread.Sheets.Events.ClipboardChanged, me.onClipboardChanged);
@@ -751,11 +751,13 @@ var gljOprObj = {
         let labourCoeDatas =  projectObj.project.labourCoe.datas;
         glj = glj?glj:_.find(proGLJ.datas.gljList, {'id': data.projectGLJID});
         if(glj){
-            let result = gljUtil.getGLJPrice(glj,proGLJ.datas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,ext);
+            let tenderCoe = projectObj.project.projectGLJ.getTenderPriceCoe(glj);
+            let result = gljUtil.getGLJPrice(glj,proGLJ.datas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,ext,tenderCoe);
             data.marketPrice = result.marketPrice;
             data.basePrice =  result.basePrice;
             data.adjustPrice = result.adjustPrice;
             data.marketUnitFee = data.marketPrice;//更新树节点市场单价列的值
+            data.tenderPrice = result.tenderPrice;
         }
         return data;
 

+ 1 - 0
web/building_saas/main/js/views/options_view.js

@@ -9,6 +9,7 @@ let optionsOprObj = {
     getOptions: function () {
         let me = this;
         me.options = projectOptins;
+        if (!me.options) return;
         let gOpts = me.options[me.optionsTypes.GENERALOPTS];
         if(gljUtil.isDef(gOpts)){
             for(let attr in gOpts){

+ 10 - 3
web/building_saas/main/js/views/project_glj_view.js

@@ -868,6 +868,7 @@ projectGljObject={
             type:glj.type,
             short_name:projectGLJ.getShortNameByID(glj.type),
             quantity:glj.quantity,
+            tenderQuantity:glj.tenderQuantity,
             supply:glj.supply,
             supply_quantity:glj.supply_quantity,
             materialType:glj.materialType,
@@ -1032,22 +1033,28 @@ projectGljObject={
         let callback=function (impactList) {
             info.sheet.suspendPaint();
             info.sheet.suspendEvent();
+            if (dataCode === 'is_adjust_price'){
+                projectGLJ.calcQuantity();
+            }
+
             if(info.sheetName =="materialTreeSheet"){
                 me.showMaterialTreeData();
             }else {
-                me.refreshProjectGljRow(row);
+                // me.refreshProjectGljRow(row);
+                me.showProjectGljData();
                 for(let g of impactList){
                     me.refreshProjectGljRowByID(g.id,row);
                 }
             }
             info.sheet.resumeEvent();
             info.sheet.resumePaint();
-            if (dataCode === 'supply' || dataCode === 'supply_quantity'){    // basePrice、marketPrice 有自己的计算代码,无需走这里重复计算
+            if (dataCode === 'supply' || dataCode === 'supply_quantity' || dataCode === 'is_adjust_price'){    // basePrice、marketPrice 有自己的计算代码,无需走这里重复计算
                 let rations = calcTools.getRationsByProjectGLJ(recode.id);
                 projectObj.project.calcProgram.calcNodesAndSave(rations, function () {
                     projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots);
                 });
-            }
+            };
+
             gljOprObj.refreshView();
         };
         if(dataCode=='basePrice'||dataCode=='marketPrice'){//修改市场价和修改定额价时需要重新记算很多受影响的树节点,现在改成与定字额工料机那里调相同的方法。

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

@@ -888,11 +888,12 @@ var projectObj = {
             }
             if (!err) {
                 that.project.projectGLJ.calcQuantity(true);//计算分部分项和技术措施项目消耗量;
-                gljCol.initGljCol(that.project.projSetting.glj_col?that.project.projSetting.glj_col.showAdjustPrice:false);
+                gljCol.initGljCol(that.project.projSetting.glj_col?that.project.projSetting.glj_col.showAdjustPrice:false,
+                    that.project.property.tenderSetting.showTenderFields?that.project.property.tenderSetting.showTenderFields:false);
                 subObj.initSubSpread();//初始化主界面下方的表格
 
                 let quantityTime = +new Date();
-                that.project.property = projectObj.project.projectInfo.property;
+               // that.project.property = projectObj.project.projectInfo.property;
                 if (typeof overwriteRationCalcBases === 'function')
                     overwriteRationCalcBases(that.project.property.taxType);
                 //that.project.calcProgram.compileAllTemps();
@@ -989,6 +990,8 @@ var projectObj = {
                 if(projectReadOnly){
                     disableSpread(that.mainSpread);
                 }
+                if (projectObj.project.projectInfo.lastFileVer != VERSION)
+                    projectObj.project.calcProgram.doTenderCalc();  // 打开标段后,进行一次全部计算,包括调价计算。
                 $.bootstrapLoading.end();
             }
             else {
@@ -3323,11 +3326,12 @@ function disableTools(){
     $('#calcProgramFileSelect').prop('disabled', 'disabled');
     //调价
     $('#calcPriceOption').prop('disabled', 'disabled');
-    $('#gljPriceTenderCoe').prop('disabled', 'disabled');
+    $('#gljPriceTenderCoe').prop('readOnly', true);
     $('#tenderGLJQuantity').prop('disabled', 'disabled');
     $('#tenderRationQuantity').prop('disabled', 'disabled');
     $('#tenderPrice').prop('disabled', 'disabled');
     $('#cleanTender').prop('disabled', 'disabled');
+    $('#calcTender').prop('disabled', 'disabled');
     //分摊
     $('#exec_divide_btn').prop('disabled', 'disabled');
     $('#cancel_divide_btn').prop('disabled', 'disabled');

+ 132 - 90
web/building_saas/main/js/views/tender_price_view.js

@@ -14,13 +14,13 @@ let tender_obj={
             {headerName: "项目名称", headerWidth: 200, dataCode: "name",showHint:true, hAlign: "left", dataType: "String",spanRows: [2]},
             {headerName: "计量\n单位", headerWidth: 60, dataCode: "unit", hAlign: "center", dataType: "String",spanRows: [2]},
             {headerName: "工程量", headerWidth: 70, dataCode: "quantity", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2],getText:'getText.quantity'},
-            {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", hAlign: "center", cellType : "checkBox",dataType: "Number",spanRows: [2]},
-            {headerName: ["初始报价","综合单价"], headerWidth: 80, dataCode: "feesIndex.common.unitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
-            {headerName: ["","综合合价"], headerWidth: 80, dataCode: "feesIndex.common.totalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
-            {headerName: ["目标造价","综合单价"], headerWidth: 80, dataCode: "targetUnitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
-            {headerName: ["","综合合价"], headerWidth: 80, dataCode: "targetTotalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
-            {headerName: ["调整后报价","综合单价"], headerWidth: 80, dataCode: "feesIndex.common.tenderUnitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
-            {headerName: ["","综合合价"], headerWidth: 80, dataCode: "feesIndex.common.tenderTotalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
+            // {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", hAlign: "center", cellType : "checkBox",dataType: "Number",spanRows: [2]},
+            {headerName: ["初始报价","综合单价"], headerWidth: 100, dataCode: "feesIndex.common.unitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
+            {headerName: ["","综合合价"], headerWidth: 100, dataCode: "feesIndex.common.totalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
+            {headerName: ["目标造价","综合单价"], headerWidth: 100, dataCode: "targetUnitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
+            {headerName: ["","综合合价"], headerWidth: 100, dataCode: "targetTotalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
+            {headerName: ["调整后报价","综合单价"], headerWidth: 100, dataCode: "feesIndex.common.tenderUnitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
+            {headerName: ["","综合合价"], headerWidth: 100, dataCode: "feesIndex.common.tenderTotalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
             {headerName: ["消耗量调整系数","人工"], headerWidth: 80, dataCode: "quantityCoe.labour", hAlign: "right", dataType: "Number",validator:"number",spanCols : [5,1]},
             {headerName: ["","材料"], headerWidth: 80, dataCode: "quantityCoe.material", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
             {headerName: ["","机械"], headerWidth: 80, dataCode: "quantityCoe.machine", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
@@ -29,7 +29,8 @@ let tender_obj={
             {headerName: "子目工程量\n调整系数", headerWidth: 80, dataCode: "rationQuantityCoe", hAlign: "right", dataType: "Number",spanRows: [2],validator:"number"}
         ],
         view: {
-            lockColumns: [0,1,2,3,4,6,7,10,11]
+            // lockColumns: [0,1,2,3,4,6,7,10,11]
+            lockColumns: [0,1,2,3,4,5,6,9,10]
         }
     },
     tenderTreeSetting:{
@@ -39,20 +40,50 @@ let tender_obj={
         "headRowHeight" : [21],
         "cols" : []
     },
+    createTree: function () {
+        let me = this;
+        if (me.tenderTree) return;
+        me.tenderTree = cacheTree.createNew(this);
+        me.tenderTreeSetting = me.createTenderTreeSetting();
+        TREE_SHEET_HELPER.initSetting($('#tenderSpread')[0], me.tenderTreeSetting);
+        me.tenderTreeSetting.setAutoFitRow = MainTreeCol.getEvent("setAutoFitRow");
+        me.createTreeNodes();
+    },
+    createTreeNodes() {
+        let me = this;
+        me.tenderTree.nodes = {}, me.tenderTree.selected = null, me.tenderTree.roots = [], me.tenderTree.items = [];
+
+        function createTenderNode(mainNode, parent, next) {
+            if (mainNode.sourceType != ModuleNames.ration_glj) {//主材、设备的工料机不用显示
+                let newNode = me.tenderTree.addNode(parent, next, mainNode.data.ID);
+                newNode.data = mainNode.data;
+                newNode.source = mainNode.source;
+                newNode.sourceType = mainNode.sourceType;
+                newNode.mainNode = mainNode;
+                if (mainNode.children.length > 0) {
+                    for (let c of mainNode.children) {
+                        createTenderNode(c, newNode, null);
+                    }
+                }
+                return newNode;
+            }
+        };
+
+        for (r of projectObj.project.mainTree.roots) {
+            createTenderNode(r, null, null);
+        };
+        me.tenderTree.sortTreeItems();
+    },
     initTenderSpread:function () {
         if(!this.tenderSpread){
             this.tenderSpread = SheetDataHelper.createNewSpread($("#tenderSpread")[0]);
             sheetCommonObj.spreadDefaultStyle(this.tenderSpread);
-        }
+        };
         this.tenderSheet = this.tenderSpread.getSheet(0);
-        this.tenderTree = cacheTree.createNew(this);
-        this.tenderTreeSetting = this.createTenderTreeSetting();
-        TREE_SHEET_HELPER.initSetting($('#tenderSpread')[0], this.tenderTreeSetting );
-        this.tenderTreeSetting.setAutoFitRow = MainTreeCol.getEvent("setAutoFitRow");
         this.tenderController = TREE_SHEET_CONTROLLER.createNew(this.tenderTree, this.tenderSheet, this.tenderTreeSetting);
         this.tenderSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onSheetValueChange);
-        this.tenderSheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onTenderRangeChange);
         this.tenderSheet.bind(GC.Spread.Sheets.Events.EnterCell, this.onEnterCell);
+        this.tenderSheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onTenderRangeChange);
         this.tenderSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onEditStarting);
         this.tenderController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, this.treeSelectedChanged);
        // this.tenderController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, this.onSelectionChange);
@@ -67,30 +98,14 @@ let tender_obj={
     },
     showTenderData:function () {
         let me = this;
-        let mainTree = projectObj.project.mainTree;
-        this.tenderTree.nodes={},this.tenderTree.selected = null,this.tenderTree.roots = [],this.tenderTree.items=[];
-        for(r of mainTree.roots){
-            createTenderNode(r,null,null);
-        }
-        me.tenderTree.sortTreeItems();
         this.tenderSheet.setRowCount(0);
+        this.tenderTreeSetting.cols.forEach(function (col) {
+            if (col.data.field.hasSubStr(".totalFee") || col.data.field.hasSubStr(".tenderTotalFee"))
+                col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.totalPrice, true);
+            else if (col.data.field.hasSubStr(".unitFee") || col.data.field.hasSubStr(".tenderUnitFee"))
+                col.data.formatter = MainTreeCol.getNumberFormatter(decimalObj.ration.unitPrice, true);
+        });
         me.tenderController.showTreeData();
-
-        function createTenderNode(mainNode,parent,next) {
-            if(mainNode.sourceType != ModuleNames.ration_glj){//主材、设备的工料机不用显示
-                let newNode = me.tenderTree.addNode(parent, next, mainNode.data.ID);
-                newNode.data = mainNode.data;
-                newNode.source =  mainNode.source;
-                newNode.sourceType = mainNode.sourceType;
-                newNode.mainNode = mainNode;
-                if(mainNode.children.length > 0){
-                    for(let c of mainNode.children){
-                        createTenderNode(c,newNode,null);
-                    }
-                }
-                return newNode;
-            }
-        }
     },
     onTenderRangeChange:function (sender,info) {
         let me = tender_obj;
@@ -174,11 +189,18 @@ let tender_obj={
         //在目标造价综合单价中输入数值,按项目属性中的清单单价精度取舍,并清空当前行的目标造价综合合价
         if(dataCode == 'targetUnitFee'){
             value = scMathUtil.roundForObj(value,getDecimal('unitPrice',node));
-            updateData?updateData.data["targetTotalFee"] = null:'';
+	    // updateData?updateData.data["targetTotalFee"] = null:'';
+            updateData?updateData.data["targetTotalFee"] = (value * node.data.quantity).toDecimal(decimalObj.decimal('totalPrice', node)):'';
         }
         if(dataCode == 'targetTotalFee'){
             value = scMathUtil.roundForObj(value,getDecimal('totalPrice',node));
-            updateData?updateData.data["targetUnitFee"] = null:'';
+            // updateData?updateData.data["targetUnitFee"] = null:'';
+            let rst = '';
+            if (updateData){
+                if (calcTools.hasQuantity(node))
+                   rst = (value / node.data.quantity).toDecimal(decimalObj.decimal('unitPrice', node));
+            };
+            updateData.data["targetUnitFee"] = rst;
         }
         updateData.data[dataCode] = value;
         updateNodes.push(updateData);
@@ -205,20 +227,23 @@ let tender_obj={
     },
     onEnterCell : function (sender,args) {
         let me = tender_obj, row = args.row, col = args.col;
-        if ([8, 9].includes(col)){
-            let node = me.tenderTree.items[row];
-            if (node.children && node.children.length > 0) {   // 父结点只读
-                me.tenderSheet.getCell(row, col).locked(true);// = true;
-            }
+        if ([7, 8].includes(col)){                                  // 目标单价、目标合价
+            let treeNode = me.tenderTree.items[row];
+            if (calcTools.isCalcBaseBill(treeNode)){                    // 公式结点只读
+                me.tenderSheet.getCell(row, col).locked(true);
+            };
         }
     },
     updateChildrenValue:function (node,dataCode,value,datas,nodes) {
          if(node.children.length > 0){
             for(let c of node.children){
-                this.updateChildrenValue(c,dataCode,value,datas,nodes);
+                let v = value;
+                if ((dataCode.indexOf("quantityCoe.") != -1) && (calcTools.isVolumePrice(c) || calcTools.isGljRation(c)))
+                    v = 0;
+                this.updateChildrenValue(c,dataCode,v,datas,nodes);
                 let updateData = {type:c.sourceType,data:{'ID' : c.data.ID}};
-                updateData.data[dataCode] = value;
-                if(dataCode == 'is_adjust_price' && value == 1){
+                updateData.data[dataCode] = v;
+                if(dataCode == 'is_adjust_price' && v == 1){
                     updateData = this.cleanTenderCoe(updateData,c);
                 }else if(dataCode.indexOf("Coe")!= -1 && c.data.is_adjust_price == 1){//更新调整系数时忽略不调价的行
                     continue;
@@ -248,31 +273,22 @@ let tender_obj={
     cleanTenderPrice:function (updateData,node) {//清空调整后报价
         if(node.data.fees){
             for(let i =0; i< node.data.fees.length; i++){
-                node.data.fees[i].tenderUnitFee?updateData.data["fees."+i+'.tenderUnitFee'] = 0:'';
-                node.data.fees[i].tenderTotalFee?updateData.data["fees."+i+'.tenderTotalFee'] = 0:'';
+                // 问题:清空调价后,报表显示为空。解决:清空后仍然要保留调后单价和调后金额,初始化使之与原始综合单价、综合合价相等。
+                // node.data.fees[i].tenderUnitFee?updateData.data["fees."+i+'.tenderUnitFee'] = 0:'';
+                // node.data.fees[i].tenderTotalFee?updateData.data["fees."+i+'.tenderTotalFee'] = 0:'';
+                node.data.fees[i].tenderUnitFee?updateData.data["fees."+i+'.tenderUnitFee'] = node.data.fees[i].unitFee:'';
+                node.data.fees[i].tenderTotalFee?updateData.data["fees."+i+'.tenderTotalFee'] = node.data.fees[i].totalFee:'';
             }
         }
     },
-    cleanCacheCoes: function (){
-        for(let node of tender_obj.tenderTree.items){
-            if (node.data.rationQuantityCoe) node.data.rationQuantityCoe = null;
-            let qcObj = node.data.quantityCoe;
-            if (qcObj){
-                for (let pn in qcObj){
-                    qcObj[pn] = null;
-                };
-            };
-        };
-    },
-
     calcOptionsChecking:function (option) {//调整选项检查,返回需要更新的数组
         let datas = [];
         let me = tender_obj;
         for(let node of me.tenderTree.items){
             let tem_updateData = {type:node.sourceType,data:{}};
-            if(option == 'coeBase') { //当值为“根据调整系数计算报价”时,清空目标报价。
+            if(option == 'coeBase') {                           // 正向:当值为“根据调整系数计算报价”时,清空目标报价。
                 me.cleanTargetPrice(tem_updateData,node);
-            }else if(option == 'priceBase'){//当值为“根据报价计算调整系数”时,清空调整系数。
+            }else if(option == 'priceBase_RCJ' || option == 'priceBase_ZM'){                    // 反向:当值为“根据报价计算调整系数”时,清空调整系数。
                 me.cleanTenderCoe(tem_updateData,node);
             }
             if(!_.isEmpty(tem_updateData.data)){//如果需要更新
@@ -359,8 +375,7 @@ let tender_obj={
         let me = tender_obj, row = args.row, col = args.col;
         if(me.editChecking(row,col) == false){
             args.cancel = true;
-        }
-
+        };
     },
     editChecking:function (row,col,isPaste = false) {//return false表示不能编辑
         let me = tender_obj;
@@ -384,41 +399,41 @@ let tender_obj={
             }
         }
         if(dataCode.indexOf('Coe') != -1){//如果是调整系数列
-            if($('#calcPriceOption').val() =='priceBase'){//下拉按钮显示为“根据报价计算调整系数”时,只读。
+            if($('#calcPriceOption').val() =='priceBase_RCJ' || $('#calcPriceOption').val() =='priceBase_ZM'){//下拉按钮显示为“根据报价计算调整系数”时,只读。
                 return false;
             }else if(me.tenderTree.items[row].data.is_adjust_price === 1){//打勾了不调价,只读。
                 return false;
             }
         }
+        // 量价类,工料机消耗量调整系数不允许输入
+        let treeNode = me.tenderTree.items[row];
+        if (calcTools.isVolumePrice(treeNode) || calcTools.isGljRation(treeNode)){
+            if ([11,12,13,14,15].includes(col))
+                return false;
+        };
         return true;
     },
-    initPageContent : function () {
+    initPageContent: function () {
         let tenderSetting = projectObj.project.property.tenderSetting;
-        let calcPriceOption = tenderSetting && tenderSetting.calcPriceOption? tenderSetting.calcPriceOption :"coeBase";
         let gljPriceTenderCoe = tenderSetting && tenderSetting.gljPriceTenderCoe?tenderSetting.gljPriceTenderCoe:1;
+        let showTenderFields = tenderSetting && tenderSetting.showTenderFields?tenderSetting.showTenderFields:false;
+        let calcPriceOption = calcTools.getTenderCalcType();
         $('#calcPriceOption').val(calcPriceOption);
         $('#gljPriceTenderCoe').val(gljPriceTenderCoe);
+        $('#cbShowTenderFields').prop("checked", showTenderFields);
         if(calcPriceOption == 'coeBase'){
-            if(!projectReadOnly){
-                $('#tenderPrice').removeAttr("disabled");
-            }
+            $('#gljPriceTenderCoe').removeAttr("disabled");
             $('#tenderGLJQuantity').attr("disabled",true);
             $('#tenderRationQuantity').attr("disabled",true);
+            if(!projectReadOnly){
+                $('#tenderPrice').removeAttr("disabled");
+            };
         }else {
-            $('#tenderPrice').attr("disabled",true);
+            $('#gljPriceTenderCoe').attr("disabled",true);
             $('#tenderGLJQuantity').removeAttr("disabled");
             $('#tenderRationQuantity').removeAttr("disabled");
-        }
-        //gljPriceTenderCoe
-    },
-    doTenderCalc: function(tender){
-        if (tender != tenderTypes.ttCalc)
-            tender_obj.cleanCacheCoes();
-        let callback = function () {
-            projectObj.project.saveProperty('hasTender', true);
-            tender_obj.showTenderData();
+            // $('#tenderPrice').attr("disabled",true);
         };
-        projectObj.project.calcProgram.calcAllNodesAndSave(calcAllType.catAll, callback, tender);
     }
 };
 
@@ -427,10 +442,16 @@ $(function () {
         sessionStorage.setItem('mainTab', '#tab_tender_price');
         $(e.relatedTarget.hash).removeClass('active');
         if(!tender_obj.tenderSpread){
+            tender_obj.createTree();
             tender_obj.initTenderSpread();
             tender_obj.showTenderData();
             tender_obj.initPageContent();
         }
+        else {
+            tender_obj.createTreeNodes();
+            tender_obj.showTenderData();
+        };
+
         autoFlashHeight();
         tender_obj.tenderSpread.refresh();
     });
@@ -452,20 +473,26 @@ $(function () {
             }
         }
         datas.push({type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.tenderSetting.gljPriceTenderCoe':1}});//恢复人材机单价调整系数为1。
-        datas.push({type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.hasTender': false}});
+        // datas.push({type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.hasTender': false}});
         me.updateTenderData(datas,function () {
             me.refreshTenderTreeByDatas(datas);
         });
+        $('#calcTender').trigger('click');
     });
 
     $('#calcPriceOption').change(function(){
         let me = tender_obj;
+
         let newVal = $(this).val();
         let datas = me.calcOptionsChecking(newVal);
         let updateData = {type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.tenderSetting.calcPriceOption':newVal}};
         datas.push(updateData);
         me.updateTenderData(datas,function () {
             me.refreshTenderTreeByDatas(datas);
+            // 反向调价时,一切换,就先把单价系数显示成1。这里仅表皮显示变了,满足客户的好奇心,后台没有同步。真正干活的是在点了调价按钮之时。
+            let tenderType = $('#calcPriceOption').val();
+            if(tenderType == 'priceBase_RCJ' || tenderType == 'priceBase_ZM')
+                $('#gljPriceTenderCoe').val(1);
         });
     });
 
@@ -474,22 +501,37 @@ $(function () {
         let process = getDecimal('process');
         var newVal = $(this).val();
         process = scMathUtil.roundForObj(newVal,process);
+        if (process == 0) process = 1;    // 清空系数时,强制给1
         let updateData = {type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.tenderSetting.gljPriceTenderCoe':process}};
         me.updateTenderData([updateData],function () {
             me.initPageContent();
         });
     });
 
-    $('#tenderPrice').on('click', function () {
-        tender_obj.doTenderCalc(tenderTypes.ttCalc);
-    });
-
-    $('#tenderGLJQuantity').on('click', function () {
-        tender_obj.doTenderCalc(tenderTypes.ttReverseGLJ);
+    $('#calcTender').on('click', function () {
+        let callback = function () {
+            // projectObj.project.saveProperty('hasTender', true);  // 一定调价,这个属性已失去意义
+            if (projectObj.project.property.needRestoreGgljPriceTenderCoe){         // 入库存储,清理标记,刷新UI显示
+                projectObj.project.saveProperty('tenderSetting.gljPriceTenderCoe', 1);
+                delete projectObj.project.property.needRestoreGgljPriceTenderCoe;
+                $('#gljPriceTenderCoe').val(1);
+            }
+            tender_obj.showTenderData();
+            projectObj.project.projectGLJ.calcQuantity();
+            // 刷新造价书界面的相关显示。刷新放在这里是为了切换UI时体验更流畅。
+            if($('#linkJSCX').hasClass('active'))
+                calcProgramObj.refreshCalcProgram(projectObj.project.mainTree.selected, 2)
+            if($('#linkGLJ').hasClass('active'))
+                gljOprObj.refreshView();
+        };
+        projectObj.project.calcProgram.doTenderCalc(callback);
     });
 
-    $('#tenderRationQuantity').on('click', function () {
-        tender_obj.doTenderCalc(tenderTypes.ttReverseRation);
+    $('#cbShowTenderFields').on('click', function () {
+        let showFields = $('#cbShowTenderFields').prop("checked");
+        projectObj.project.saveProperty('tenderSetting.showTenderFields', showFields);
+        projectObj.project.property.tenderSetting.showTenderFields = showFields;
+        gljCol.showTenderFields(showFields, true);
     });
 
 });