gljModel.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. /**
  2. * Created by Zhong on 2017/8/11.
  3. */
  4. const mongoose = require('mongoose');
  5. const gljMapModel = mongoose.model('std_glj_lib_map');
  6. const gljModel = mongoose.model('std_glj_lib_gljList');
  7. const gljClassModel = mongoose.model('std_glj_lib_gljClass');
  8. const gljClassTemplateModel = mongoose.model('std_glj_lib_gljClassTemplate');
  9. const compilationModel = mongoose.model('compilation');
  10. const scMathUtil = require('../../../public/scMathUtil').getUtil();
  11. const rationModel = mongoose.model('std_ration_lib_ration_items');
  12. import {OprDao} from "./gljMapModel";
  13. import moment from "moment";
  14. import counter from "../../../public/counter/counter";
  15. import async from "async";
  16. class GljDao extends OprDao{
  17. //test
  18. async deSomething (libID){
  19. let pClass = await gljClassModel.find({repositoryId: libID, Name: '2013全省材料预算价格'});
  20. let classIDs = [],
  21. pClassIDs = [];
  22. for (let p of pClass) {
  23. let p1Class = await gljClassModel.find({repositoryId: libID, ParentID: p.ID});
  24. for (let c of p1Class) {
  25. pClassIDs.push(c.ID);
  26. }
  27. }
  28. let subClass = await gljClassModel.find({repositoryId: libID, ParentID: {$in: pClassIDs}});
  29. for (let s of subClass) {
  30. classIDs.push(s.ID);
  31. }
  32. let subSonClass = await gljClassModel.find({repositoryId: libID, ParentID: {$in: classIDs}});
  33. for (let ss of subSonClass){
  34. classIDs.push(ss.ID);
  35. }
  36. classIDs = Array.from(new Set(classIDs));
  37. //相关人材机
  38. let gljs = await gljModel.find({repositoryId: libID, gljClass: {$in: classIDs}}, '-_id gljClass ID');
  39. let gljIDs = [];
  40. for (let g of gljs) {
  41. gljIDs.push(g.ID);
  42. }
  43. let gljLib = await gljMapModel.findOne({ID: libID});
  44. let refRationLibIDs = [];
  45. for (let rl of gljLib.rationLibs) {
  46. refRationLibIDs.push(rl.ID);
  47. }
  48. let i = 0;
  49. for (let rationLibID of refRationLibIDs) {
  50. await rationModel.update({rationRepId: rationLibID, 'rationGljList.gljId': {$in: gljIDs}}, {$pull: {rationGljList: {gljId: {$in: gljIDs}}}}, {multi: true});
  51. console.log(`i++======================`);
  52. console.log(i++);
  53. }
  54. await gljModel.remove({ID: {$in: gljIDs}});
  55. console.log('end');
  56. }
  57. //test
  58. getGljTypes (gljLibId, callback){
  59. gljClassModel.find({"repositoryId": gljLibId, "$or": [{"isDeleted": null}, {"isDeleted": false}, {deleted: false} ]},function(err,data){
  60. if(err) callback("获取工料机类型错误!",false)
  61. else {
  62. callback(0, data);
  63. }
  64. })
  65. }
  66. _exist(data, attr){
  67. return data && data[attr] !== 'undefined' && data[attr];
  68. }
  69. sortToNumber(datas){
  70. for(let i = 0, len = datas.length; i < len; i++){
  71. let data = datas[i]._doc;
  72. if(this._exist(data, 'basePrice')){
  73. data['basePrice'] = parseFloat(data['basePrice']);
  74. }
  75. if(this._exist(data, 'component')){
  76. for(let j = 0, jLen = data['component'].length; j < jLen; j++){
  77. let comGljObj = data['component'][j]._doc;
  78. if(this._exist(comGljObj, 'consumeAmt')){
  79. comGljObj['consumeAmt'] = parseFloat(comGljObj['consumeAmt']);
  80. }
  81. }
  82. }
  83. }
  84. }
  85. async getGljItemsByRep(repositoryId,callback = null){
  86. /* let me = this;
  87. if (callback === null) {
  88. return gljModel.find({"repositoryId": repositoryId});
  89. } else {
  90. gljModel.find({"repositoryId": repositoryId},function(err,data){
  91. if(err) callback(true, "")
  92. else {
  93. me.sortToNumber(data);
  94. callback(false,data);
  95. }
  96. })
  97. }*/
  98. let me = this;
  99. let rst = [];
  100. //批量获取异步
  101. let functions = [];
  102. let count = await gljModel.find({repositoryId: repositoryId, $or: [{deleted: null}, {deleted: false}]}).count();
  103. let findCount = Math.ceil(count/500);
  104. for(let i = 0, len = findCount; i < len; i++){
  105. functions.push((function(flag) {
  106. return function (cb) {
  107. gljModel.find({repositoryId: repositoryId, deleted: null}, cb).skip(flag).sort({ID: 1}).limit(500);
  108. }
  109. })(i*500));
  110. }
  111. async.parallel(functions, function (err, results) {
  112. if(err){
  113. callback(err, null);
  114. }
  115. else{
  116. for(let stdGljs of results){
  117. rst = rst.concat(stdGljs);
  118. }
  119. me.sortToNumber(rst);
  120. callback(0, rst);
  121. }
  122. });
  123. }
  124. getGljItemByType (repositoryId, type, callback){
  125. let me = this;
  126. gljModel.find({"repositoryId": repositoryId, "gljType": type},function(err,data){
  127. if(err) callback(true, "");
  128. else {
  129. me.sortToNumber(data);
  130. callback(false, data);
  131. }
  132. })
  133. };
  134. getGljItem (repositoryId, code, callback){
  135. let me = this;
  136. gljModel.find({"repositoryId": repositoryId, "code": code},function(err,data){
  137. if(err) callback(true, "")
  138. else {
  139. me.sortToNumber(data);
  140. callback(false, data);
  141. }
  142. })
  143. };
  144. getGljItems (gljIds, callback){
  145. let me = this;
  146. gljModel.find({"ID": {"$in": gljIds}},function(err,data){
  147. if(err) callback(true, "")
  148. else {
  149. me.sortToNumber(data);
  150. callback(false, data);
  151. }
  152. })
  153. };
  154. getGljItemsByCode (repositoryId, codes, callback){
  155. let me = this;
  156. gljModel.find({"repositoryId": repositoryId,"code": {"$in": codes}},function(err,data){
  157. if(err) callback(true, "");
  158. else {
  159. me.sortToNumber(data);
  160. callback(false, data);
  161. }
  162. })
  163. };
  164. updateComponent(libId, oprtor, updateArr, callback){
  165. let parallelFucs = [];
  166. for(let i = 0; i < updateArr.length; i++){
  167. parallelFucs.push((function(obj){
  168. return function (cb) {
  169. if(typeof obj.component === 'undefined'){
  170. obj.component = [];
  171. }
  172. gljModel.update({repositoryId: libId, ID: obj.ID}, obj, function (err, result) {
  173. if(err){
  174. cb(err);
  175. }
  176. else{
  177. cb(null, obj);
  178. }
  179. })
  180. }
  181. })(updateArr[i]));
  182. }
  183. parallelFucs.push((function () {
  184. return function (cb) {
  185. GljDao.updateOprArr({ID: libId}, oprtor, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  186. if(err){
  187. cb(err);
  188. }
  189. else{
  190. cb(null);
  191. }
  192. })
  193. }
  194. })());
  195. async.parallel(parallelFucs, function (err, result) {
  196. if(err){
  197. callback(err, '更新组成物错误!', null);
  198. }
  199. else{
  200. callback(null, '成功!', result);
  201. }
  202. });
  203. }
  204. mixUpdateGljItems (repId, lastOpr, updateItems, addItems, rIds, callback) {
  205. if (updateItems.length == 0 && rIds.length == 0) {
  206. GljDao.addGljItems(repId, lastOpr, addItems, callback);
  207. }
  208. else if(rIds.length > 0 && updateItems.length > 0){
  209. async.parallel([
  210. function (cb) {
  211. GljDao.removeGljItems(repId, lastOpr, rIds, cb);
  212. },
  213. function (cb) {
  214. GljDao.updateGljItems(repId, lastOpr, updateItems, cb);
  215. }
  216. ], function (err) {
  217. if(err){
  218. callback(true, "Fail to update and delete", false)
  219. }
  220. else{
  221. callback(false, "Save successfully", false);
  222. }
  223. })
  224. }
  225. else if (rIds.length > 0 && updateItems.length === 0) {
  226. GljDao.removeGljItems(repId, lastOpr, rIds, callback);
  227. }
  228. else if(updateItems.length > 0 || addItems.length > 0){
  229. GljDao.updateGljItems(repId, lastOpr, updateItems, function(err, results){
  230. if (err) {
  231. callback(true, "Fail to update", false);
  232. } else {
  233. if (addItems && addItems.length > 0) {
  234. GljDao.addGljItems(repId, lastOpr, addItems, callback);
  235. } else {
  236. callback(false, "Save successfully", results);
  237. }
  238. }
  239. });
  240. }
  241. }
  242. /*mixUpdateGljItems (repId, lastOpr, updateItems, addItems, rIds, callback) {
  243. if (updateItems.length == 0 && rIds.length == 0) {
  244. GljDao.addGljItems(repId, lastOpr, addItems, callback);
  245. } else if (rIds.length > 0) {
  246. GljDao.removeGljItems(repId, lastOpr, rIds, function(err, message, docs) {
  247. });
  248. }else{
  249. GljDao.updateGljItems(repId, lastOpr, updateItems, function(err, results){
  250. if (err) {
  251. callback(true, "Fail to update", false);
  252. } else {
  253. if (addItems && addItems.length > 0) {
  254. GljDao.addGljItems(repId, lastOpr, addItems, callback);
  255. } else {
  256. callback(false, "Save successfully", results);
  257. }
  258. }
  259. });
  260. }
  261. };*/
  262. static removeGljItems (repId, lastOpr, rIds, callback) {
  263. if (rIds && rIds.length > 0) {
  264. gljModel.collection.remove({ID: {$in: rIds}}, null, function(err, docs){
  265. if (err) {
  266. callback(true, "Fail to remove", false);
  267. } else {
  268. GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  269. if(err){
  270. callback(true, "Fail to update operator", false);
  271. }
  272. else{
  273. callback(false, "Remove successfully", docs);
  274. }
  275. });
  276. }
  277. })
  278. } else {
  279. callback(false, "No records were deleted!", null);
  280. }
  281. }
  282. static addGljItems (repId, lastOpr, items, callback) {
  283. if (items && items.length > 0) {
  284. counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, items.length, function(err, result){
  285. var maxId = result.sequence_value;
  286. var arr = [];
  287. for (var i = 0; i < items.length; i++) {
  288. var obj = new gljModel(items[i]);
  289. obj.ID = (maxId - (items.length - 1) + i);
  290. obj.repositoryId = repId;
  291. arr.push(obj);
  292. }
  293. gljModel.collection.insert(arr, null, function(err, docs){
  294. if (err) {
  295. callback(true, "Fail to add", false);
  296. } else {
  297. GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  298. if(err){
  299. callback(true, "Fail to update Operator", false);
  300. }
  301. else{
  302. callback(false, "Add successfully", docs);
  303. }
  304. });
  305. }
  306. })
  307. });
  308. } else {
  309. callback(true, "No source", false);
  310. }
  311. }
  312. static updateGljItems(repId, lastOpr, items, callback) {
  313. var functions = [];
  314. for (var i=0; i < items.length; i++) {
  315. functions.push((function(doc) {
  316. return function(cb) {
  317. var filter = {};
  318. if (doc.ID) {
  319. filter.ID = doc.ID;
  320. } else {
  321. filter.repositoryId = repId;
  322. filter.code = doc.code;
  323. }
  324. gljModel.update(filter, doc, cb);
  325. };
  326. })(items[i]));
  327. }
  328. functions.push((function () {
  329. return function (cb) {
  330. GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  331. if(err){
  332. cb(err);
  333. }
  334. else{
  335. cb(null);
  336. }
  337. })
  338. }
  339. })());
  340. async.parallel(functions, function(err, results) {
  341. callback(err, results);
  342. });
  343. }
  344. getRationGljIds(rationLibs, callback){
  345. }
  346. updateNodes (updateData, lastOpr, callback) {
  347. let functions = [];
  348. for (let i = 0, len = updateData.length; i < len; i++) {
  349. functions.push((function(doc) {
  350. return function(cb) {
  351. if(doc.updateType === 'update' && !doc.updateData.deleted){
  352. gljClassModel.update({repositoryId: doc.updateData.repositoryId, ID: doc.updateData.ID}, doc.updateData, function (err) {
  353. if(err){
  354. cb(err);
  355. }
  356. else {
  357. cb(null);
  358. }
  359. });
  360. }
  361. else if(doc.updateType === 'update' && doc.updateData.deleted){
  362. gljClassModel.remove({repositoryId: doc.updateData.repositoryId, ID: doc.updateData.ID}, function (err) {
  363. if(err){
  364. cb(err);
  365. }
  366. else {
  367. gljModel.remove({repositoryId: doc.updateData.repositoryId, gljClass: doc.updateData.ID}, function (err) {
  368. if(err){
  369. cb(err);
  370. }
  371. else{
  372. cb(null);
  373. }
  374. });
  375. }
  376. });
  377. }
  378. else if(doc.updateType === 'new'){
  379. gljClassModel.create(doc.updateData, function (err) {
  380. if(err){
  381. cb(err);
  382. }
  383. else {
  384. cb(null);
  385. }
  386. });
  387. }
  388. };
  389. })(updateData[i]));
  390. }
  391. if(updateData.length > 0){
  392. functions.push((function () {
  393. return function (cb) {
  394. GljDao.updateOprArr({ID: updateData[0].updateData.rationRepId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  395. if(err){
  396. cb(err);
  397. }
  398. else{
  399. cb(null);
  400. }
  401. })
  402. }
  403. })());
  404. }
  405. async.parallel(functions, function(err, results) {
  406. if(!err){
  407. err = 0;
  408. }
  409. callback(err, results);
  410. });
  411. }
  412. /* updateNodes (repId, lastOpr, nodes, callback) {
  413. var functions = [];
  414. for (var i=0; i < nodes.length; i++) {
  415. functions.push((function(doc) {
  416. return function(cb) {
  417. gljClassModel.update({ID: doc.ID}, doc, cb);
  418. };
  419. })(nodes[i]));
  420. }
  421. functions.push((function () {
  422. return function (cb) {
  423. GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  424. if(err){
  425. cb(err);
  426. }
  427. else{
  428. cb(null);
  429. }
  430. })
  431. }
  432. })());
  433. async.parallel(functions, function(err, results) {
  434. callback(err, results);
  435. });
  436. }*/
  437. removeNodes (repId, lastOpr, nodeIds, preNodeId, preNodeNextId, callback){
  438. var functions = [];
  439. if (preNodeId != -1) {
  440. functions.push((function(nodeId, nextId) {
  441. return function(cb) {
  442. gljClassModel.update({ID: nodeId}, {"NextSiblingID": nextId}, cb);
  443. };
  444. })(preNodeId, preNodeNextId));
  445. }
  446. for (var i=0; i < nodeIds.length; i++) {
  447. functions.push((function(nodeId) {
  448. return function(cb) {
  449. gljClassModel.update({ID: nodeId}, {"isDeleted": true}, cb);
  450. };
  451. })(nodeIds[i]));
  452. }
  453. functions.push((function () {
  454. return function (cb) {
  455. GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  456. if(err){
  457. cb(err);
  458. }
  459. else{
  460. cb(null);
  461. }
  462. })
  463. }
  464. })());
  465. async.parallel(functions, function(err, results) {
  466. callback(err, results);
  467. });
  468. }
  469. createNewNode(repId, lastOpr, lastNodeId, nodeData, callback) {
  470. return counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, 1, function(err, result){
  471. nodeData.repositoryId = repId;
  472. nodeData.ID = result.sequence_value;
  473. var node = new gljModel(nodeData);
  474. async.parallel([
  475. function (cb) {
  476. node.save(function (err, result) {
  477. if (err) {
  478. cb("章节树ID错误!", false);
  479. } else {
  480. if (lastNodeId > 0) {
  481. gljClassModel.update({ID: lastNodeId}, {"NextSiblingID": nodeData.ID}, function(err, rst){
  482. if (err) {
  483. cb("章节树ID错误!", false);
  484. } else {
  485. cb(false, result);
  486. }
  487. });
  488. } else cb(false, result);
  489. }
  490. });
  491. },
  492. function (cb) {
  493. GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  494. if(err){
  495. cb(err);
  496. }
  497. else{
  498. cb(null);
  499. }
  500. })
  501. }
  502. ], function (err, result) {
  503. if(err){
  504. callback(true, "章节树错误!", false);
  505. }
  506. else{
  507. callback(false, '', result[0]);
  508. }
  509. })
  510. });
  511. }
  512. getGljItemsOccupied(repId, occupation, callback){
  513. gljModel.find({repositoryId: repId}, occupation, function (err, result) {
  514. if(err) callback(true, 'fail', null);
  515. else callback(false, 'sc', result);
  516. });
  517. }
  518. async getGljItemsByRepId(repositoryId, returnFields = ''){
  519. return gljModel.find({"repositoryId": repositoryId}, returnFields);
  520. }
  521. async batchUpdateGljPrice(gljLibId, sheetData){
  522. let gljLib = await gljMapModel.findOne({ID: gljLibId});
  523. if(!gljLib){
  524. throw '不存在此人材机库';
  525. }
  526. let compilation = await compilationModel.findOne({_id: mongoose.Types.ObjectId(gljLib.compilationId)});
  527. if(!compilation){
  528. throw '不存在此费用定额';
  529. }
  530. let priceProperties = compilation.priceProperties ? compilation.priceProperties : [];
  531. //根据第一行数据,获取列下标与字段名映射
  532. let colMapping = {};
  533. for(let col = 0; col < sheetData[0].length; col++){
  534. let cData = sheetData[0][col];
  535. if(cData === '编码'){
  536. colMapping['code'] = col;
  537. }
  538. else {
  539. if(priceProperties.length === 0){
  540. if(cData === '定额价'){
  541. colMapping['basePrice'] = col;
  542. break;
  543. }
  544. }
  545. else {
  546. for(let priceProp of priceProperties){
  547. if(priceProp.price.dataName === cData){
  548. colMapping[priceProp.price.dataCode] = col;
  549. break;
  550. }
  551. }
  552. }
  553. }
  554. }
  555. let colMappingKeys = Object.keys(colMapping);
  556. if(colMappingKeys.length < 2){
  557. throw 'excel数据不正确'
  558. }
  559. let updateBulk = [];
  560. //避免重复
  561. let updateCodes = [];
  562. //库中存在的人材机
  563. let dateA = Date.now();
  564. let existGljs = await gljModel.find({repositoryId: gljLibId}, '-_id code ID');
  565. let existMapping = {};
  566. for (let glj of existGljs) {
  567. existMapping[glj.code] = glj;
  568. }
  569. for(let row = 0; row < sheetData.length; row++){
  570. if(row === 0){
  571. continue;
  572. }
  573. let gljCode = sheetData[row][colMapping.code],
  574. existGlj = existMapping[gljCode];
  575. //更新多单价、不覆盖priceProperty字段,覆盖priceProperty下的子字段'priceProperty.x'
  576. if(gljCode && gljCode !== '' && !updateCodes.includes(gljCode) && existGlj){
  577. if(priceProperties.length > 0){
  578. for(let priceProp of priceProperties){
  579. let dataCode = priceProp.price.dataCode;
  580. let priceCellData = sheetData[row][colMapping[dataCode]];
  581. //Excel中没有这个单价则跳过
  582. if (!colMapping[dataCode]) {
  583. continue;
  584. }
  585. let updateSet = {};
  586. updateSet['priceProperty.' + dataCode] = priceCellData && !isNaN(priceCellData) ?
  587. scMathUtil.roundTo(parseFloat(priceCellData), -2) : 0;
  588. updateBulk.push({
  589. updateOne: {filter: {ID: existGlj.ID}, update: {$set: updateSet}}
  590. });
  591. }
  592. updateCodes.push(gljCode);
  593. }
  594. else {
  595. if(colMapping.basePrice){
  596. let priceCellData = sheetData[row][colMapping.basePrice];
  597. let basePrice = priceCellData && !isNaN(priceCellData) ?
  598. scMathUtil.roundTo(priceCellData, -2) : 0;
  599. updateCodes.push(gljCode);
  600. updateBulk.push({
  601. updateOne: {filter: {ID: existGlj.ID}, update: {$set: {basePrice: basePrice}}}
  602. });
  603. }
  604. }
  605. }
  606. }
  607. if(updateBulk.length > 0){
  608. while (updateBulk.length > 0) {
  609. let sliceBulk = updateBulk.splice(0, 1000);
  610. await gljModel.bulkWrite(sliceBulk);
  611. }
  612. }
  613. }
  614. }
  615. export default GljDao;