gljModel.js 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  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 gljModelBackup = mongoose.model('std_glj_lib_gljList_backup');
  8. const gljClassModel = mongoose.model('std_glj_lib_gljClass');
  9. const gljClassModelBackup = mongoose.model('std_glj_lib_gljClass_backup');
  10. const projectGLJModel = mongoose.model('glj_list');
  11. const projectModel = mongoose.model('projects');
  12. const userModel = mongoose.model('users');
  13. const gljClassTemplateModel = mongoose.model('std_glj_lib_gljClassTemplate');
  14. const compilationModel = mongoose.model('compilation');
  15. const scMathUtil = require('../../../public/scMathUtil').getUtil();
  16. const rationMapModel = mongoose.model('std_ration_lib_map');
  17. const rationModel = mongoose.model('std_ration_lib_ration_items');
  18. const complementaryRationModel = mongoose.model('complementary_ration_items');
  19. import { OprDao } from "./gljMapModel";
  20. import moment from "moment";
  21. import counter from "../../../public/counter/counter";
  22. import async from "async";
  23. let _ = require("lodash");
  24. class GljDao extends OprDao {
  25. // 处理单价,将多单价的第一个价格字段,设置成定额价
  26. async setBasePrice(libID) {
  27. const gljs = await gljModel.find({ repositoryId: libID }).lean();
  28. const bulks = [];
  29. gljs.forEach(glj => {
  30. const basePrice = glj.priceProperty && glj.priceProperty.price1 !== undefined && glj.priceProperty.price1 !== null ? glj.priceProperty.price1 : 0;
  31. bulks.push({ updateOne: { filter: { ID: glj.ID }, update: { $set: { basePrice, priceProperty: {} } } } })
  32. });
  33. const chunks = _.chunk(bulks, 1000);
  34. for (const chunk of chunks) {
  35. if (chunk.length) {
  36. await gljModel.bulkWrite(chunk);
  37. }
  38. }
  39. }
  40. // 处理消耗量,将多消耗量的第一个消耗量字段,设置成消耗量
  41. async setConsumeAmt(sourceLibID, targetLibID) {
  42. const sourceGljs = await gljModelBackup.find({ repositoryId: sourceLibID }).lean();
  43. const targetGljs = await gljModel.find({ repositoryId: targetLibID }).lean();
  44. const sourceMap = {};
  45. const sourceIDMap = {};
  46. sourceGljs.forEach(glj => {
  47. sourceMap[glj.code] = glj;
  48. sourceIDMap[glj.ID] = glj.code;
  49. });
  50. const targetMap = {};
  51. targetGljs.forEach(glj => {
  52. targetMap[glj.code] = glj;
  53. });
  54. const bulks = [];
  55. targetGljs.forEach(glj => {
  56. const source = sourceMap[glj.code];
  57. if (source && source.component && source.component.length) {
  58. const component = [];
  59. source.component.forEach(c => {
  60. const cCode = sourceIDMap[c.ID];
  61. if (!cCode) {
  62. return;
  63. }
  64. const target = targetMap[cCode];
  65. if (!target) {
  66. return;
  67. }
  68. const newID = target.ID;
  69. const consumeAmt = c.consumeAmtProperty ? c.consumeAmtProperty.consumeAmt1 : undefined;
  70. component.push({ ID: newID, consumeAmt });
  71. })
  72. bulks.push({ updateOne: { filter: { ID: glj.ID }, update: { $set: { component } } } })
  73. }
  74. });
  75. if (bulks.length) {
  76. const chunks = _.chunk(bulks, 1000);
  77. for (const chunk of chunks) {
  78. if (chunk.length) {
  79. await gljModel.bulkWrite(chunk);
  80. }
  81. }
  82. }
  83. }
  84. async copyLib(sourceLibID, targetLibID) {
  85. const task = [
  86. this.copyClassData(sourceLibID, targetLibID),
  87. this.copyGLJData(sourceLibID, targetLibID)
  88. ];
  89. await Promise.all(task);
  90. }
  91. async copyClassData(sourceLibID, targetLibID) {
  92. const sourceClassData = await gljClassModel.find({ repositoryId: sourceLibID }, '-_id').lean();
  93. const insertData = sourceClassData.map(item => ({
  94. ...item,
  95. repositoryId: targetLibID
  96. }));
  97. if (insertData.length) {
  98. await gljClassModel.insertMany(insertData);
  99. }
  100. }
  101. async copyGLJData(sourceLibID, targetLibID) {
  102. const sourceGLJData = await gljModel.find({ repositoryId: sourceLibID }, '-_id').lean();
  103. const IDMapping = {};
  104. const countData = await counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, sourceGLJData.length);
  105. const countIdx = countData.sequence_value - (sourceGLJData.length - 1);
  106. sourceGLJData.forEach((glj, index) => {
  107. IDMapping[glj.ID] = countIdx + index;
  108. });
  109. const insertData = sourceGLJData.map(glj => {
  110. const newComponent = (glj.component || []).map(c => ({
  111. ID: IDMapping[c.ID],
  112. consumeAmt: c.consumeAmt
  113. }));
  114. /* // 设备改材料
  115. const gljType = glj.gljType === 5 ? 201 : glj.gljType; */
  116. return {
  117. ...glj,
  118. repositoryId: targetLibID,
  119. ID: IDMapping[glj.ID],
  120. component: newComponent
  121. };
  122. });
  123. if (insertData.length) {
  124. await gljModel.insertMany(insertData);
  125. }
  126. }
  127. async getReference(repositoryId, gljId) {
  128. const gljLib = await gljMapModel.findOne({ ID: repositoryId });
  129. const rationLibIds = gljLib.rationLibs.map(lib => lib.ID);
  130. const rationLibs = await rationMapModel.find({ ID: { $in: rationLibIds } }, '-_id ID dispName');
  131. const rationLibNameMapping = {};
  132. rationLibs.forEach(item => {
  133. rationLibNameMapping[item.ID] = item.dispName;
  134. });
  135. const stdRations = await rationModel.find({ rationRepId: { $in: rationLibIds }, 'rationGljList.gljId': gljId }, '-_id code rationRepId');
  136. const rst = {};
  137. const unknownLib = '未知定额库';
  138. const complementaryLib = '补充定额库';
  139. stdRations.forEach(ration => {
  140. const libName = rationLibNameMapping[ration.rationRepId] || unknownLib;
  141. if (!rst[libName]) {
  142. rst[libName] = [];
  143. }
  144. rst[libName].push(ration);
  145. });
  146. const complementaryRations = await complementaryRationModel.find({ 'rationGljList.gljId': gljId }, '-_id code');
  147. if (complementaryRations.length) {
  148. rst[complementaryLib] = [];
  149. }
  150. complementaryRations.forEach(ration => rst[complementaryLib].push({ code: ration.code }));
  151. return rst;
  152. }
  153. async getUsedInfo(repositoryId, gljId) {
  154. let userMap = {};
  155. let userIDList = [];
  156. let projectList = await projectGLJModel.find({ "glj_id": gljId }, '-_id project_id').lean();
  157. if (projectList.length > 0) {
  158. let projectUserList = await projectModel.find({ 'ID': { $in: _.map(projectList, "project_id") } }, '-_id ID userID').lean();
  159. for (let p of projectUserList) {
  160. if (!userMap[p.userID]) {
  161. userMap[p.userID] = true;
  162. userIDList.push(p.userID);
  163. }
  164. }
  165. let userList = await userModel.find({ '_id': { $in: userIDList } }, '_id username mobile').lean();
  166. for (let u of userList) {
  167. userMap[u._id.toString()] = u;
  168. }
  169. for (let p of projectUserList) {
  170. p.username = userMap[p.userID].username;
  171. p.mobile = userMap[p.userID].mobile;
  172. }
  173. return projectUserList
  174. }
  175. return [];
  176. }
  177. async getGljTreeSync(gljLibId) {
  178. return await gljClassModel.find({ repositoryId: gljLibId });
  179. }
  180. getGljTypes(gljLibId, callback) {
  181. gljClassModel.find({ "repositoryId": gljLibId, "$or": [{ "isDeleted": null }, { "isDeleted": false }, { deleted: false }] },
  182. '-_id', { lean: true }, function (err, data) {
  183. if (err) callback("获取工料机类型错误!", false)
  184. else {
  185. callback(0, data);
  186. }
  187. })
  188. }
  189. _exist(data, attr) {
  190. return data && data[attr] !== 'undefined' && data[attr];
  191. }
  192. sortToNumber(datas) {
  193. for (let i = 0, len = datas.length; i < len; i++) {
  194. let data = datas[i]._doc;
  195. if (this._exist(data, 'basePrice')) {
  196. data['basePrice'] = parseFloat(data['basePrice']);
  197. }
  198. if (this._exist(data, 'component')) {
  199. for (let j = 0, jLen = data['component'].length; j < jLen; j++) {
  200. let comGljObj = data['component'][j]._doc;
  201. if (this._exist(comGljObj, 'consumeAmt')) {
  202. comGljObj['consumeAmt'] = parseFloat(comGljObj['consumeAmt']);
  203. }
  204. }
  205. }
  206. }
  207. }
  208. async getGljItemsSync(gljLibId) {
  209. return await gljModel.find({ repositoryId: gljLibId }, '-_id', { lean: true });
  210. }
  211. async getGljItemsByRep(repositoryId, callback = null) {
  212. /* let me = this;
  213. if (callback === null) {
  214. return gljModel.find({"repositoryId": repositoryId});
  215. } else {
  216. gljModel.find({"repositoryId": repositoryId},function(err,data){
  217. if(err) callback(true, "")
  218. else {
  219. me.sortToNumber(data);
  220. callback(false,data);
  221. }
  222. })
  223. }*/
  224. let me = this;
  225. let rst = [];
  226. //批量获取异步
  227. let functions = [];
  228. let count = await gljModel.find({ repositoryId: repositoryId, $or: [{ deleted: null }, { deleted: false }] }).count();
  229. let findCount = Math.ceil(count / 500);
  230. for (let i = 0, len = findCount; i < len; i++) {
  231. functions.push((function (flag) {
  232. return function (cb) {
  233. gljModel.find({ repositoryId: repositoryId, deleted: null }, '-_id', { lean: true }, cb).skip(flag).sort({ ID: 1 }).limit(500);
  234. }
  235. })(i * 500));
  236. }
  237. async.parallel(functions, function (err, results) {
  238. if (err) {
  239. callback(err, null);
  240. }
  241. else {
  242. for (let stdGljs of results) {
  243. rst = rst.concat(stdGljs);
  244. }
  245. me.sortToNumber(rst);
  246. callback(0, rst);
  247. }
  248. });
  249. }
  250. getGljItemByType(repositoryId, type, callback) {
  251. let me = this;
  252. gljModel.find({ "repositoryId": repositoryId, "gljType": type }, function (err, data) {
  253. if (err) callback(true, "");
  254. else {
  255. me.sortToNumber(data);
  256. callback(false, data);
  257. }
  258. })
  259. };
  260. getGljItem(repositoryId, code, callback) {
  261. let me = this;
  262. gljModel.find({ "repositoryId": repositoryId, "code": code }, function (err, data) {
  263. if (err) callback(true, "")
  264. else {
  265. me.sortToNumber(data);
  266. callback(false, data);
  267. }
  268. })
  269. };
  270. getGljItems(gljIds, callback) {
  271. let me = this;
  272. gljModel.find({ "ID": { "$in": gljIds } }, function (err, data) {
  273. if (err) callback(true, "")
  274. else {
  275. me.sortToNumber(data);
  276. callback(false, data);
  277. }
  278. })
  279. };
  280. getGljItemsByCode(repositoryId, codes, callback) {
  281. let me = this;
  282. gljModel.find({ "repositoryId": repositoryId, "code": { "$in": codes } }, function (err, data) {
  283. if (err) callback(true, "");
  284. else {
  285. me.sortToNumber(data);
  286. callback(false, data);
  287. }
  288. })
  289. };
  290. updateComponent(libId, oprtor, updateArr, callback) {
  291. let parallelFucs = [];
  292. for (let i = 0; i < updateArr.length; i++) {
  293. parallelFucs.push((function (obj) {
  294. return function (cb) {
  295. if (typeof obj.component === 'undefined') {
  296. obj.component = [];
  297. }
  298. gljModel.update({ repositoryId: libId, ID: obj.ID }, obj, function (err, result) {
  299. if (err) {
  300. cb(err);
  301. }
  302. else {
  303. cb(null, obj);
  304. }
  305. })
  306. }
  307. })(updateArr[i]));
  308. }
  309. parallelFucs.push((function () {
  310. return function (cb) {
  311. GljDao.updateOprArr({ ID: libId }, oprtor, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  312. if (err) {
  313. cb(err);
  314. }
  315. else {
  316. cb(null);
  317. }
  318. })
  319. }
  320. })());
  321. async.parallel(parallelFucs, function (err, result) {
  322. if (err) {
  323. callback(err, '更新组成物错误!', null);
  324. }
  325. else {
  326. callback(null, '成功!', result);
  327. }
  328. });
  329. }
  330. mixUpdateGljItems(repId, lastOpr, updateItems, addItems, rIds, callback) {
  331. if (updateItems.length == 0 && rIds.length == 0) {
  332. GljDao.addGljItems(repId, lastOpr, addItems, callback);
  333. }
  334. else if (rIds.length > 0 && updateItems.length > 0) {
  335. async.parallel([
  336. function (cb) {
  337. GljDao.removeGljItems(repId, lastOpr, rIds, cb);
  338. },
  339. function (cb) {
  340. GljDao.updateGljItems(repId, lastOpr, updateItems, cb);
  341. }
  342. ], function (err) {
  343. if (err) {
  344. callback(true, "Fail to update and delete", false)
  345. }
  346. else {
  347. callback(false, "Save successfully", false);
  348. }
  349. })
  350. }
  351. else if (rIds.length > 0 && updateItems.length === 0) {
  352. GljDao.removeGljItems(repId, lastOpr, rIds, callback);
  353. }
  354. else if (updateItems.length > 0 || addItems.length > 0) {
  355. GljDao.updateGljItems(repId, lastOpr, updateItems, function (err, results) {
  356. if (err) {
  357. callback(true, "Fail to update", false);
  358. } else {
  359. if (addItems && addItems.length > 0) {
  360. GljDao.addGljItems(repId, lastOpr, addItems, callback);
  361. } else {
  362. callback(false, "Save successfully", results);
  363. }
  364. }
  365. });
  366. }
  367. }
  368. /*mixUpdateGljItems (repId, lastOpr, updateItems, addItems, rIds, callback) {
  369. if (updateItems.length == 0 && rIds.length == 0) {
  370. GljDao.addGljItems(repId, lastOpr, addItems, callback);
  371. } else if (rIds.length > 0) {
  372. GljDao.removeGljItems(repId, lastOpr, rIds, function(err, message, docs) {
  373. });
  374. }else{
  375. GljDao.updateGljItems(repId, lastOpr, updateItems, function(err, results){
  376. if (err) {
  377. callback(true, "Fail to update", false);
  378. } else {
  379. if (addItems && addItems.length > 0) {
  380. GljDao.addGljItems(repId, lastOpr, addItems, callback);
  381. } else {
  382. callback(false, "Save successfully", results);
  383. }
  384. }
  385. });
  386. }
  387. };*/
  388. static removeGljItems(repId, lastOpr, rIds, callback) {
  389. if (rIds && rIds.length > 0) {
  390. gljModel.collection.remove({ ID: { $in: rIds } }, null, function (err, docs) {
  391. if (err) {
  392. callback(true, "Fail to remove", false);
  393. } else {
  394. GljDao.updateOprArr({ ID: repId }, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  395. if (err) {
  396. callback(true, "Fail to update operator", false);
  397. }
  398. else {
  399. callback(false, "Remove successfully", docs);
  400. }
  401. });
  402. }
  403. })
  404. } else {
  405. callback(false, "No records were deleted!", null);
  406. }
  407. }
  408. static addGljItems(repId, lastOpr, items, callback) {
  409. if (items && items.length > 0) {
  410. const codes = [];
  411. items.forEach(item => codes.push(item.code));
  412. gljModel.find({ repositoryId: repId, code: { $in: codes } }, '-_id code', { lean: true }, (err, codeData) => {
  413. if (err) {
  414. callback(true, '判断编码唯一性失败', false);
  415. return;
  416. }
  417. const insertData = [];
  418. const failCode = [];
  419. items.forEach(item => {
  420. const matchData = codeData.find(codeItem => codeItem.code === item.code);
  421. if (!matchData) {
  422. insertData.push(item);
  423. } else {
  424. failCode.push(item.code);
  425. }
  426. });
  427. if (!insertData.length) {
  428. callback(false, 'empty data', { insertData, failCode });
  429. return;
  430. }
  431. counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, items.length, (counterErr, counterData) => {
  432. if (counterErr) {
  433. callback(true, '获取人材机ID失败', false);
  434. return;
  435. }
  436. const maxId = counterData.sequence_value;
  437. for (let i = 0; i < insertData.length; i++) {
  438. insertData[i].ID = (maxId - (insertData.length - 1) + i);
  439. insertData[i].repositoryId = repId;
  440. }
  441. const task = [];
  442. insertData.forEach(item => {
  443. task.push({
  444. insertOne: { document: item }
  445. });
  446. });
  447. gljModel.bulkWrite(task, (insertErr, rst) => {
  448. if (insertErr) {
  449. callback(true, '新增数据失败', false);
  450. return;
  451. }
  452. GljDao.updateOprArr({ ID: repId }, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  453. if (err) {
  454. callback(true, "Fail to update Operator", false);
  455. } else {
  456. callback(false, "Add successfully", { insertData, failCode });
  457. }
  458. });
  459. });
  460. });
  461. });
  462. } else {
  463. callback(true, "No source", false);
  464. }
  465. }
  466. static updateGljItems(repId, lastOpr, items, callback) {
  467. var functions = [];
  468. for (var i = 0; i < items.length; i++) {
  469. functions.push((function (doc) {
  470. return function (cb) {
  471. var filter = {};
  472. if (doc.ID) {
  473. filter.ID = doc.ID;
  474. } else {
  475. filter.repositoryId = repId;
  476. filter.code = doc.code;
  477. }
  478. gljModel.update(filter, doc, cb);
  479. };
  480. })(items[i]));
  481. }
  482. functions.push((function () {
  483. return function (cb) {
  484. GljDao.updateOprArr({ ID: repId }, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  485. if (err) {
  486. cb(err);
  487. }
  488. else {
  489. cb(null);
  490. }
  491. })
  492. }
  493. })());
  494. async.parallel(functions, function (err, results) {
  495. callback(err, results);
  496. });
  497. }
  498. getRationGljIds(rationLibs, callback) {
  499. }
  500. updateNodes(updateData, lastOpr, callback) {
  501. let functions = [];
  502. for (let i = 0, len = updateData.length; i < len; i++) {
  503. functions.push((function (doc) {
  504. return function (cb) {
  505. if (doc.updateType === 'update' && !doc.updateData.deleted) {
  506. gljClassModel.update({ repositoryId: doc.updateData.repositoryId, ID: doc.updateData.ID }, doc.updateData, function (err) {
  507. if (err) {
  508. cb(err);
  509. }
  510. else {
  511. cb(null);
  512. }
  513. });
  514. }
  515. else if (doc.updateType === 'update' && doc.updateData.deleted) {
  516. gljClassModel.remove({ repositoryId: doc.updateData.repositoryId, ID: doc.updateData.ID }, function (err) {
  517. if (err) {
  518. cb(err);
  519. }
  520. else {
  521. gljModel.remove({ repositoryId: doc.updateData.repositoryId, gljClass: doc.updateData.ID }, function (err) {
  522. if (err) {
  523. cb(err);
  524. }
  525. else {
  526. cb(null);
  527. }
  528. });
  529. }
  530. });
  531. }
  532. else if (doc.updateType === 'new') {
  533. gljClassModel.create(doc.updateData, function (err) {
  534. if (err) {
  535. cb(err);
  536. }
  537. else {
  538. cb(null);
  539. }
  540. });
  541. }
  542. };
  543. })(updateData[i]));
  544. }
  545. if (updateData.length > 0) {
  546. functions.push((function () {
  547. return function (cb) {
  548. GljDao.updateOprArr({ ID: updateData[0].updateData.rationRepId }, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  549. if (err) {
  550. cb(err);
  551. }
  552. else {
  553. cb(null);
  554. }
  555. })
  556. }
  557. })());
  558. }
  559. async.parallel(functions, function (err, results) {
  560. if (!err) {
  561. err = 0;
  562. }
  563. callback(err, results);
  564. });
  565. }
  566. /* updateNodes (repId, lastOpr, nodes, callback) {
  567. var functions = [];
  568. for (var i=0; i < nodes.length; i++) {
  569. functions.push((function(doc) {
  570. return function(cb) {
  571. gljClassModel.update({ID: doc.ID}, doc, cb);
  572. };
  573. })(nodes[i]));
  574. }
  575. functions.push((function () {
  576. return function (cb) {
  577. GljDao.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  578. if(err){
  579. cb(err);
  580. }
  581. else{
  582. cb(null);
  583. }
  584. })
  585. }
  586. })());
  587. async.parallel(functions, function(err, results) {
  588. callback(err, results);
  589. });
  590. }*/
  591. removeNodes(repId, lastOpr, nodeIds, preNodeId, preNodeNextId, callback) {
  592. var functions = [];
  593. if (preNodeId != -1) {
  594. functions.push((function (nodeId, nextId) {
  595. return function (cb) {
  596. gljClassModel.update({ ID: nodeId }, { "NextSiblingID": nextId }, cb);
  597. };
  598. })(preNodeId, preNodeNextId));
  599. }
  600. for (var i = 0; i < nodeIds.length; i++) {
  601. functions.push((function (nodeId) {
  602. return function (cb) {
  603. gljClassModel.update({ ID: nodeId }, { "isDeleted": true }, cb);
  604. };
  605. })(nodeIds[i]));
  606. }
  607. functions.push((function () {
  608. return function (cb) {
  609. GljDao.updateOprArr({ ID: repId }, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  610. if (err) {
  611. cb(err);
  612. }
  613. else {
  614. cb(null);
  615. }
  616. })
  617. }
  618. })());
  619. async.parallel(functions, function (err, results) {
  620. callback(err, results);
  621. });
  622. }
  623. createNewNode(repId, lastOpr, lastNodeId, nodeData, callback) {
  624. return counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, 1, function (err, result) {
  625. nodeData.repositoryId = repId;
  626. nodeData.ID = result.sequence_value;
  627. var node = new gljModel(nodeData);
  628. async.parallel([
  629. function (cb) {
  630. node.save(function (err, result) {
  631. if (err) {
  632. cb("章节树ID错误!", false);
  633. } else {
  634. if (lastNodeId > 0) {
  635. gljClassModel.update({ ID: lastNodeId }, { "NextSiblingID": nodeData.ID }, function (err, rst) {
  636. if (err) {
  637. cb("章节树ID错误!", false);
  638. } else {
  639. cb(false, result);
  640. }
  641. });
  642. } else cb(false, result);
  643. }
  644. });
  645. },
  646. function (cb) {
  647. GljDao.updateOprArr({ ID: repId }, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  648. if (err) {
  649. cb(err);
  650. }
  651. else {
  652. cb(null);
  653. }
  654. })
  655. }
  656. ], function (err, result) {
  657. if (err) {
  658. callback(true, "章节树错误!", false);
  659. }
  660. else {
  661. callback(false, '', result[0]);
  662. }
  663. })
  664. });
  665. }
  666. getGljItemsOccupied(repId, occupation, callback) {
  667. gljModel.find({ repositoryId: repId }, occupation, function (err, result) {
  668. if (err) callback(true, 'fail', null);
  669. else callback(false, 'sc', result);
  670. });
  671. }
  672. async getGljItemsByRepId(repositoryId, returnFields = '') {
  673. return gljModel.find({ "repositoryId": repositoryId }, returnFields);
  674. }
  675. async batchUpdateGljPrice(gljLibId, sheetData) {
  676. let gljLib = await gljMapModel.findOne({ ID: gljLibId });
  677. if (!gljLib) {
  678. throw '不存在此人材机库';
  679. }
  680. let compilation = await compilationModel.findOne({ _id: mongoose.Types.ObjectId(gljLib.compilationId) });
  681. if (!compilation) {
  682. throw '不存在此费用定额';
  683. }
  684. let priceProperties = compilation.priceProperties ? compilation.priceProperties : [];
  685. //根据第一行数据,获取列下标与字段名映射
  686. let colMapping = {};
  687. for (let col = 0; col < sheetData[0].length; col++) {
  688. let cData = sheetData[0][col];
  689. if (cData === '编码') {
  690. colMapping['code'] = col;
  691. }
  692. else {
  693. if (priceProperties.length === 0) {
  694. if (cData === '定额价') {
  695. colMapping['basePrice'] = col;
  696. break;
  697. }
  698. }
  699. else {
  700. for (let priceProp of priceProperties) {
  701. if (priceProp.price.dataName === cData) {
  702. colMapping[priceProp.price.dataCode] = col;
  703. break;
  704. }
  705. }
  706. }
  707. }
  708. }
  709. let colMappingKeys = Object.keys(colMapping);
  710. if (colMappingKeys.length < 2) {
  711. throw 'excel数据不正确'
  712. }
  713. let updateBulk = [];
  714. //避免重复
  715. let updateCodes = [];
  716. //库中存在的人材机
  717. let dateA = Date.now();
  718. let existGljs = await gljModel.find({ repositoryId: gljLibId }, '-_id code ID');
  719. let existMapping = {};
  720. for (let glj of existGljs) {
  721. existMapping[glj.code] = glj;
  722. }
  723. for (let row = 0; row < sheetData.length; row++) {
  724. if (row === 0) {
  725. continue;
  726. }
  727. let gljCode = sheetData[row][colMapping.code],
  728. existGlj = existMapping[gljCode];
  729. //更新多单价、不覆盖priceProperty字段,覆盖priceProperty下的子字段'priceProperty.x'
  730. if (gljCode && gljCode !== '' && !updateCodes.includes(gljCode) && existGlj) {
  731. if (priceProperties.length > 0) {
  732. for (let priceProp of priceProperties) {
  733. let dataCode = priceProp.price.dataCode;
  734. let priceCellData = sheetData[row][colMapping[dataCode]];
  735. //Excel中没有这个单价则跳过
  736. if (!colMapping[dataCode]) {
  737. continue;
  738. }
  739. let updateSet = {};
  740. updateSet['priceProperty.' + dataCode] = priceCellData && !isNaN(priceCellData) ?
  741. scMathUtil.roundTo(parseFloat(priceCellData), -2) : 0;
  742. updateBulk.push({
  743. updateOne: { filter: { ID: existGlj.ID }, update: { $set: updateSet } }
  744. });
  745. }
  746. updateCodes.push(gljCode);
  747. }
  748. else {
  749. if (colMapping.basePrice) {
  750. let priceCellData = sheetData[row][colMapping.basePrice];
  751. let basePrice = priceCellData && !isNaN(priceCellData) ?
  752. scMathUtil.roundTo(priceCellData, -2) : 0;
  753. updateCodes.push(gljCode);
  754. updateBulk.push({
  755. updateOne: { filter: { ID: existGlj.ID }, update: { $set: { basePrice: basePrice } } }
  756. });
  757. }
  758. }
  759. }
  760. }
  761. if (updateBulk.length > 0) {
  762. while (updateBulk.length > 0) {
  763. let sliceBulk = updateBulk.splice(0, 1000);
  764. await gljModel.bulkWrite(sliceBulk);
  765. }
  766. }
  767. }
  768. async importComponents(gljLibId, sheetData) {
  769. const gljLib = await gljMapModel.findOne({ ID: gljLibId });
  770. if (!gljLib) {
  771. throw '不存在此人材机库';
  772. }
  773. const compilation = await compilationModel.findOne({ _id: mongoose.Types.ObjectId(gljLib.compilationId) });
  774. if (!compilation) {
  775. throw '不存在此费用定额';
  776. }
  777. // 将所有人材机进行编码映射
  778. const allGLJs = await gljModel.find({ repositoryId: gljLibId }, { ID: true, code: true }).lean();
  779. const codeMapping = {};
  780. allGLJs.forEach(glj => codeMapping[glj.code] = glj);
  781. // excel表格列号与字段的映射
  782. const colMapping = {
  783. // 材料编码
  784. code: 0,
  785. // 组成物编码
  786. componentCode: 1,
  787. // 组成物消耗量
  788. consumeAmt: 2
  789. };
  790. // 跳过列头
  791. for (let row = 1; row < sheetData.length; row++) {
  792. const rowData = sheetData[row];
  793. const code = rowData[colMapping.code];
  794. const componentCode = rowData[colMapping.componentCode];
  795. const consumeAmt = +rowData[colMapping.consumeAmt];
  796. const glj = codeMapping[code];
  797. const component = codeMapping[componentCode];
  798. if (!glj || !component) {
  799. continue;
  800. }
  801. if (!glj.component) {
  802. glj.component = [];
  803. }
  804. glj.component.push({
  805. ID: component.ID,
  806. consumeAmt: consumeAmt
  807. });
  808. }
  809. // 更新数据
  810. const tasks = [];
  811. allGLJs.filter(glj => glj.component && glj.component.length).forEach(glj => {
  812. tasks.push({
  813. updateOne: {
  814. filter: {
  815. ID: glj.ID
  816. },
  817. update: { $set: { component: glj.component } }
  818. }
  819. });
  820. });
  821. if (tasks.length) {
  822. await gljModel.bulkWrite(tasks);
  823. }
  824. }
  825. }
  826. export default GljDao;