gljModel.js 39 KB

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