zhangweicheng 5 gadi atpakaļ
vecāks
revīzija
f63c394332

+ 1 - 1
modules/all_models/compleGlj_section.js

@@ -14,7 +14,7 @@ const Schema = mongoose.Schema;
 const compleGljSection = new Schema({
     userId: String,
     compilationId: String,
-    Name: String,
+    Name: {type: String,index: true},
     ID: String,
     ParentID: String,
     NextSiblingID: String,

+ 1 - 1
modules/all_models/compleRation_ration.js

@@ -41,7 +41,7 @@ const compleRationSchema = new Schema({
     userId: String,
     compilationId: String,
     rationRepId: Number,
-    ID:Number,
+    ID:{type: Number,index: true},
     code: String,
     name: String,
     unit: String,

+ 1 - 1
modules/all_models/compleRation_section.js

@@ -17,7 +17,7 @@ const compleRationSectionTreeSchema = new Schema({
     name: String,
     //是否是同层第一个节点
    // isFirst: Boolean,
-    ID: String,
+    ID: {type: String,index: true},
     NextSiblingID: String,
     ParentID: String,
     deleteInfo: deleteSchema,

+ 1 - 1
modules/all_models/stdRation_coe.js

@@ -19,7 +19,7 @@ const coeSchema = new Schema({
 
 const coeListSchema = new Schema({
     libID: Number,                      // 所属定额定ID
-    ID: Number,                         // 系数ID(流水号ID)
+    ID: {type: Number,index: true},                         // 系数ID(流水号ID)
     serialNo: Number,                  //编号
     name: String,                       // 名称
     content: String,                    // 说明

+ 1 - 1
modules/all_models/stdRation_ration.js

@@ -32,7 +32,7 @@ const rationInstSchema = new Schema({
 },{_id: false});
 
 const rationItemSchema = new Schema({
-    ID:Number,
+    ID:{type: Number,index: true},
     code: String,
     name: String,
     unit: String,

+ 2 - 3
modules/all_models/stdRation_section.js

@@ -6,15 +6,14 @@ const mongoose = require('mongoose');
 const Schema = mongoose.Schema;
 const rationChapterTreeSchema = new Schema({//章节树  //生成唯一id改为sectionID  改成string
     rationRepId: Number,
-    ID:Number,
+    ID:{type: Number,index: true},
     ParentID:Number,
     NextSiblingID:Number,
     name: String,
     explanation: String,//说明
     ruleText: String,//计算规则,
     jobContentSituation: String,//工作内容适用情况,ALL适用本项全部定额,PARTIAL适用本项部分定额
-    annotationSituation: String,//附注适用情况,ALL适用本项全部定额,PARTIAL适用本项部分定额
-    isDeleted: Boolean
+    annotationSituation: String//附注适用情况,ALL适用本项全部定额,PARTIAL适用本项部分定额
 });
 
 mongoose.model("std_ration_lib_ration_chapter_trees", rationChapterTreeSchema, 'std_ration_lib_ration_chapter_trees');

+ 1 - 1
modules/all_models/std_glj.js

@@ -21,7 +21,7 @@ const std_gljComponent = new Schema(
 const std_glj = new Schema({
     deleted: Boolean,
     repositoryId: {type: Number,index: true},
-    ID: Number,
+    ID: {type: Number,index: true},
     code: String,
     name: String,
     specs: String,

+ 6 - 6
modules/complementary_ration_lib/models/searchModel.js

@@ -27,28 +27,28 @@ class SearchDao{
                 ration = await this.getCompleRation(userId,compilationId,code,ID);
             }else {
                 firstLib = parseInt(firstLib);
-                let firstQuery = {rationRepId: firstLib, code: code, $or: [{isDeleted: null}, {isDeleted: false}]};
+                let firstQuery = {rationRepId: firstLib, code: code};
                 if(ID){
-                    firstQuery = {ID: ID, $or: [{isDeleted: null}, {isDeleted: false}]};
+                    firstQuery = {ID: ID};
                 }
                 ration = await this.getStdRation(firstQuery);
             }
             if(ration == null){//选中的定额库或者默认的定额库中没有找到定额,才走常规的流程查找其它定额库
-                let stdQuery = {rationRepId: {$in: otherLibs}, code: code, $or: [{isDeleted: null}, {isDeleted: false}]};
+                let stdQuery = {rationRepId: {$in: otherLibs}, code: code};
                 if(ID){
-                    stdQuery = {ID: ID, $or: [{isDeleted: null}, {isDeleted: false}]};
+                    stdQuery = {ID: ID};
                 }
                 ration = await this.getStdRation(stdQuery);
                 if(ration == null) ration = await this.getCompleRation(userId,compilationId,code,ID);
             }
             if(isDef(ration)){
                 if (ration.type === 'std') {
-                    let stdChapter = await stdSectionTreeModel.findOne({rationRepId: ration.rationRepId, ID: ration.sectionId, $or: [{isDeleted: null}, {isDeleted: false}]});
+                    let stdChapter = await stdSectionTreeModel.findOne({ID: ration.sectionId});
                     if(isDef(stdChapter)){
                         ration.chapter = stdChapter._doc;
                     }
                 } else {
-                    let compleChapter = await compleRationSectionTreeModel.findOne({ID: ration.sectionId, $or: [{isDeleted: null}, {isDeleted: false}]});
+                    let compleChapter = await compleRationSectionTreeModel.findOne({ID: ration.sectionId});
                     if(isDef(compleChapter)){
                         ration.chapter = compleChapter._doc;
                     }

+ 493 - 78
modules/main/facade/ration_facade.js

@@ -17,6 +17,7 @@ module.exports = {
 
 let mongoose = require('mongoose');
 import SearchDao from '../../complementary_ration_lib/models/searchModel';
+import GLJListModel from "../../glj/models/glj_list_model";
 const scMathUtil = require('../../../public/scMathUtil').getUtil();
 let ration_glj_facade = require("../../ration_glj/facade/ration_glj_facade");
 let glj_calculate_facade = require("../../ration_glj/facade/glj_calculate_facade");
@@ -37,6 +38,13 @@ let complementaryRationModel = mongoose.model('complementary_ration_items');
 
 let coeMolde = mongoose.model('std_ration_lib_coe_list');
 let compleCoeModel = mongoose.model('complementary_ration_coe_list');
+let projectGLJModel = mongoose.model("glj_list");
+let mixRatioModel = mongoose.model("mix_ratio");
+let complementaryGljLibModel = mongoose.model('complementary_glj_lib');
+let counterModel =  mongoose.model('counter');
+let unitPriceModel = mongoose.model('unit_price');
+let chongqingOverWrite = require("../../../web/over_write/js/chongqing_2018.js");
+
 
 let _= require('lodash');
 const projectDao = require('../../pm/models/project_model').project;
@@ -164,8 +172,8 @@ async function insertNewRation(newData,defaultLibID,std,calQuantity) {//插入
     }
     let addRationGLJTime = +new Date();
     console.log("计算消耗量时间-------------------------------"+(addRationGLJTime - startTime));
-    let newRation = await ration_model.model.create(newData);
-    return newRation;
+    await ration_model.model.insertMany(newData);
+    return newData;
     /*ration_model.model.create(newData);
     return newData;*/
 }
@@ -313,34 +321,47 @@ async function addRationTemplate(std,newRation) {
 async function addRationCoe(std,newRation,compilation) {
     let ration_coe_list = [];
     let seq = 0;
+    let stdCoeIDs = [];//与comCoeIDs两者不共存
+    let comCoeIDs = [];
+    let coeMap={};
     if(std.hasOwnProperty('rationCoeList')&&std.rationCoeList.length>0){//添加标准库的工料机
         for(let sub of std.rationCoeList){
-            let libCoe;
-            if (std.type === 'std') {
-                libCoe = await coeMolde.findOne({'libID':std.rationRepId,'ID':sub.ID,"$or": [{"isDeleted": null}, {"isDeleted": false}]});//std.rationRepId;
-            } else {
-                libCoe = await compleCoeModel.findOne({ID: sub.ID, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]});
-            }
-            if(libCoe){
-                let newCoe = {};
-                newCoe.ID = uuidV1();
-                newCoe.coeID = sub.ID;
-                newCoe.seq = seq;
-                newCoe.name = libCoe.name;
-                newCoe.content = libCoe.content;
-                newCoe.original_code = libCoe.original_code;
-                newCoe.option_codes = libCoe.option_codes;
-                newCoe.option_list = libCoe.option_list;
-                newCoe.isAdjust=0;
-                newCoe.coes = libCoe.coes;
-                newCoe.rationID = newRation.ID;
-                newCoe.projectID = newRation.projectID;
-                seq++;
-                ration_coe_list.push(newCoe);
-            }
+          std.type === 'std'?stdCoeIDs.push(sub.ID):comCoeIDs.push(sub.ID);  
+        }
+        let libCoeList = [];
+        let seqLibIDs = [];
+        if (std.type === 'std'){
+          libCoeList = await coeMolde.find({'ID':{'$in':stdCoeIDs}}).lean();
+          seqLibIDs = stdCoeIDs;
+        }else{
+          libCoeList = await compleCoeModel.find({'ID':{'$in':comCoeIDs}}).lean();
+          seqLibIDs = comCoeIDs;
+        }
+        for(let lib of libCoeList){
+          coeMap[lib.ID] = lib;
+        }
+        for(let ID of seqLibIDs){
+          let libCoe = coeMap[ID];
+          if(libCoe){
+            let newCoe = {};
+            newCoe.ID = uuidV1();
+            newCoe.coeID = ID;
+            newCoe.seq = seq;
+            newCoe.name = libCoe.name;
+            newCoe.content = libCoe.content;
+            newCoe.original_code = libCoe.original_code;
+            newCoe.option_codes = libCoe.option_codes;
+            newCoe.option_list = libCoe.option_list;
+            newCoe.isAdjust=0;
+            newCoe.coes = libCoe.coes;
+            newCoe.rationID = newRation.ID;
+            newCoe.projectID = newRation.projectID;
+            seq++;
+            ration_coe_list.push(newCoe); 
+          }
         }
     }
-    let lastCoe = await getCustomerCoe(newRation.projectID,newRation.ID,seq,compilation);
+    let lastCoe = await getCustomerCoe(newRation.projectID,newRation.ID,seq,compilation);//这个地方加载overWrite需要一些时间
     ration_coe_list.push(lastCoe);
     await ration_coe.insertMany(ration_coe_list);
     return ration_coe_list;
@@ -376,9 +397,13 @@ async function getCustomerCoe(projectID,rationID,seq,compilation){//取自定义
     try {
     //查看编办中有没有重写路径
      if(compilation.overWriteUrl && compilation.overWriteUrl!=""){
-         let overWrite = require("../../.."+compilation.overWriteUrl);
-         if(overWrite.getCusCoeContent) lastCoe.content = overWrite.getCusCoeContent();
-         if(overWrite.getCustomerCoeData) lastCoe.coes = overWrite.getCustomerCoeData();
+        if(compilation.overWriteUrl.indexOf("chongqing_2018")!= -1){
+          console.log("重庆overwrite");
+          let overWrite = chongqingOverWrite
+          if(overWrite.getCusCoeContent) lastCoe.content = overWrite.getCusCoeContent();
+          if(overWrite.getCustomerCoeData) lastCoe.coes = overWrite.getCustomerCoeData();
+        }
+         
      }
      return lastCoe
    }catch (err){
@@ -400,6 +425,9 @@ async function addRationGLJ(std,newRation,compilation) {
     let newRationGLJList = [];
     let rationGLJShowList = [];
     let projectGLJList = [];
+    let gljKeyMap = {};
+    let mixRatioMap={};
+    let gljCodes=[];
     let unitPriceFileId = 0;
     let property = await projectDao.getProjectProperty(newRation.projectID);
     if(property){
@@ -425,56 +453,66 @@ async function addRationGLJ(std,newRation,compilation) {
         let stdGLJMapTime = +new Date();
         console.log("找到工料机映射表时间-------------------------------"+(stdGLJMapTime - first));
         for(let sub of std.rationGljList){
-            let newGLJ = {};
-            newGLJ.ID = uuidV1();
-            newGLJ.projectID = newRation.projectID;
-            newGLJ.GLJID = sub.gljId;
-            newGLJ.rationID = newRation.ID;
-            newGLJ.billsItemID = newRation.billsItemID;
-            newGLJ.rationItemQuantity = sub.consumeAmt;
-            newGLJ.quantity = sub.consumeAmt;
-            newGLJ.glj_repository_id = std.rationRepId;
-            let std_glj = null;
-            if(sub.type == 'complementary'){//有可能来自标准工料机库或补充工料机库
-                std_glj = cptGLJMap[sub.gljId];
-                newGLJ.from = 'cpt';
-            }else {
-                std_glj = stdGLJMap[sub.gljId];
-                newGLJ.from = 'std';
-            }
-            //多单价情况处理
-            if(ext && ext.priceField && std_glj && std_glj.priceProperty){
-                std_glj.basePrice =  std_glj.priceProperty[ext.priceField];
-            }
-            if(std_glj){
-                newGLJ.name = std_glj.name;
-                newGLJ.code = std_glj.code;
-                newGLJ.original_code = std_glj.code;
-                newGLJ.unit = std_glj.unit;
-                newGLJ.specs = std_glj.specs;
-                newGLJ.model = std_glj.model;
-                newGLJ.basePrice = std_glj.basePrice;
-                newGLJ.marketPrice = std_glj.basePrice;
-                newGLJ.taxRate= std_glj.taxRate;
-                newGLJ.shortName = std_glj.shortName;
-                newGLJ.type = std_glj.gljType;
-                newGLJ.repositoryId = std_glj.repositoryId;
-                newGLJ.adjCoe = std_glj.adjCoe;
-                newGLJ.materialType = std_glj.materialType;
-                newGLJ.materialCoe = std_glj.materialCoe;
-                newGLJ.materialIndexType = std_glj.materialIndexType;
-                newGLJ.materialIndexUnit = std_glj.materialIndexUnit;
-                newGLJ.materialIndexCoe = std_glj.materialIndexCoe;
-                newGLJ.createType = 'normal';
-                let [info,projectGLJ] =  await ration_glj_facade.getInfoFromProjectGLJ(newGLJ,unitPriceFileId,ext);
-                newGLJ = ration_glj_facade.createNewRecord(info);
-                newRationGLJList.push(newGLJ);
-                rationGLJShowList.push(info);
-                projectGLJList.push(projectGLJ)
-            }
+          let newGLJ = {};
+          newGLJ.ID = uuidV1();
+          newGLJ.projectID = newRation.projectID;
+          newGLJ.GLJID = sub.gljId;
+          newGLJ.rationID = newRation.ID;
+          newGLJ.billsItemID = newRation.billsItemID;
+          newGLJ.rationItemQuantity = sub.consumeAmt;
+          newGLJ.quantity = sub.consumeAmt;
+          newGLJ.glj_repository_id = std.rationRepId;
+          let std_glj = null;
+          if(sub.type == 'complementary'){//有可能来自标准工料机库或补充工料机库
+              std_glj = cptGLJMap[sub.gljId];
+              newGLJ.from = 'cpt';
+          }else {
+              std_glj = stdGLJMap[sub.gljId];
+              newGLJ.from = 'std';
+          }
+          //多单价情况处理
+          if(ext && ext.priceField && std_glj && std_glj.priceProperty){
+              std_glj.basePrice =  std_glj.priceProperty[ext.priceField];
+          }
+          if(std_glj){
+            newGLJ.name = std_glj.name;
+            newGLJ.code = std_glj.code;
+            newGLJ.original_code = std_glj.code;
+            newGLJ.unit = std_glj.unit;
+            newGLJ.specs = std_glj.specs;
+            newGLJ.model = std_glj.model;
+            newGLJ.basePrice = std_glj.basePrice;
+            newGLJ.marketPrice = std_glj.basePrice;
+            newGLJ.taxRate= std_glj.taxRate;
+            newGLJ.shortName = std_glj.shortName;
+            newGLJ.type = std_glj.gljType;
+            newGLJ.repositoryId = std_glj.repositoryId;
+            newGLJ.adjCoe = std_glj.adjCoe;
+            newGLJ.materialType = std_glj.materialType;
+            newGLJ.materialCoe = std_glj.materialCoe;
+            newGLJ.materialIndexType = std_glj.materialIndexType;
+            newGLJ.materialIndexUnit = std_glj.materialIndexUnit;
+            newGLJ.materialIndexCoe = std_glj.materialIndexCoe;
+            newGLJ.createType = 'normal';
+
+            let tindex = getIndex(newGLJ);
+            if(std_glj.component && std_glj.component.length > 0) mixRatioMap[tindex] = std_glj.component;
+            let tdata = ration_glj_facade.getGLJSearchInfo(newGLJ);
+            gljKeyMap[tindex] = tdata;
+            gljCodes.push(tdata.code);
+            newRationGLJList.push(newGLJ);
+
+              // let [info,projectGLJ] =  await ration_glj_facade.getInfoFromProjectGLJ(newGLJ,unitPriceFileId,ext);
+              // newGLJ = ration_glj_facade.createNewRecord(info);
+              // newRationGLJList.push(newGLJ);
+              // rationGLJShowList.push(info);
+              // projectGLJList.push(projectGLJ)
+          }
             //let InfoFromProjectGLJ = +new Date();
             //console.log("找到项目工料机时间-------------------------------"+(InfoFromProjectGLJ - std_gljTime));
         }
+        [newRationGLJList, projectGLJList] =  await getProjectGLJinfo(newRation.projectID,newRationGLJList,gljKeyMap,gljCodes,mixRatioMap,unitPriceFileId,ext);
+
     }
     let before = +new Date();
     console.log("总查询时间为-------------------------------"+(before-first));
@@ -484,9 +522,374 @@ async function addRationGLJ(std,newRation,compilation) {
     let after = +new Date();
     console.log("实际插入时间为-------------------------------"+(after-before));
     console.log("总操作时间为-------------------------------"+(after-first));
-    return [rationGLJShowList,projectGLJList]
+    return [newRationGLJList,projectGLJList]
+}
+
+
+async function getProjectGLJinfo(projectID,t_newRationGLJList,gljKeyMap,gljCodes,mixRatioMap,unitPriceFileId,ext){//批量插入或查找项目工料机信息
+  //先根据工料机编号在项目工料机中查找工料机是否存在
+  let projectGLJMap={};
+  let projectGLJList = [];
+  let newProjectGLJList=[];//工料机ID要重新去取
+  let connectKeyList = [];
+  let newRationGLJList = [];
+
+  let gljListModel = new GLJListModel();
+  let t_projectGLJList = await projectGLJModel.find({'project_id':projectID,'code':{'$in':gljCodes}}).lean();
+  for(let pg of t_projectGLJList){
+     let pindex = getIndex(pg);  
+     projectGLJMap[pindex] = pg;
+  }
+  for(let key in gljKeyMap){
+    if(!projectGLJMap[key]){//如果项目工料机不存在,则添加
+      newProjectGLJList.push(gljKeyMap[key]);
+      projectGLJMap[key] = gljKeyMap[key];
+    }
+    //查看组成物
+    if(gljListModel.ownCompositionTypes.indexOf(gljKeyMap[key].type)!=-1){//有组成物的类型
+      connectKeyList.push(key);
+    }
+  }
+
+
+  let [existMixRatioMap,mixRatioInsertData,missCodeList] = await getMixRatioInfo(projectID,projectGLJMap,newProjectGLJList,mixRatioMap,connectKeyList,unitPriceFileId,ext);
+  if(missCodeList.length > 0) gljCodes = gljCodes.concat(missCodeList);
+ 
+ 
+  let [unitPriceMap,newUnitPriceList] = await getUnitPriceData(newProjectGLJList,gljCodes,unitPriceFileId);
+  if(newUnitPriceList.length > 0) await unitPriceModel.insertMany(newUnitPriceList);
+
+
+  if(mixRatioInsertData.length > 0) await mixRatioModel.insertMany(mixRatioInsertData);
+
+  //插入项目工料机
+  if(newProjectGLJList.length > 0){
+    await setIDfromCounter("glj_list",newProjectGLJList);
+    await projectGLJModel.insertMany(newProjectGLJList);
+  }
+
+
+  //组装数据
+  for(let ration_glj of t_newRationGLJList){
+    let rkey = getIndex(ration_glj);
+    let pglj = projectGLJMap[rkey];
+    let subList = [];
+    setUnitPrice(pglj,unitPriceMap);
+    if(existMixRatioMap[rkey]){//如果有组成物
+      for(let m of existMixRatioMap[rkey]){
+         let mpglj = projectGLJMap[getIndex(m)]
+         if(mpglj){
+          let cglj = _.clone(mpglj); 
+          setUnitPrice(cglj,unitPriceMap);
+          cglj.ratio_data = m;
+          subList.push(cglj);
+         }else{
+            throw  `组成物${m.name}对应的项目工料机没有找到`;
+         }
+      }
+      pglj.subList =subList; 
+    }
+    ration_glj.projectGLJID = pglj.id;
+    newRationGLJList.push(ration_glj_facade.createNewRecord(ration_glj));
+    projectGLJList.push(pglj);
+  }
+
+
+
+  return [newRationGLJList, projectGLJList];
+
+
+
+
+  function setUnitPrice(p,unitPriceMap){
+    p.unit_price = unitPriceMap[getIndex(p)];
+  }
+
+}
+
+
+
+async function getUnitPriceData(newProjectGLJList,gljCodes,unitPriceFileId){
+  let unitPriceMap = {};
+  let newUnitPriceList = [];
+  let unitPriceList = await unitPriceModel.find({unit_price_file_id: unitPriceFileId,'code':{'$in':gljCodes}}).lean();
+  for(let u of unitPriceList){
+    unitPriceMap[getIndex(u)]=u;
+  }
+
+  for(let np of newProjectGLJList){
+    let pkey = getIndex(np);
+    if(unitPriceMap[pkey]) continue;
+
+    let insertData = {
+      code: np.code,
+      base_price: np.base_price,
+      market_price: np.market_price,
+      unit_price_file_id: unitPriceFileId,
+      name: np.name,
+      specs:np.specs?np.specs:'',
+      original_code:np.original_code,
+      unit:np.unit?np.unit:'',
+      type: np.type,
+      short_name: np.shortName !== undefined ? np.shortName : '',
+      glj_id: np.glj_id,
+      is_add:0,
+      grossWeightCoe:np.grossWeightCoe,
+      purchaseStorageRate:np.purchaseStorageRate,
+      offSiteTransportLossRate:np.offSiteTransportLossRate,
+      handlingLossRate:np.handlingLossRate
+    };
+    if(np.from=='cpt') insertData.is_add=1;//如果是来自补充工料机,则都添加新增标记
+    if(insertData.code != insertData.original_code) insertData.is_add=1;//添加的时候如果是复制整块来的,可能在源项目中是新增的工料机,这里也要添上(暂时可能还用不到)
+    newUnitPriceList.push(insertData);
+    unitPriceMap[pkey] = insertData;
+  }
+
+
+  if(newUnitPriceList.length > 0) await setIDfromCounter("unit_price",newUnitPriceList);
+
+  return [unitPriceMap,newUnitPriceList];
+
+
 }
 
+
+async function getMixRatioInfo(projectID,projectGLJMap,newProjectGLJList,mixRatioMap,connectKeyList,unitPriceFileId,ext){//取组成物信息,得到缺少的组成物情况
+  let missCodeList = []; //所有组成物信息的编码,用来统一查询对应的项目工料机是否存在
+  let existMixRatioMap ={};
+  let codeMap={};//用来去重
+  let mixRatioInsertData = [];
+
+
+  // 1. 先检查现在的组成物表中,是否有相关信息 - 生成映射记录
+  if(connectKeyList.length > 0){//有组成物的话从数据库中取出组成物信息
+    let mixRatioList = await mixRatioModel.find({'unit_price_file_id': unitPriceFileId,'connect_key': {'$in':connectKeyList}}).lean();
+    for(let m of mixRatioList){
+        //组成物信息分组,查看哪些是已经存在的
+       existMixRatioMap[m.connect_key]?existMixRatioMap[m.connect_key].push(m):existMixRatioMap[m.connect_key]=[m];
+       //查看组成物对应的项目工料机是否存在,如果不存在,要插入项目工料机
+       let mkey = getIndex(m);
+       if(!projectGLJMap[mkey] && !codeMap[m.code]){//如果之前查出来的项目工料机中不包含组成物的信息,要加到missCode里面再查找一次项目工料机看是否存在
+          missCodeList.push(m.code);
+          codeMap[m.code] = true;
+       } 
+    }
+
+    // 2 将第一步得到的映射表 与在标准库查询父工料机得到的映射表对比,得出哪些组物成还需要添加,获得库ID
+    let stdIDs = []; 
+    let comIDs = [];
+    let missMixRatioGroup = [];
+    for(let ck of connectKeyList){//查看项目中组成物信息是否已经存在,如果不存在,则用插定额时获取的组成物信息从数据库中获取
+       if(!existMixRatioMap[ck] && mixRatioMap[ck] && mixRatioMap[ck].length > 0){//组成物信息不存在
+         let pglj = projectGLJMap[ck];//取出父数据 
+         let from =  pglj.from === undefined|| pglj.from ===null || pglj.from === ""?'std' : pglj.from;
+         for(let c of mixRatioMap[ck]){
+            if(from == "std"){//标准的工料机只来自标准的
+                stdIDs.push(c.ID); 
+            }else{
+              c.isStd?stdIDs.push(c.ID):comIDs.push(c.ID);  
+            } 
+         } 
+         missMixRatioGroup.push({'connect_key':ck,'list':mixRatioMap[ck],'from':from});
+       }
+    }
+
+    //3.统一查询所有组成物在标准库中的详细信息
+    let stdMixMap = {};
+    //整理需插入的组成物列表的数据
+    //来自标准工料机
+    if(stdIDs.length > 0){
+      stdIDs = _.uniq(stdIDs);//去重
+      let stdMixList =  await std_glj_lib_gljList_model.find({'ID':{'$in':stdIDs}}).lean();
+      for(let sm of stdMixList){
+        stdMixMap[sm.ID] = sm;
+        let skey = getIndex(sm,['code','name','specs','unit','gljType']);
+        if(!projectGLJMap[skey] && !codeMap[sm.code]){
+          missCodeList.push(sm.code);
+          codeMap[sm.code] = true;
+        }
+      }
+    }
+    //来自组成物工料机
+    let comMixMap = {};
+    if(comIDs.length > 0){
+      comIDs = _.uniq(comIDs);//去重
+      let comMixList = await complementaryGljLibModel.find({'ID':{'$in':comIDs}}).lean();
+      for(let cm of comMixList){
+        comMixMap[cm.ID] = cm;
+        let ckey = getIndex(cm,['code','name','specs','unit','gljType']);
+        if(!projectGLJMap[ckey] && codeMap[cm.code]){
+          missCodeList.push(cm.code);
+          codeMap[cm.code] = true;
+        } 
+      }
+    }
+  
+
+    //4.生成需要插入组成物表的数据
+    for(let mg of missMixRatioGroup){//整理需要插入组成物列表的数据
+        for(let tc of mg.list){
+          let consumpiton = tc.consumeAmt;
+          //只有标准的工料机的组成物才会有多单价、多组成物消耗量的情况
+          if(mg.from == 'std' && ext && ext.quantityField &&( tc.consumeAmtProperty[ext.quantityField]!= undefined && tc.consumeAmtProperty[ext.quantityField]!=null)){
+              consumpiton = tc.consumeAmtProperty[ext.quantityField];
+          }
+          let mfrom = mg.from == 'std' || tc.isStd?'std':'cpt'; 
+          let tmp = mfrom == 'std'?stdMixMap[tc.ID]:comMixMap[tc.ID];//取出之前库中查到的工料机
+          let mixRatioData = {
+              consumption: consumpiton,
+              glj_id: tmp.ID,
+              unit_price_file_id: unitPriceFileId,
+              connect_key: mg.connect_key,
+              type: tmp.gljType,
+              code: tmp.code,
+              specs:tmp.specs?tmp.specs:"",
+              name:tmp.name,
+              unit:tmp.unit?tmp.unit:'',
+              from:mfrom
+            };
+          mixRatioInsertData.push(mixRatioData);
+        }
+    }
+
+
+    if(mixRatioInsertData.length > 0) await setIDfromCounter("mix_ratio",mixRatioInsertData,existMixRatioMap,'connect_key');
+    //await mixRatioModel.insertMany(mixRatioInsertData);  因为没有事务添加组成物数据要放在添加单价文件数据之后
+     
+
+    //5.查询组成物对应的项目工料机是否存在,如果不存在,生成项目工料机信息
+    let projectGLJList = await projectGLJModel.find({'project_id':projectID,'code':{'$in':missCodeList}}).lean();
+    for(let pg of projectGLJList){
+      let pindex = getIndex(pg);  
+      projectGLJMap[pindex] = pg;
+    }
+
+    let lessMix = [];//组成物表存在,项目工料机不存在的数据
+    let lessMixMap = {};//防止重复添加
+    for(let connect_key in existMixRatioMap){
+      let mixRatios = existMixRatioMap[connect_key]; 
+      for(let m of mixRatios){
+        let mk = getIndex(m);
+        if(!projectGLJMap[mk] && !lessMixMap[mk]){//如果组成物对应的项目工料机不存在
+          let nglj = null;
+          if(m.from == 'std'){//这里有值,说明是刚添加到组成物文件中的数据   
+            nglj = stdMixMap[m.glj_id];
+          }else if(m.from == 'cpt'){//这里有值,说明是刚添加到组成物文件中的数据   
+            nglj = comMixMap[m.glj_id];
+          }    
+          if(nglj){
+            nglj.from = m.from;
+            let np = getProjectGLJNewData(nglj,projectID,ext);
+            newProjectGLJList.push(np);
+            projectGLJMap[mk] = np;
+          }else{//这里没找到,说明是组成物文件里有,但是项目工料机没有的数据
+            lessMix.push(m);
+          }
+          lessMixMap[mk] = true;//只要处理过一次,就不用再重新处理了,机械组成物,比如柴油这些,会出现多次
+        }
+      }
+    }
+
+
+   //6. 组成物文件里有,但是项目工料机没有的数据(共用单价文件等情况产生)    
+    let lessIDList=[];
+    let uniqMap ={};//去重
+    let lessStdMix = [];//防止组成物中改了名称等,但是通过glj_id取出来的是还没改前的原始数据
+    if(lessMix.length > 0){
+      for(let lm of lessMix){
+        let parentglj = projectGLJMap[lm.connect_key];
+        if(!parentglj) throw `含有组成物工料机${lm.connect_key},没有找到,添加定额失败`;
+        if((parentglj.from == "std" || lm.from == "std") && lm.code!="80CCS"){//车船税特殊处理
+          if(!uniqMap[lm.glj_id]){
+            lessIDList.push(lm.glj_id);
+            uniqMap[lm.glj_id] = lm;
+          }
+          lessStdMix.push(lm);
+        }else {//来自组成物的直接设置    
+          lm.from = 'cpt';
+          lm.gljType = lm.type;
+          let t_mg = getProjectGLJNewData(lm,projectID);
+          newProjectGLJList.push(t_mg);
+          projectGLJMap[getIndex(lm)] = t_mg;
+        }
+      }
+    }
+
+    if(lessIDList.length > 0){
+      let less_stds =  await std_glj_lib_gljList_model.find({'ID':{'$in':lessIDList}}).lean();
+      let less_stds_map = {};
+      for(let les of  less_stds){
+        less_stds_map[les.ID] = les;
+      }
+      for(let t_l_m of lessStdMix){
+        let t_nglj = less_stds_map[t_l_m.glj_id];
+        t_nglj.from = 'std';
+        //防止组成物中改了名称等,但是通过glj_id取出来的是还没改前的原始数据
+        t_nglj.name = t_l_m.name;
+        t_nglj.code = t_l_m.code;
+        t_nglj.gljType = t_l_m.type;
+        t_nglj.specs = t_l_m.specs;
+        t_nglj.unit = t_l_m.unit;
+        let t_np = getProjectGLJNewData(t_nglj,projectID,ext);
+        newProjectGLJList.push(t_np);
+        projectGLJMap[getIndex(t_l_m)] = t_np;
+      }
+    }
+
+  }
+  return [existMixRatioMap,mixRatioInsertData,missCodeList]
+
+}
+
+
+function getProjectGLJNewData(tmp,projectId,ext){
+  let gljData = {
+      glj_id: tmp.ID,
+      repositoryId:tmp.repositoryId,
+      project_id: projectId,
+      code: tmp.code,
+      name: tmp.name,
+      specs: tmp.specs?tmp.specs:'',
+      unit: tmp.unit === undefined ? '' : tmp.unit,
+      type: tmp.gljType,
+      adjCoe:tmp.adjCoe,
+      original_code:tmp.code,
+      materialType: tmp.materialType,   //三材类别
+      materialCoe: tmp.materialCoe,
+      base_price: tmp.basePrice,
+      market_price: tmp.basePrice,
+      from:tmp.from?tmp.from:"std"
+  };
+  if(gljData.from == 'std' && ext && ext.priceField &&( tmp.priceProperty[ext.priceField]!= undefined && tmp.priceProperty[ext.priceField]!=null)){
+    basePrice = scMathUtil.roundTo(tmp.priceProperty[ext.priceField],-6);
+    gljData.base_price = basePrice;
+    gljData.market_price = basePrice;
+  }
+  return gljData;
+}
+
+async function setIDfromCounter(name,list,map,keyfield){//map,keyfield
+
+  let update = {$inc: {sequence_value: list.length}};
+  let condition = {_id: name};
+  let options = {new: true};
+
+  // 先查找更新
+  let counter = await counterModel.findOneAndUpdate(condition, update, options);
+  let firstID = counter.sequence_value - (list.length - 1);
+  for(let a of list){
+      a.id = firstID;
+      firstID+=1
+      if(map && keyfield){
+        let key = a[keyfield];
+        map[key]?map[key].push(a):map[key]=[a]
+      }
+  }
+
+}
+
+
+
 async function deleRationSubRecode(projectID,rationID,cleanzmhs=false) {//删除挂在定额下的数据,如工程量明细,定额工料机等
     let delete_query={projectID: projectID, rationID: rationID};
     //删除工程量明细
@@ -680,4 +1083,16 @@ function FilterNumberFromUnit (unit) {
     } else {
         return 1;
     }
-};
+};
+
+function getIndex(obj,tpops){
+  let pops = tpops?tpops:['code','name','specs','unit','type'];
+  let t_index = '';
+  let k_arr=[];
+  for(let p of pops){
+      let tmpK = (obj[p]==undefined||obj[p]==null||obj[p]=='')?'null':obj[p];
+      k_arr.push(tmpK);
+  }
+  t_index=k_arr.join("|-|");
+  return t_index;
+}

+ 2 - 2
public/web/tree_sheet/tree_sheet_controller.js

@@ -202,10 +202,10 @@ var TREE_SHEET_CONTROLLER = {
             }
         };
 
-        controller.prototype.refreshTreeNode = function (nodes, recursive) {
+        controller.prototype.refreshTreeNode = function (nodes, recursive,autoFit) {
             var that = this;
             TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
-                TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, nodes, recursive)
+                TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, nodes, recursive,autoFit)
             })
         };
 

+ 2 - 2
public/web/tree_sheet/tree_sheet_helper.js

@@ -109,7 +109,7 @@ var TREE_SHEET_HELPER = {
             }
         })
     },
-    refreshTreeNodeData: function (setting, sheet, nodes, recursive) {
+    refreshTreeNodeData: function (setting, sheet, nodes, recursive,autoFit=true) {
         nodes.forEach(function (node) {
             let iRow = node.serialNo();
             if(setting.emptyRowHeader){
@@ -206,7 +206,7 @@ var TREE_SHEET_HELPER = {
                     cell.locked(typeof projectReadOnly !== 'undefined' && projectReadOnly ? true : false);
                 }
             });
-            if(setting.setAutoFitRow){
+            if(autoFit==true && setting.setAutoFitRow){
                 setting.setAutoFitRow(sheet,node)//自动行高功能比较费时,400行,启用和不启用相差2秒左右
             }
             if (recursive) {

+ 2 - 1
web/building_saas/main/js/controllers/project_controller.js

@@ -4,7 +4,7 @@
 
 ProjectController = {
     /* sc: tree_sheet_controller */
-    syncDisplayNewNode: function (sc, newNode) {
+    syncDisplayNewNode: function (sc, newNode,callback) {
         TREE_SHEET_HELPER.massOperationSheet(sc.sheet, function () {
             var sels = sc.sheet.getSelections();
             sc.sheet.addRows(newNode.serialNo(), 1);
@@ -14,6 +14,7 @@ ProjectController = {
             //不显示到中间
             //sc.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
             cbTools.refreshFormulaNodes();
+            if(callback) callback();
         });
     },
     syncDisplayNewNodes: function (sc, newNodes,withOutSelect=false) {//withOutSelect 不需要自动选中,外面自已处理

+ 6 - 3
web/building_saas/main/js/models/bills.js

@@ -854,10 +854,13 @@ var Bills = {
                 me.tree.m_delete(idTreeNodes);
                 $.bootstrapLoading.end();
                 //重新计算
-                project.installation_fee.calcInstallationFee(function (isChange) {
-                    project.calcProgram.calcAllNodesAndSave();
-                    if(!isChange) {
+                project.installation_fee.calcInstallationFee(function (isChange,nodes) {
+                    if(nodes && nodes.length > 0)parentNodes = parentNodes.concat(nodes);
+                    project.calcProgram.calcNodesAndSave(parentNodes);
+                    if(isChange) {
                         project.projectGLJ.loadData();
+                    }else{
+                      project.projectGLJ.calcQuantity();
                     }
                     gljOprObj.refreshView();
                 });

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

@@ -332,7 +332,7 @@ let cbTools = {
     refreshFormulaNodes: function () {
         try {
             let nodes = this.getFormulaNodes();
-            if (nodes.length > 0) projectObj.mainController.refreshTreeNode(nodes);
+            if (nodes.length > 0) projectObj.mainController.refreshTreeNode(nodes,false,false);
         } catch (err) {
             alert('公式引用行号显示刷新失败:' + err.message);
         }

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

@@ -2097,7 +2097,7 @@ class CalcProgram {
             };
 
             for (let node of treeNodes) { delete node.changed };
-            projectObj.mainController.refreshTreeNode(treeNodes);
+            projectObj.mainController.refreshTreeNode(treeNodes,false,false);
 
             // 批量树结点计算后,计算程序早已物是人非,所以这里要重新计算一下。警告:第二个参数千万不能改成3,否则死循环!
             if (activeSubSheetIsCalcProgram())

+ 4 - 3
web/building_saas/main/js/models/ration.js

@@ -673,9 +673,10 @@ var Ration = {
                 newNode.source = newSource;
                 newNode.sourceType = project.Ration.getSourceType();
                 newNode.data = newSource;
-                ProjectController.syncDisplayNewNode(sheetController, newNode);
-                project.ration_glj.addToMainTree(data.ration_gljs);
-                projectObj.mainController.refreshTreeNode([newNode], false);
+                ProjectController.syncDisplayNewNode(sheetController, newNode,function(){
+                  project.ration_glj.addToMainTree(data.ration_gljs);
+                  projectObj.mainController.refreshTreeNode([newNode], false);
+                });
             }
 
 

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

@@ -98,8 +98,6 @@ var ration_coe = {
                 criteria.ration_coe_list.push(newCoe);
             }
             criteria.updateType = 'ut_create';
-            console.log('enterrrrrrrrrrrrrrrrrrrrrr');
-            console.log(criteria);
             return criteria;
         };
         ration_coe.prototype.getCustomerCoeData = function () {

+ 47 - 46
web/building_saas/main/js/views/glj_view.js

@@ -539,49 +539,54 @@ var gljOprObj = {
         }
     },
     showDataIfRationSelect: function (node,selectedNodeId) {
-        var isShow = false;
-        if(projectReadOnly && this.setting.view.lockColumns){
-            this.setting.view.lockColumns = null;
-        }
-        if(selectedNodeId){
-            this.selectedNodeId = selectedNodeId;
-        }
-        if (node) {
-            if (this.selectedNodeId && this.selectedNodeId == node.getID()) {
-                return;
-            } else {
-                //恢复底色
-                this.sheet.setStyle(this.sheet.getActiveRowIndex(), -1, this.getSelStyle(false,this.setting.style));
-                this.selectedNodeId = node.getID();
-            }
-            if (node.sourceType == "ration") {
-                if(node.data.type==rationType.gljRation){
-                    if($('#linkGLJ').hasClass('active'))  this.showMixRatio(node);
-                }else {
-                    if($('#linkGLJ').hasClass('active')){
-                        this.showRationGLJData(node);
-                        subObj.showGljSubTabData();
-                       // MaterialController.showReplaceDiv(node);
-                    }
-                    if($('#linkAZZJF').hasClass('active')) installationFeeObj.showRationInstallationData(node);
-                    if($('#linkMBZM').hasClass('active')) mbzm_obj.showMBZMData(node);
-                }
-                isShow = true;
-            }
-            if(node.sourceType == ModuleNames.ration_glj){
-                if($('#linkGLJ').hasClass('active')) this.showMixRatio(node);
-                MaterialController.hideReplaceDiv();
-                isShow = true;
-            }
-            if($('#linkGCLMX').hasClass('active')) this.showQuantityDetailData(node);
+      this.sheet.suspendPaint();
+      this.sheet.suspendEvent();
+      var isShow = false;
+      if(projectReadOnly && this.setting.view.lockColumns){
+          this.setting.view.lockColumns = null;
+      }
+      if(selectedNodeId){
+          this.selectedNodeId = selectedNodeId;
+      }
+      if (node) {
+          if (this.selectedNodeId && this.selectedNodeId == node.getID()) {
+              return;
+          } else {
+              //恢复底色
+              this.sheet.setStyle(this.sheet.getActiveRowIndex(), -1, this.getSelStyle(false,this.setting.style));
+              this.selectedNodeId = node.getID();
+          }
+          if (node.sourceType == "ration") {
+              if(node.data.type==rationType.gljRation){
+                  if($('#linkGLJ').hasClass('active'))  this.showMixRatio(node);
+              }else {
+                  if($('#linkGLJ').hasClass('active')){
+                      this.showRationGLJData(node);
+                      subObj.showGljSubTabData();
+                      // MaterialController.showReplaceDiv(node);
+                  }
+                  if($('#linkAZZJF').hasClass('active')) installationFeeObj.showRationInstallationData(node);
+                  if($('#linkMBZM').hasClass('active')) mbzm_obj.showMBZMData(node);
+              }
+              isShow = true;
+          }
+          if(node.sourceType == ModuleNames.ration_glj){
+              if($('#linkGLJ').hasClass('active')) this.showMixRatio(node);
+              MaterialController.hideReplaceDiv();
+              isShow = true;
+          }
+          if($('#linkGCLMX').hasClass('active')) this.showQuantityDetailData(node);
+
+      } else {
+          this.selectedNodeId = null;
+      }
+      if (!isShow) {
+          this.clearSheetData();
+          MaterialController.hideReplaceDiv();
+      }
+      this.sheet.resumeEvent();
+      this.sheet.resumePaint();
 
-        } else {
-            this.selectedNodeId = null;
-        }
-        if (!isShow) {
-            this.clearSheetData();
-            MaterialController.hideReplaceDiv();
-        }
         //子目换算
         //zmhs_obj.showZMHSData(node);
         //   $('#dropdown').hide();
@@ -680,8 +685,6 @@ var gljOprObj = {
         return codeMap;
     },
     initRationTree: function (init,codeMap) {
-        this.sheet.suspendPaint();
-        this.sheet.suspendEvent();
         this.sheet.setRowCount(this.sheetData.length >30?this.sheetData.length:30);
         for (var i = 0; i < this.sheetData.length; i++) {
             let options = this.getCodeOptions(this.sheetData[i],codeMap);
@@ -693,8 +696,6 @@ var gljOprObj = {
                 }
             }
         }
-        this.sheet.resumeEvent();
-        this.sheet.resumePaint();
     },
     getCodeOptions:function (recode,codeMap) {
         let options = [];

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

@@ -252,13 +252,15 @@ var projectObj = {
     setActiveCell(field, moveScroll){
         projectObj.mainSpread.focus(true);
         let mainSheet = projectObj.mainSpread.getActiveSheet();
-        let fieldCol = colSettingObj.getColByField(field);
-        if(fieldCol){
-            if(moveScroll){
-                mainSheet.showColumn(fieldCol, GC.Spread.Sheets.HorizontalPosition.center);
-            }
-            mainSheet.setActiveCell(projectObj.project.mainTree.selected.serialNo(), fieldCol);
-        }
+        TREE_SHEET_HELPER.massOperationSheet(mainSheet,function(){
+          let fieldCol = colSettingObj.getColByField(field);
+          if(fieldCol){
+              if(moveScroll){
+                  mainSheet.showColumn(fieldCol, GC.Spread.Sheets.HorizontalPosition.center);
+              }
+              mainSheet.setActiveCell(projectObj.project.mainTree.selected.serialNo(), fieldCol);
+          }
+        });
     },
     //获取粘贴更改的单元格(粘贴时,跳过隐藏行)
     checkSpreadChangedCells: function (info) {

+ 4 - 4
web/building_saas/main/js/views/zmhs_view.js

@@ -119,6 +119,8 @@ let zmhs_obj = {
         let selected = node?node:projectObj.project.mainTree.selected;
         let ration_coe = projectObj.project.ration_coe;
         let coeList = [];
+        this.coeSheet.suspendPaint();
+        this.coeSheet.suspendEvent();
         if(selected&&selected.sourceType == "ration"){
             let ration = selected.data;
             let assList = this.getAssList(node); //2019-01-23 新需求,将辅助定额合并到一个表显示  -- 20191206 辅助定额放前面
@@ -130,8 +132,6 @@ let zmhs_obj = {
         this.coeSheet.setRowCount(0);
         sheetCommonObj.showData(this.coeSheet, this.coeSetting,coeList);
         if (coeList.length > 0) {
-            this.coeSheet.suspendPaint();
-            this.coeSheet.suspendEvent();
             for(let i =0;i<coeList.length;i++ ){
                 if(gljUtil.isDef(coeList[i].option_codes)&&coeList[i].option_codes!=""){
                     this.getComboBoxForCodes(coeList[i],i);//设置可选类型的下拉框
@@ -143,8 +143,6 @@ let zmhs_obj = {
                     this.coeSheet.setCellType(i, 1, sheetCommonObj.getCustomerCoeCellType(this.generateHtmlString,this.bindCusEditorValue,this.updateCusCoeAfterEditor), GC.Spread.Sheets.SheetArea.viewport);
                 }
             }
-            this.coeSheet.resumeEvent();
-            this.coeSheet.resumePaint();
         }
         this.coeSheetData = coeList;
         if(projectReadOnly){
@@ -153,6 +151,8 @@ let zmhs_obj = {
         if(preSelections){//定位光标到之前的位置
             this.coeSheet.setSelection(preSelections[0].row,preSelections[0].col,preSelections[0].rowCount,preSelections[0].colCount);
         }
+        this.coeSheet.resumeEvent();
+        this.coeSheet.resumePaint();
     },
     showCusData:function (node) {
         let selected = node?node:projectObj.project.mainTree.selected;