ration_facade.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. /**
  2. * Created by zhang on 2018/2/9.
  3. */
  4. //先导出后require可以解决循环引用问题
  5. module.exports = {
  6. replaceRations: replaceRations,
  7. addNewRation:addNewRation,
  8. addMultiRation: addMultiRation,
  9. deleteMultiRation:deleteMultiRation,
  10. getSameSectionRations:getSameSectionRations,
  11. getExtendData:getExtendData,
  12. getDefaultProgramID:getDefaultProgramID,
  13. deleteSubListByQuery:deleteSubListByQuery,
  14. updateCoeAdjust:updateCoeAdjust
  15. };
  16. let mongoose = require('mongoose');
  17. import SearchDao from '../../complementary_ration_lib/models/searchModel';
  18. const scMathUtil = require('../../../public/scMathUtil').getUtil();
  19. let ration_glj_facade = require("../../ration_glj/facade/ration_glj_facade");
  20. let glj_calculate_facade = require("../../ration_glj/facade/glj_calculate_facade");
  21. let quantity_detail = require("../facade/quantity_detail_facade");
  22. let ration_glj = mongoose.model('ration_glj');
  23. let ration_coe = mongoose.model('ration_coe');
  24. let ration_model = require('../models/ration');
  25. let bill_model = require('../models/bills');
  26. let decimal_facade = require('./decimal_facade');
  27. let installationFeeModel = mongoose.model("installation_fee");
  28. let rationInstallationModel = mongoose.model('ration_installation');
  29. let rationTemplateModel = mongoose.model('ration_template');
  30. const uuidV1 = require('uuid/v1');
  31. let std_glj_lib_gljList_model = mongoose.model('std_glj_lib_gljList');
  32. let complementary_glj_model = mongoose.model('complementary_glj_lib');
  33. let rationItemModel = mongoose.model("std_ration_lib_ration_items");
  34. let complementaryRationModel = mongoose.model('complementary_ration_items');
  35. let coeMolde = mongoose.model('std_ration_lib_coe_list');
  36. let compleCoeModel = mongoose.model('complementary_ration_coe_list');
  37. let _= require('lodash');
  38. const projectDao = require('../../pm/models/project_model').project;
  39. let projectModel = mongoose.model('projects');
  40. const fs = require('fs');
  41. async function addNewRation(data,compilation) {
  42. let query = data.itemQuery;
  43. let stdRation = null;
  44. let startTime = +new Date();
  45. if(query){
  46. let searchDao = new SearchDao();
  47. stdRation = await searchDao.getRationItem(query.userID, compilation._id, [query.rationRepId],query.code, query.ID);
  48. //data.newData.code = query.code;
  49. }
  50. let stdRationTime = +new Date();
  51. console.log("取std定额时间-------------------------------"+(stdRationTime - startTime));
  52. if(data.brUpdate.length>0){
  53. await updateSerialNo(data.brUpdate);
  54. }
  55. let newRation =await insertNewRation(data.newData,data.defaultLibID,stdRation,data.calQuantity);
  56. let addRationGLJTime = +new Date();
  57. console.log("插入新定额时间-------------------------------"+(addRationGLJTime - stdRationTime));
  58. if(stdRation){
  59. return await addRationSubList(stdRation,newRation,data.needInstall,compilation);
  60. }else {
  61. return {ration:newRation};
  62. }
  63. }
  64. async function addMultiRation(datas,compilation) {
  65. let rst = [];
  66. for(let data of datas){
  67. let r = await addNewRation(data,compilation);
  68. rst.push(r);
  69. }
  70. return rst;
  71. }
  72. async function deleteMultiRation(rations) {//这里是只有删除的情况,删除定额的同时删除定额下挂的其它子项目
  73. if(rations.length > 0){//删除定额下的
  74. let rationIDS = _.map(rations,'ID');
  75. await deleteSubListByQuery({projectID:rations[0].projectID,rationID:{"$in": rationIDS}});
  76. await ration_model.model.deleteMany({ID:{"$in": rationIDS}});
  77. }
  78. }
  79. async function getSameSectionRations(data,userId,compilationId){
  80. //let userId
  81. //要先根据定额获取所属章节的ID
  82. let from = data.from; //定额类型,是标准的还是用户定义的
  83. let code = data.code;
  84. let libID = data.libID;
  85. let sectionId,rations=[];
  86. if(from == 'std'){
  87. let ration = await rationItemModel.findOne({rationRepId:libID,code:code},['sectionId']);
  88. sectionId = ration? ration.sectionId:null;
  89. }else {
  90. let ration = await complementaryRationModel.findOne({userId:userId,compilationId: compilationId,code:code},['sectionId']);
  91. sectionId = ration?ration.sectionId:null;
  92. }
  93. if(sectionId){
  94. if (from == 'std') {
  95. rations = await rationItemModel.find({sectionId: sectionId});
  96. } else {
  97. rations = await complementaryRationModel.find({userId: userId, sectionId: sectionId});
  98. }
  99. rations = _.sortBy(rations,'code');
  100. }
  101. return rations
  102. }
  103. async function updateSerialNo(serialNoUpdate){
  104. let tasks=[];
  105. for(let data of serialNoUpdate){
  106. let task={
  107. updateOne:{
  108. filter:{
  109. ID:data.ID,
  110. projectID:data.projectID
  111. },
  112. update :{
  113. serialNo:data.serialNo
  114. }
  115. }
  116. };
  117. tasks.push(task);
  118. }
  119. await ration_model.model.bulkWrite(tasks);
  120. }
  121. async function insertNewRation(newData,defaultLibID,std,calQuantity) {//插入新的定额
  122. let startTime = +new Date();
  123. if(std){
  124. newData.code = std.code;
  125. newData.name = std.name;
  126. newData.caption = std.caption;
  127. newData.unit = std.unit;
  128. newData.libID = std.rationRepId;
  129. newData.stdID = std.ID;
  130. newData.content = std.jobContent;
  131. newData.annotation = std.annotation;
  132. if (std.chapter) {
  133. newData.comments = std.chapter.explanation;
  134. newData.ruleText = std.chapter.ruleText;
  135. }
  136. newData.prefix = '';
  137. newData.from = std.type === 'complementary' ? 'cpt' : 'std';
  138. if(defaultLibID !== std.rationRepId){//定额是默认定额库中的时,只显示编号;
  139. newData.prefix = '借';//定额不是默认定额库中的、且不是补充定额库中的时, 在定额编号前显示“借”。
  140. if(newData.from === 'cpt') newData.prefix = '补';//定额是补充定额库中的时,在定额编号前显示“补”;
  141. }
  142. if(std.feeType == undefined || std.feeType == null || std.feeType ==''){//定额取费专业为空的情况下,取项目属性中的定额取费专业ID
  143. newData.programID = await getProgramForProject(newData.projectID);
  144. }else {
  145. newData.programID = std.feeType;
  146. }
  147. newData.manageFeeRate = std.manageFeeRate;
  148. newData.rationAssList = createRationAss(std);
  149. // calculate ration Quantity
  150. }
  151. if(calQuantity){
  152. await CalculateQuantity(newData,newData.billsItemID,newData.projectID);
  153. }
  154. let addRationGLJTime = +new Date();
  155. console.log("计算消耗量时间-------------------------------"+(addRationGLJTime - startTime));
  156. let newRation = await ration_model.model.create(newData);
  157. return newRation;
  158. /*ration_model.model.create(newData);
  159. return newData;*/
  160. }
  161. async function replaceRations(userID,data,compilation) {
  162. let searchDao = new SearchDao();
  163. let recodes = [];
  164. for(let recode of data.nodeInfo){
  165. let stdRation = await searchDao.getRationItem(userID,compilation._id,data.libIDs,recode.newCode, null);
  166. let newRecode = await replaceRation(recode,stdRation,data.defaultLibID,data.projectID,data.calQuantity,compilation,data.cleanzmhs);
  167. if(newRecode){
  168. recodes.push(newRecode);
  169. }else {
  170. break;
  171. }
  172. }
  173. return recodes;
  174. }
  175. async function getDefaultProgramID(data) {
  176. let searchDao = new SearchDao();
  177. let programID;
  178. let std = await searchDao.getRationItem(data.userID,data.compilationId,[data.libID],data.code, null);
  179. if(std == null||std ==undefined || std.feeType == undefined || std.feeType == null || std.feeType ==''){//定额取费专业为空的情况下,取项目属性中的定额取费专业ID
  180. programID = await getProgramForProject(data.projectID);
  181. }else {
  182. programID = std.feeType;
  183. }
  184. return programID;
  185. }
  186. async function replaceRation(nodeInfo,stdRation,defaultLibID,projectID,calQuantity,compilation,cleanzmhs) {
  187. if(nodeInfo.newCode == null||nodeInfo.newCode ==""){//说明是删除编号,则要变成一条空定额
  188. await deleRationSubRecode(projectID,nodeInfo.ID);//删除定额下挂的各种数据,如定额工料机等
  189. return await setEmptyRation(projectID,nodeInfo.ID);
  190. }else if(stdRation){
  191. await deleRationSubRecode(projectID,nodeInfo.ID,cleanzmhs);//删除定额下挂的各种数据,如定额工料机等
  192. let newRation = await updateRation(stdRation,defaultLibID,nodeInfo.ID,nodeInfo.billsItemID,projectID,calQuantity,cleanzmhs);//生成并插入新的定额
  193. return await addRationSubList(stdRation,newRation,nodeInfo.needInstall,compilation,cleanzmhs);
  194. }else {
  195. return null;
  196. }
  197. }
  198. async function addRationSubList(stdRation,newRation,needInstall,compilation,cleanzmhs=false) {
  199. let startTime = +new Date();
  200. let [ration_gljs,projectGLJList] = await addRationGLJ(stdRation,newRation,compilation);
  201. let addRationGLJTime = +new Date();
  202. console.log("添加定额工料机时间-----"+(addRationGLJTime - startTime));
  203. let ration_coes = await addRationCoe(stdRation,newRation,compilation);
  204. let addRationCoeTime = +new Date();
  205. console.log("添加定额coe时间-----"+(addRationCoeTime - addRationGLJTime));
  206. let ration_installations = [];
  207. let ration_template = [];
  208. if(cleanzmhs == false){//清除子目换算即cleanzmh==true时 模板子目、安装增加费不用恢复成标准的
  209. if(needInstall && stdRation.type == 'std'){//只有标准的定额才有安装增加费,补充的定额没有安装增加费
  210. ration_installations = await addRationInstallFee(stdRation,newRation);
  211. }
  212. let addRationInstallFeeTime = +new Date();
  213. console.log("添加定额install时间-----"+(addRationInstallFeeTime - addRationCoeTime));
  214. //添加定额模板子目
  215. ration_template = await addRationTemplate(stdRation,newRation);
  216. }else if(newRation.areaIncreaseFee == true){//清空子目换算时,如果有面积增加费,子目调整状态要生成
  217. let t = await glj_calculate_facade.calculateQuantity({rationID:newRation.ID},true);
  218. newRation.adjustState = t.adjustState;
  219. }
  220. return {ration:newRation,ration_gljs:ration_gljs,ration_coes:ration_coes,ration_installations:ration_installations,ration_templates:ration_template?[ration_template]:[],projectGLJList:projectGLJList};
  221. }
  222. async function addRationInstallFee(std,newRation) {
  223. let install_fee_list = [];
  224. if(std.hasOwnProperty('rationInstList') && std.rationInstList.length > 0){
  225. let installFee = await installationFeeModel.findOne({'projectID': newRation.projectID});
  226. if(!installFee) return;//如果没有找到项目对应的安装增加费,则不添加
  227. for(let ri of std.rationInstList){
  228. let feeItem = _.find(installFee.installFeeItem,{'ID':ri.feeItemId});
  229. let section = _.find(installFee.installSection,{'ID':ri.sectionId});
  230. if(feeItem&&section){
  231. let tem_r_i = {
  232. libID:installFee.libID,
  233. projectID:newRation.projectID,
  234. rationID:newRation.ID,
  235. feeItemId:feeItem.ID,
  236. sectionId:section.ID,
  237. itemName:feeItem.feeItem,
  238. feeType:feeItem.feeType,
  239. sectionName:section.name,
  240. unifiedSetting:1,
  241. ruleId:''
  242. };
  243. if(feeItem.isCal==1&&section.feeRuleId&&section.feeRuleId!=''){//勾选记取时并且有规则ID时才读取
  244. let feeRule = _.find(installFee.feeRule,{'ID':section.feeRuleId});
  245. if(feeRule){
  246. tem_r_i.ruleId = feeRule.ID;
  247. }
  248. }
  249. tem_r_i.ID = uuidV1();
  250. install_fee_list.push(tem_r_i);
  251. }
  252. }
  253. if(install_fee_list.length>0){
  254. await rationInstallationModel.insertMany(install_fee_list);
  255. }
  256. }
  257. return install_fee_list;
  258. }
  259. async function addRationTemplate(std,newRation) {
  260. let templateList = [];
  261. if(std.hasOwnProperty('rationTemplateList') && std.rationTemplateList.length > 0){
  262. for(let tem of std.rationTemplateList){
  263. let re_ration = await rationItemModel.findOne({rationRepId:std.rationRepId,ID:tem.rationID});
  264. if(re_ration){
  265. let template = {
  266. billID:"",
  267. fxID:"",
  268. quantity:"0",
  269. coe:"0"
  270. };
  271. template.code = re_ration.code;
  272. template.name = re_ration.name;
  273. template.type = tem.type;
  274. template.unit = re_ration.unit;
  275. template.billsLocation = tem.billsLocation;
  276. template.defaultLocation = tem.billsLocation;
  277. templateList.push(template)
  278. }
  279. }
  280. }
  281. if(templateList.length > 0){
  282. let ration_template = {};
  283. ration_template.ID = uuidV1();
  284. ration_template.projectID = newRation.projectID;
  285. ration_template.rationID = newRation.ID;
  286. ration_template.createLocation = 1; //默认模板子目分别放在措施项目下
  287. ration_template.templateList = templateList;
  288. await rationTemplateModel.create(ration_template);
  289. return ration_template;
  290. }
  291. return null;
  292. }
  293. async function addRationCoe(std,newRation,compilation) {
  294. let ration_coe_list = [];
  295. let seq = 0;
  296. if(std.hasOwnProperty('rationCoeList')&&std.rationCoeList.length>0){//添加标准库的工料机
  297. for(let sub of std.rationCoeList){
  298. let libCoe;
  299. if (std.type === 'std') {
  300. libCoe = await coeMolde.findOne({'libID':std.rationRepId,'ID':sub.ID,"$or": [{"isDeleted": null}, {"isDeleted": false}]});//std.rationRepId;
  301. } else {
  302. libCoe = await compleCoeModel.findOne({ID: sub.ID, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]});
  303. }
  304. if(libCoe){
  305. let newCoe = {};
  306. newCoe.ID = uuidV1();
  307. newCoe.coeID = sub.ID;
  308. newCoe.seq = seq;
  309. newCoe.name = libCoe.name;
  310. newCoe.content = libCoe.content;
  311. newCoe.original_code = libCoe.original_code;
  312. newCoe.option_codes = libCoe.option_codes;
  313. newCoe.option_list = libCoe.option_list;
  314. newCoe.isAdjust=0;
  315. newCoe.coes = libCoe.coes;
  316. newCoe.rationID = newRation.ID;
  317. newCoe.projectID = newRation.projectID;
  318. seq++;
  319. ration_coe_list.push(newCoe);
  320. }
  321. }
  322. }
  323. let lastCoe = await getCustomerCoe(newRation.projectID,newRation.ID,seq,compilation);
  324. ration_coe_list.push(lastCoe);
  325. await ration_coe.insertMany(ration_coe_list);
  326. return ration_coe_list;
  327. }
  328. function getCustomerCoeData() {
  329. var coeList = [
  330. {amount:1, operator:'*', gljCode:null, coeType:'定额'},
  331. { amount:1, operator:'*', gljCode:null, coeType:'人工'},
  332. { amount:1, operator:'*', gljCode:null, coeType:'材料'},
  333. { amount:1, operator:'*', gljCode:null, coeType:'机械'},
  334. { amount:1, operator:'*', gljCode:null, coeType:'主材'},
  335. { amount:1, operator:'*', gljCode:null, coeType:'设备'}
  336. ];
  337. return coeList;
  338. };
  339. async function getCustomerCoe(projectID,rationID,seq,compilation){//取自定义乘系数,根据编办不同,内容可能不同
  340. //生成默认的自定义乘系数
  341. let lastCoe ={
  342. coeID:-1,
  343. name : '自定义系数',
  344. content:'人工×1,材料×1,机械×1,主材×1,设备×1',
  345. isAdjust:1,
  346. seq:seq,
  347. rationID : rationID,
  348. projectID : projectID
  349. };
  350. lastCoe.ID = uuidV1();
  351. lastCoe.coes = getCustomerCoeData();
  352. try {
  353. //查看编办中有没有重写路径
  354. if(compilation.overWriteUrl && compilation.overWriteUrl!=""){
  355. let overWrite = require("../../.."+compilation.overWriteUrl);
  356. if(overWrite.getCusCoeContent) lastCoe.content = overWrite.getCusCoeContent();
  357. if(overWrite.getCustomerCoeData) lastCoe.coes = overWrite.getCustomerCoeData();
  358. }
  359. return lastCoe
  360. }catch (err){
  361. console.log("读取自定义系数重写文件失败");
  362. console.log(err.message);
  363. return lastCoe
  364. }
  365. }
  366. //对于多单价,多组成物消耗量的编办,通过这个方法获取单价、组成物消耗量的字段,
  367. function getExtendData(property,compilation) {
  368. return projectDao.getExtendData(property,compilation);
  369. }
  370. async function addRationGLJ(std,newRation,compilation) {
  371. let newRationGLJList = [];
  372. let rationGLJShowList = [];
  373. let projectGLJList = [];
  374. let unitPriceFileId = 0;
  375. let property = await projectDao.getProjectProperty(newRation.projectID);
  376. if(property){
  377. unitPriceFileId = property.unitPriceFile !== undefined ? property.unitPriceFile.id : 0;
  378. }
  379. let ext = getExtendData(property,compilation);
  380. let first = +new Date();
  381. if(std.hasOwnProperty('rationGljList') && std.rationGljList.length > 0){
  382. let stdGLJID =[];//标准工料机ID数组
  383. let cptGLJID=[];//补充工料机ID数组
  384. //let stdGLJID = _.map(std.rationGljList,'gljId');
  385. for(let tem_g of std.rationGljList){
  386. if(tem_g.type == 'complementary'){
  387. cptGLJID.push(tem_g.gljId);
  388. }else {
  389. stdGLJID.push(tem_g.gljId);
  390. }
  391. }
  392. let stdGLJList = stdGLJID.length > 0 ? await std_glj_lib_gljList_model.find({'ID':{'$in':stdGLJID}}):[];//速度优化-------先一次性取出所有的工料机列表
  393. let stdGLJMap = _.indexBy(stdGLJList, 'ID');
  394. let cptGLJList = cptGLJID.length > 0 ? await complementary_glj_model.find({'userId':std.userId,'ID':{'$in':cptGLJID}}):[];
  395. let cptGLJMap = _.indexBy(cptGLJList, 'ID');
  396. let stdGLJMapTime = +new Date();
  397. console.log("找到工料机映射表时间-------------------------------"+(stdGLJMapTime - first));
  398. for(let sub of std.rationGljList){
  399. let newGLJ = {};
  400. newGLJ.ID = uuidV1();
  401. newGLJ.projectID = newRation.projectID;
  402. newGLJ.GLJID = sub.gljId;
  403. newGLJ.rationID = newRation.ID;
  404. newGLJ.billsItemID = newRation.billsItemID;
  405. newGLJ.rationItemQuantity = sub.consumeAmt;
  406. newGLJ.quantity = sub.consumeAmt;
  407. newGLJ.glj_repository_id = std.rationRepId;
  408. let std_glj = null;
  409. if(sub.type == 'complementary'){//有可能来自标准工料机库或补充工料机库
  410. std_glj = cptGLJMap[sub.gljId];
  411. newGLJ.from = 'cpt';
  412. }else {
  413. std_glj = stdGLJMap[sub.gljId];
  414. newGLJ.from = 'std';
  415. //多单价情况处理
  416. if(ext && ext.priceField && std_glj && std_glj.priceProperty){
  417. std_glj.basePrice = std_glj.priceProperty[ext.priceField];
  418. }
  419. }
  420. if(std_glj){
  421. newGLJ.name = std_glj.name;
  422. newGLJ.code = std_glj.code;
  423. newGLJ.original_code = std_glj.code;
  424. newGLJ.unit = std_glj.unit;
  425. newGLJ.specs = std_glj.specs;
  426. newGLJ.model = std_glj.model;
  427. newGLJ.basePrice = std_glj.basePrice;
  428. newGLJ.marketPrice = std_glj.basePrice;
  429. newGLJ.shortName = std_glj.shortName;
  430. newGLJ.type = std_glj.gljType;
  431. newGLJ.repositoryId = std_glj.repositoryId;
  432. newGLJ.adjCoe = std_glj.adjCoe;
  433. newGLJ.materialType = std_glj.materialType;
  434. newGLJ.materialCoe = std_glj.materialCoe;
  435. newGLJ.materialIndexType = std_glj.materialIndexType;
  436. newGLJ.materialIndexUnit = std_glj.materialIndexUnit;
  437. newGLJ.materialIndexCoe = std_glj.materialIndexCoe;
  438. newGLJ.createType = 'normal';
  439. let [info,projectGLJ] = await ration_glj_facade.getInfoFromProjectGLJ(newGLJ,unitPriceFileId,ext);
  440. newGLJ = ration_glj_facade.createNewRecord(info);
  441. newRationGLJList.push(newGLJ);
  442. rationGLJShowList.push(info);
  443. projectGLJList.push(projectGLJ)
  444. }
  445. //let InfoFromProjectGLJ = +new Date();
  446. //console.log("找到项目工料机时间-------------------------------"+(InfoFromProjectGLJ - std_gljTime));
  447. }
  448. }
  449. let before = +new Date();
  450. console.log("总查询时间为-------------------------------"+(before-first));
  451. if(newRationGLJList.length>0){
  452. await ration_glj.insertMany(newRationGLJList);
  453. }
  454. let after = +new Date();
  455. console.log("实际插入时间为-------------------------------"+(after-before));
  456. console.log("总操作时间为-------------------------------"+(after-first));
  457. return [rationGLJShowList,projectGLJList]
  458. }
  459. async function deleRationSubRecode(projectID,rationID,cleanzmhs=false) {//删除挂在定额下的数据,如工程量明细,定额工料机等
  460. let delete_query={projectID: projectID, rationID: rationID};
  461. //删除工程量明细
  462. await deleteSubListByQuery(delete_query,cleanzmhs) ;
  463. }
  464. async function deleteSubListByQuery(delete_query,cleanzmhs=false) {
  465. if(cleanzmhs == false){//清空子目换算即cleanzmh==true时不需要清空工程量明细、模板关联子目、安装增加费
  466. await quantity_detail.deleteByQuery(delete_query) ;//删除工程量明细
  467. await rationInstallationModel.deleteMany(delete_query);//删除安装增加费
  468. await rationTemplateModel.deleteMany(delete_query);//删除模板关联子目
  469. }
  470. //to do稳定土也要删除
  471. await ration_coe.deleteMany(delete_query);//删除附注条件
  472. await ration_glj.deleteMany(delete_query);//删除定额工料机
  473. }
  474. async function updateCoeAdjust(data,compilation) {
  475. let replace = [];
  476. await ration_coe.update({ID:data.ID},data.doc);
  477. //添加单个工料机的情况
  478. if (data.add.length > 0) await ration_glj_facade.insertAddTypeGLJ(data.add,compilation);
  479. if(data.delete.length > 0) await ration_glj_facade.deleteGLJ(data.delete);
  480. //替换工料机的情况
  481. if (data.replace.length > 0){
  482. for(let r of data.replace){
  483. replace.push(await ration_glj_facade.replaceGLJByData(r,compilation)) ;
  484. }
  485. }
  486. let cal_result = await glj_calculate_facade.calculateQuantity({projectID:data.projectID,rationID:data.rationID},null,true);
  487. let coe = {
  488. query:{ID:data.ID,projectID:data.projectID},
  489. doc:data.doc
  490. };
  491. let ration_glj ={
  492. quantityRefresh:true,
  493. glj_result:cal_result.glj_result
  494. };
  495. let ration = {
  496. ID:cal_result.rationID,
  497. adjustState:cal_result.adjustState,
  498. name:cal_result.rationName
  499. };
  500. return {coe:coe,ration_glj:ration_glj,ration:ration,add:data.add,delete:data.delete,replace:replace}
  501. }
  502. async function updateRation(std,defaultLibID,rationID,billsItemID,projectID,calQuantity,cleanzmh=false) {
  503. // insertNewRation
  504. let ration ={};
  505. ration.code = std.code;
  506. ration.name = std.name;
  507. ration.caption = std.caption;
  508. ration.unit = std.unit;
  509. if (std.type === 'std') {
  510. ration.libID = std.rationRepId;
  511. ration.stdID = std.ID;
  512. }
  513. ration.content = std.jobContent;
  514. ration.manageFeeRate = std.manageFeeRate;
  515. ration.adjustState = '';
  516. ration.isFromDetail=0;
  517. ration.isSubcontract=false;
  518. ration.fees=[];
  519. if (std.chapter) {
  520. ration.comments = std.chapter.explanation;
  521. ration.ruleText = std.chapter.ruleText;
  522. }
  523. ration.from = std.type === 'complementary' ? 'cpt' : 'std';
  524. //定额前缀 none:0, complementary:1, borrow: 2
  525. ration.prefix = '';
  526. if(parseInt(defaultLibID) !== std.rationRepId){//定额是默认定额库中的时,只显示编号;
  527. ration.prefix = '借';//定额不是默认定额库中的、且不是补充定额库中的时, 在定额编号前显示“借”。
  528. if(ration.from === 'cpt') ration.prefix = '补';//定额是补充定额库中的时,在定额编号前显示“补”;
  529. }
  530. ration.rationAssList = createRationAss(std);//生成辅助定额
  531. if(cleanzmh==false){//如果是清空子目换算,即cleanzmh==true 保留定额工程量、工程量表达式、含量(分解系数)、取费专业(取费类别)
  532. if(std.feeType == undefined || std.feeType == null || std.feeType ==''){//定额取费专业为空的情况下,取项目属性中的定额取费专业ID
  533. ration.programID = await getProgramForProject(projectID);
  534. }else {
  535. ration.programID = std.feeType;
  536. }
  537. if(calQuantity){
  538. await CalculateQuantity(ration,billsItemID,projectID);
  539. }
  540. }
  541. let unsetObject = {
  542. "marketUnitFee":1,
  543. 'marketTotalFee':1,
  544. "maskName":1
  545. };
  546. let newRation = await ration_model.model.findOneAndUpdate({ID:rationID,projectID:projectID},{"$set":ration,"$unset":unsetObject},{new: true});//;
  547. return newRation;
  548. }
  549. async function setEmptyRation(projectID,rationID){
  550. let ration ={};
  551. ration.code = "";
  552. ration.name = "";
  553. ration.caption = "";
  554. ration.unit = "";
  555. ration.libID = null;
  556. ration.content = "";
  557. ration.adjustState = '';
  558. ration.isFromDetail=0;
  559. ration.isSubcontract=false;
  560. ration.fees=[];
  561. ration.comments = "";
  562. ration.ruleText = "";
  563. ration.quantity="";
  564. ration.contain="";
  565. ration.quantityEXP="";
  566. ration.from = 'std';
  567. //定额前缀 none:0, complementary:1, borrow: 2
  568. ration.prefix = '';
  569. ration.rationAssList = [];
  570. ration.marketUnitFee ="";
  571. ration.marketTotalFee ="";
  572. ration.maskName = "";
  573. ration.targetTotalFee ='';
  574. ration.targetUnitFee = "";
  575. ration.deleteInfo = null;
  576. ration.quantityCoe = {};
  577. ration.rationQuantityCoe="";
  578. ration.tenderQuantity = "";
  579. ration.programID = null;
  580. let newRation = await ration_model.model.findOneAndUpdate({ID:rationID,projectID:projectID},{"$set":ration},{new: true});//;
  581. return {ration:newRation,ration_gljs:[],ration_coes:[],ration_installs:[]};
  582. }
  583. function createRationAss(std) {
  584. let rationAssList = [];//生成辅助定额
  585. if(std.hasOwnProperty('rationAssList')&&std.rationAssList.length>0){
  586. let assGroup = _.groupBy(std.rationAssList,'name');
  587. for(let key in assGroup){
  588. let assList = assGroup[key];
  589. let ass = assList[0];
  590. ass._doc.actualValue = ass.stdValue;
  591. ass._doc.isAdjust = 0;
  592. if(_.isString(ass._doc.assistCode)) ass._doc.assistCode = ass._doc.assistCode.replace("\n","");
  593. if(_.isString(ass._doc.thirdRationCode)) ass._doc.thirdRationCode = ass._doc.thirdRationCode.replace("\n","");
  594. if(assList.length > 1){
  595. ass._doc.groupList = JSON.parse(JSON.stringify(assList)) ;
  596. ass._doc.maxValue = assList[assList.length-1]._doc.maxValue;
  597. }
  598. rationAssList.push(ass);
  599. }
  600. }
  601. return rationAssList;
  602. }
  603. async function CalculateQuantity (ration,billsItemID,projectID) {
  604. // calculate ration Quantity
  605. let project = await projectModel.findOne({ID:projectID});
  606. let decimalObject =await decimal_facade.getProjectDecimal(projectID,project);
  607. let quantity_decimal = (decimalObject&&decimalObject.ration&&decimalObject.ration.quantity)?decimalObject.ration.quantity:3;
  608. let pbill = await bill_model.model.findOne({projectID:projectID,ID:billsItemID});
  609. let t_unit = ration.unit?ration.unit.replace(/^\d+/,""):"";
  610. if(t_unit!=pbill.unit){//如果定额工程量的单位去除前面的数字后不等于清单单位,定额工程量保持不变
  611. return ;
  612. }
  613. let billsQuantity = pbill.quantity ? pbill.quantity : 0;
  614. let bill_decimal = await decimal_facade.getBillsQuantityDecimal(projectID,pbill.unit,project);
  615. billsQuantity=scMathUtil.roundForObj(billsQuantity,bill_decimal);
  616. ration.quantityEXP="QDL";
  617. ration.quantity = scMathUtil.roundForObj(billsQuantity / FilterNumberFromUnit(ration.unit),quantity_decimal);//不管是否打勾都做转换
  618. ration.contain = scMathUtil.roundForObj(ration.quantity/billsQuantity,6);
  619. };
  620. async function getProgramForProject(projectID){
  621. let project = await projectModel.findOne({ID:projectID});
  622. return project.property.engineering;
  623. }
  624. function FilterNumberFromUnit (unit) {
  625. let reg = new RegExp('^[0-9]+');
  626. if (reg.test(unit)) {
  627. return parseInt(unit.match(reg)[0]);
  628. } else {
  629. return 1;
  630. }
  631. };