ration_item.js 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226
  1. /**
  2. * Created by Tony on 2017/4/28.
  3. */
  4. const mongoose = require('mongoose');
  5. let async = require("async");
  6. let moment = require('moment');
  7. let counter = require('../../../public/counter/counter');
  8. let gljDao = require('./glj_repository');
  9. let rationRepositoryDao = require('./repository_map');
  10. const scMathUtil = require('../../../public/scMathUtil').getUtil();
  11. const rationItemModel = mongoose.model('std_ration_lib_ration_items');
  12. const rationItemBackupModel = mongoose.model('std_ration_lib_ration_items_backup');
  13. const stdRationLibModel = mongoose.model('std_ration_lib_map');
  14. const stdRationSectionModel = mongoose.model('std_ration_lib_ration_chapter_trees');
  15. const stdRationSectionBackupModel = mongoose.model('std_ration_lib_ration_chapter_trees_backup');
  16. const stdCoeModel = mongoose.model('std_ration_lib_coe_list');
  17. const stdCoeBackupModel = mongoose.model('std_ration_lib_coe_list_backup');
  18. const compleRationModel = mongoose.model('complementary_ration_items');
  19. import STDGLJListModel from '../../std_glj_lib/models/gljModel';
  20. import InstallationDao from '../models/installation';
  21. const installationDao = new InstallationDao();
  22. import GljDao from "../../std_glj_lib/models/gljModel";
  23. const stdGljDao = new GljDao();
  24. import stdgljutil from "../../../public/cache/std_glj_type_util";
  25. //add
  26. const stdGLJItemModel = mongoose.model('std_glj_lib_gljList');
  27. const stdGLJItemModelBackup = mongoose.model('std_glj_lib_gljList_backup');
  28. // const _rationItemModelBackup = mongoose.model('std_ration_lib_ration_items_backup');
  29. var rationItemDAO = function () { };
  30. async function getIDMapping(counterName, data) {
  31. const counterInfo = await counter.counterDAO.getIDAfterCount(counterName, data.length);
  32. const maxID = +counterInfo.sequence_value;
  33. const IDMapping = {};
  34. data.forEach((item, index) => {
  35. IDMapping[item.ID] = maxID - (data.length - 1) + index;
  36. });
  37. return IDMapping;
  38. }
  39. // 拷贝分类树
  40. async function copyClassData(sourceLibID, targetLibID) {
  41. const sourceClassData = await stdRationSectionModel.find({ rationRepId: sourceLibID }, '-_id').lean();
  42. const IDMapping = await getIDMapping(counter.moduleName.rationTree, sourceClassData);
  43. const insertData = sourceClassData.map(item => ({
  44. ...item,
  45. rationRepId: targetLibID,
  46. ID: IDMapping[item.ID],
  47. ParentID: IDMapping[item.ParentID] || -1,
  48. NextSiblingID: IDMapping[item.NextSiblingID] || -1,
  49. }));
  50. if (insertData.length) {
  51. await stdRationSectionModel.insertMany(insertData);
  52. }
  53. return IDMapping;
  54. }
  55. // 拷贝子目换算
  56. async function copyCoeData(sourceLibID, targetLibID) {
  57. const sourceCoeData = await stdCoeModel.find({ libID: sourceLibID }, '-_id').lean();
  58. const IDMapping = await getIDMapping(counter.moduleName.coeList, sourceCoeData);
  59. const insertData = sourceCoeData.map(item => ({
  60. ...item,
  61. libID: targetLibID,
  62. ID: IDMapping[item.ID],
  63. }));
  64. if (insertData.length) {
  65. await stdCoeModel.insertMany(insertData);
  66. }
  67. return IDMapping;
  68. }
  69. // 拷贝定额库
  70. rationItemDAO.prototype.copyLib = async function (sourceLibID, targetLibID, sourceGLJLibID, targetGLJLibID) {
  71. const sourceRationData = await rationItemModel.find({ rationRepId: sourceLibID }, '-_id').lean();
  72. const rationIDMapping = await getIDMapping(counter.moduleName.rations, sourceRationData);
  73. const classIDMapping = await copyClassData(sourceLibID, targetLibID);
  74. const coeIDMapping = await copyCoeData(sourceLibID, targetLibID);
  75. const sourceGLJData = await stdGLJItemModel.find({ repositoryId: sourceGLJLibID }, '-_id code ID').lean();
  76. const sourceGLJCodeMapping = {};
  77. sourceGLJData.forEach(glj => sourceGLJCodeMapping[glj.code] = glj.ID);
  78. const targetGLJData = await stdGLJItemModel.find({ repositoryId: targetGLJLibID }, '-_id code ID').lean();
  79. // 旧ID-新ID映射
  80. const gljIDMapping = {};
  81. targetGLJData.forEach(glj => {
  82. const orgID = sourceGLJCodeMapping[glj.code];
  83. if (orgID) {
  84. gljIDMapping[orgID] = glj.ID;
  85. }
  86. });
  87. sourceRationData.forEach(ration => {
  88. ration.rationRepId = targetLibID;
  89. ration.ID = rationIDMapping[ration.ID];
  90. ration.sectionId = classIDMapping[ration.sectionId];
  91. ration.rationCoeList.forEach(coe => {
  92. coe.ID = coeIDMapping[coe.ID];
  93. });
  94. const rationGLJList = [];
  95. ration.rationGljList.forEach(rGLJ => {
  96. const newGLJID = gljIDMapping[rGLJ.gljId];
  97. if (newGLJID) {
  98. rGLJ.gljId = newGLJID;
  99. rationGLJList.push(rGLJ);
  100. }
  101. });
  102. ration.rationGljList = rationGLJList;
  103. });
  104. if (sourceRationData.length) {
  105. await rationItemModel.insertMany(sourceRationData);
  106. }
  107. }
  108. rationItemDAO.prototype.handleGLJCode = async function (rationLibID, gljLibID) {
  109. const rations = await rationItemModel.find({ rationRepId: rationLibID }, 'ID rationGljList').lean();
  110. const gljs = await stdGLJItemModel.find({ repositoryId: gljLibID }, 'ID code').lean();
  111. const gljMap = {};
  112. gljs.forEach(glj => gljMap[glj.ID] = glj.code);
  113. const bulks = [];
  114. rations.forEach(ration => {
  115. if (ration.rationGljList && ration.rationGljList.length) {
  116. ration.rationGljList.forEach(rGLJ => {
  117. rGLJ.gljCode = gljMap[rGLJ.gljId];
  118. });
  119. bulks.push({
  120. updateOne: {
  121. filter: { ID: ration.ID },
  122. update: { $set: { rationGljList: ration.rationGljList } }
  123. }
  124. })
  125. }
  126. });
  127. if (bulks.length) {
  128. await rationItemModel.bulkWrite(bulks);
  129. }
  130. }
  131. rationItemDAO.prototype.updateRationGLJByOrgID = async function (rationLibID, gljLibID) {
  132. const gljList = await stdGLJItemModel.find({ repositoryId: gljLibID }, 'ID orgID').lean();
  133. const IDMap = {};
  134. gljList.forEach(({ orgID, ID }) => IDMap[orgID] = ID);
  135. const rations = await rationItemModel.find({ rationRepId: rationLibID }, 'ID rationGljList').lean();
  136. const bulks = [];
  137. rations
  138. .filter(ration => ration.rationGljList.length)
  139. .forEach(ration => {
  140. const newRationGLJList = [];
  141. ration.rationGljList.forEach(rGLJ => {
  142. const newGLJID = IDMap[rGLJ.gljId];
  143. if (newGLJID) {
  144. newRationGLJList.push({
  145. ...rGLJ,
  146. gljId: newGLJID
  147. });
  148. }
  149. });
  150. bulks.push({
  151. updateOne: {
  152. filter: { ID: ration.ID },
  153. update: { rationGljList: newRationGLJList }
  154. }
  155. })
  156. });
  157. if (bulks.length) {
  158. await rationItemModel.bulkWrite(bulks);
  159. }
  160. }
  161. // 处理部颁数据
  162. rationItemDAO.prototype.handleBBData = async function (rationLibID, gljLibID) {
  163. const rations = await rationItemModel.find({ rationRepId: rationLibID }, '-_id ID rationGljList').lean();
  164. const gljs = await stdGLJItemModel.find({ repositoryId: gljLibID, 'component.0': { $exists: true } }, '-_id ID component').lean();
  165. const gljIDMap = {};
  166. gljs.forEach(glj => gljIDMap[glj.ID] = gljs);
  167. const updateData = [];
  168. const errorRange = 0.004;
  169. for (const ration of rations) {
  170. if (!ration.rationGljList) {
  171. continue;
  172. }
  173. const componentAmtMap = {};
  174. for (const rGLJ of ration.rationGljList) {
  175. const stdGLJ = gljIDMap[rGLJ.gljId];
  176. if (!stdGLJ) {
  177. continue;
  178. }
  179. for (const c of stdGLJ.component) {
  180. const amt = c.consumeAmt * rGLJ.consumeAmt;
  181. if (componentAmtMap[c.ID]) {
  182. componentAmtMap[c.ID] += amt;
  183. } else {
  184. componentAmtMap[c.ID] = amt;
  185. }
  186. }
  187. }
  188. const newRationGljList = [];
  189. let isChanged = false;
  190. for (const rGLJ of ration.rationGljList) {
  191. if (componentAmtMap[rGLJ.gljId]) {
  192. const diff = Math.abs(componentAmtMap[rGLJ.gljId] - rGLJ.consumeAmt);
  193. if (diff <= errorRange) {
  194. isChanged = true;
  195. } else {
  196. newRationGljList.push(rGLJ);
  197. }
  198. } else {
  199. newRationGljList.push(rGLJ);
  200. }
  201. }
  202. if (isChanged) {
  203. updateData.push({
  204. updateOne: {
  205. filter: { ID: ration.ID },
  206. update: { rationGljList: newRationGljList }
  207. }
  208. });
  209. }
  210. }
  211. if (updateData.length) {
  212. await rationItemModel.bulkWrite(updateData);
  213. }
  214. };
  215. // 由于导入excel时,excel数据存在负的工程量,所以导入后一些定额人材机的消耗量可能为负,需要处理
  216. rationItemDAO.prototype.handleMinusQuantity = async function () {
  217. const updateTask = [];
  218. const repIDs = new Set();
  219. const rations = await rationItemModel.find({ 'rationGljList.consumeAmt': { $lt: 0 } }).lean();
  220. for (const ration of rations) {
  221. repIDs.add(ration.rationRepId);
  222. const rationGLJList = [];
  223. for (const rGLJ of ration.rationGljList) {
  224. rationGLJList.push({
  225. gljId: rGLJ.gljId,
  226. consumeAmt: Math.abs(rGLJ.consumeAmt),
  227. proportion: rGLJ.proportion
  228. });
  229. }
  230. updateTask.push({
  231. updateOne: {
  232. filter: { ID: ration.ID },
  233. update: { $set: { rationGljList: rationGLJList } }
  234. }
  235. });
  236. }
  237. if (updateTask.length) {
  238. await rationItemModel.bulkWrite(updateTask);
  239. }
  240. console.log(`repIDs`);
  241. console.log(repIDs);
  242. };
  243. rationItemDAO.prototype.prepareInitData = async function (rationRepId) {
  244. // 定额库
  245. const libTask = stdRationLibModel.findOne({ ID: rationRepId }, '-_id ID dispName gljLib');
  246. // 定额编码
  247. const codesTask = rationItemModel.find({ rationRepId }, '-_id code', { lean: true });
  248. // 定额章节树
  249. const sectionTreeTask = stdRationSectionModel.find({ rationRepId }, '-_id', { lean: true });
  250. // 安装增加费
  251. const installationTask = installationDao.getInstallation(rationRepId);
  252. const [libInfo, codesArr, sectionTree, installationList] = await Promise.all([libTask, codesTask, sectionTreeTask, installationTask]);
  253. const rationsCodes = codesArr.reduce((acc, cur) => {
  254. acc.push(cur.code);
  255. return acc;
  256. }, []);
  257. // 人材机分类树
  258. const gljLibId = libInfo.gljLib;
  259. const gljTreeTask = stdGljDao.getGljTreeSync(gljLibId);
  260. const gljTask = stdGljDao.getGljItemsSync(gljLibId);
  261. const [gljTree, gljList] = await Promise.all([gljTreeTask, gljTask]);
  262. const gljDistTypeList = stdgljutil.getStdGljTypeCacheObj().toArray();
  263. return {
  264. libInfo,
  265. rationsCodes,
  266. sectionTree,
  267. installationList,
  268. gljTree,
  269. gljList,
  270. gljDistTypeList
  271. };
  272. };
  273. //将消耗量为负的人材机改为正的
  274. rationItemDAO.prototype.toPositive = async function (rationRepId) {
  275. let rations = await rationItemModel.find({ rationRepId: rationRepId, 'rationGljList.consumeAmt': { $lt: 0 } });
  276. let task = [];
  277. for (let ration of rations) {
  278. let update = false;
  279. for (let rGlj of ration.rationGljList) {
  280. if (rGlj.consumeAmt < 0) {
  281. update = true;
  282. rGlj.consumeAmt = Math.abs(rGlj.consumeAmt);
  283. }
  284. }
  285. if (update) {
  286. task.push({ updateOne: { filter: { ID: ration.ID }, update: { rationGljList: ration.rationGljList } } });
  287. }
  288. }
  289. if (task.length > 0) {
  290. await rationItemModel.bulkWrite(task);
  291. }
  292. };
  293. rationItemDAO.prototype.getRationItemsByLib = async function (rationRepId, showHint = null, returnFields = '') {
  294. let rationLib = await stdRationLibModel.findOne({ ID: rationRepId, deleted: false });
  295. if (!rationLib) {
  296. return [];
  297. }
  298. let startDate = new Date();
  299. let rations = await rationItemModel.find({ rationRepId: rationRepId }, returnFields);
  300. console.log(`Date: ${new Date() - startDate}====================================`);
  301. if (!showHint) {
  302. return rations;
  303. }
  304. else {
  305. const stdBillsLibListsModel = new STDGLJListModel();
  306. const stdGLJData = await stdBillsLibListsModel.getGljItemsByRepId(rationLib.gljLib, '-_id ID code name unit gljType');
  307. let gljMapping = {};
  308. for (let glj of stdGLJData) {
  309. gljMapping[glj.ID] = glj;
  310. }
  311. //设置悬浮
  312. for (let ration of rations) {
  313. let hintsArr = [];
  314. //对人材机进行排序
  315. ration.rationGljList.sort(function (a, b) {
  316. let gljA = gljMapping[a.gljId],
  317. gljB = gljMapping[b.gljId];
  318. if (gljA && gljB) {
  319. let aV = gljA.gljType + gljA.code,
  320. bV = gljB.gljType + gljB.code;
  321. if (aV > bV) {
  322. return 1;
  323. } else if (aV < bV) {
  324. return -1;
  325. }
  326. }
  327. return 0;
  328. });
  329. for (let rationGlj of ration.rationGljList) {
  330. let subGlj = gljMapping[rationGlj.gljId];
  331. if (subGlj) {
  332. hintsArr.push(` ${subGlj.code} ${subGlj.name}${subGlj.specs ? '&nbsp;&nbsp;&nbsp;' + subGlj.specs : ''}&nbsp;&nbsp&nbsp;${subGlj.unit}&nbsp;&nbsp;&nbsp;${rationGlj.consumeAmt}`);
  333. }
  334. }
  335. hintsArr.push(`基价 元 ${ration.basePrice}`);
  336. if (ration.jobContent && ration.jobContent.toString().trim() !== '') {
  337. hintsArr.push(`工作内容:`);
  338. hintsArr = hintsArr.concat(ration.jobContent.split('\n'));
  339. }
  340. if (ration.annotation && ration.annotation.toString().trim() !== '') {
  341. hintsArr.push(`附注:`);
  342. hintsArr = hintsArr.concat(ration.annotation.split('\n'));
  343. }
  344. ration._doc.hint = hintsArr.join('<br>');
  345. }
  346. return rations;
  347. }
  348. };
  349. rationItemDAO.prototype.sortToNumber = function (datas) {
  350. for (let i = 0, len = datas.length; i < len; i++) {
  351. let data = datas[i]._doc;
  352. if (_exist(data, 'labourPrice')) {
  353. data['labourPrice'] = parseFloat(data['labourPrice']);
  354. }
  355. if (_exist(data, 'materialPrice')) {
  356. data['materialPrice'] = parseFloat(data['materialPrice']);
  357. }
  358. if (_exist(data, 'machinePrice')) {
  359. data['machinePrice'] = parseFloat(data['machinePrice']);
  360. }
  361. if (_exist(data, 'basePrice')) {
  362. data['basePrice'] = parseFloat(data['basePrice']);
  363. }
  364. if (_exist(data, 'rationGljList')) {
  365. for (let j = 0, jLen = data['rationGljList'].length; j < jLen; j++) {
  366. let raGljObj = data['rationGljList'][j]._doc;
  367. if (_exist(raGljObj, 'consumeAmt')) {
  368. raGljObj['consumeAmt'] = parseFloat(raGljObj['consumeAmt']);
  369. }
  370. }
  371. }
  372. }
  373. function _exist(data, attr) {
  374. return data && data[attr] !== undefined && data[attr];
  375. }
  376. };
  377. rationItemDAO.prototype.getRationItemsBySection = async function (rationRepId, sectionId, callback) {
  378. let me = this;
  379. try {
  380. let rations = await rationItemModel.find({ rationRepId: rationRepId, sectionId: sectionId });
  381. me.sortToNumber(rations);
  382. let matchRationIDs = [],
  383. matchRations = [];
  384. for (let ration of rations) {
  385. if (ration.rationTemplateList) {
  386. for (let rt of ration.rationTemplateList) {
  387. if (rt.rationID) {
  388. matchRationIDs.push(rt.rationID);
  389. }
  390. }
  391. }
  392. }
  393. if (matchRationIDs.length > 0) {
  394. matchRations = await rationItemModel.find({ ID: { $in: matchRationIDs } }, '-_id ID code name');
  395. }
  396. for (let mr of matchRations) {
  397. for (let ration of rations) {
  398. if (ration.rationTemplateList) {
  399. for (let rt of ration.rationTemplateList) {
  400. if (rt.rationID && rt.rationID === mr.ID) {
  401. rt.code = mr.code ? mr.code : '';
  402. rt.name = mr.name ? mr.name : '';
  403. }
  404. }
  405. }
  406. }
  407. }
  408. callback(false, "Get items successfully", rations);
  409. } catch (err) {
  410. console.log(err);
  411. callback(true, "Fail to get items", "");
  412. }
  413. /* rationItemModel.find({"rationRepId": rationRepId, "sectionId": sectionId, "$or": [{"isDeleted": null}, {"isDeleted": false} ]},function(err,data){
  414. if(err) callback(true, "Fail to get items", "");
  415. else {
  416. me.sortToNumber(data);
  417. callback(false,"Get items successfully", data);
  418. }
  419. })*/
  420. };
  421. rationItemDAO.prototype.mixUpdateRationItems = function (rationLibId, lastOpr, sectionId, updateItems, addItems, rIds, callback) {
  422. var me = this;
  423. if (updateItems.length == 0 && rIds.length == 0) {
  424. me.addRationItems(rationLibId, lastOpr, sectionId, addItems, callback);
  425. } else {
  426. me.removeRationItems(rationLibId, lastOpr, rIds, function (err, message, docs) {
  427. if (err) {
  428. callback(true, "Fail to remove", false);
  429. } else {
  430. me.updateRationItems(rationLibId, lastOpr, sectionId, updateItems, function (err, results) {
  431. if (err) {
  432. callback(true, "Fail to save", false);
  433. } else {
  434. if (addItems && addItems.length > 0) {
  435. me.addRationItems(rationLibId, lastOpr, sectionId, addItems, callback);
  436. } else {
  437. callback(false, "Save successfully", results);
  438. }
  439. }
  440. });
  441. }
  442. })
  443. }
  444. };
  445. rationItemDAO.prototype.removeRationItems = function (rationLibId, lastOpr, rIds, callback) {
  446. if (rIds.length > 0) {
  447. rationItemModel.collection.remove({ ID: { $in: rIds } }, null, function (err, docs) {
  448. if (err) {
  449. callback(true, "Fail to remove", false);
  450. } else {
  451. rationRepositoryDao.updateOprArr({ ID: rationLibId }, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  452. if (!err) {
  453. rationItemModel.update({ rationRepId: rationLibId }, { $pull: { rationTemplateList: { rationID: { $in: rIds } } } }, function (theErr) {
  454. if (!theErr) {
  455. callback(false, "Remove successfully", docs);
  456. } else {
  457. callback(true, "Fail to remove", false);
  458. }
  459. });
  460. } else {
  461. callback(true, "Fail to remove", false);
  462. }
  463. })
  464. }
  465. })
  466. } else {
  467. callback(false, "No records were deleted!", null);
  468. }
  469. };
  470. rationItemDAO.prototype.getRationItemsByCode = function (repId, code, callback) {
  471. rationItemModel.find({ "rationRepId": repId, "code": { '$regex': code, $options: '$i' }, "$or": [{ "isDeleted": null }, { "isDeleted": false }] }, function (err, data) {
  472. if (err) callback(true, "Fail to get items", "")
  473. else callback(false, "Get items successfully", data);
  474. })
  475. };
  476. rationItemDAO.prototype.findRation = function (repId, keyword, callback) {
  477. var filter = {
  478. 'rationRepId': repId,
  479. '$and': [{
  480. '$or': [{ 'code': { '$regex': keyword, $options: '$i' } }, { 'name': { '$regex': keyword, $options: '$i' } }]
  481. }, {
  482. '$or': [{ 'isDeleted': { "$exists": false } }, { 'isDeleted': null }, { 'isDeleted': false }]
  483. }]
  484. };
  485. rationItemModel.find(filter, function (err, data) {
  486. if (err) {
  487. callback(true, 'Fail to find ration', null);
  488. } else {
  489. callback(false, '', data);
  490. }
  491. })
  492. }
  493. rationItemDAO.prototype.getRationItem = async function (repId, code) {
  494. let ration = await rationItemModel.findOne({ rationRepId: repId, code: code });
  495. return ration;
  496. };
  497. rationItemDAO.prototype.addRationItems = function (rationLibId, lastOpr, sectionId, items, callback) {
  498. if (items && items.length > 0) {
  499. counter.counterDAO.getIDAfterCount(counter.moduleName.rations, items.length, function (err, result) {
  500. var maxId = result.sequence_value;
  501. var arr = [];
  502. for (var i = 0; i < items.length; i++) {
  503. var obj = new rationItemModel(items[i]);
  504. obj.ID = (maxId - (items.length - 1) + i);
  505. obj.sectionId = sectionId;
  506. obj.rationRepId = rationLibId;
  507. arr.push(obj);
  508. }
  509. rationItemModel.collection.insert(arr, null, function (err, docs) {
  510. if (err) {
  511. callback(true, "Fail to save", false);
  512. } else {
  513. rationRepositoryDao.updateOprArr({ ID: rationLibId }, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  514. if (err) {
  515. callback(true, "Fail to sava operator", false);
  516. }
  517. else {
  518. callback(false, "Save successfully", docs);
  519. }
  520. })
  521. }
  522. })
  523. });
  524. } else {
  525. callback(true, "Source error!", false);
  526. }
  527. };
  528. rationItemDAO.prototype.updateRationItems = function (rationLibId, lastOpr, sectionId, items, callback) {
  529. console.log('enter============');
  530. var functions = [];
  531. for (var i = 0; i < items.length; i++) {
  532. functions.push((function (doc) {
  533. return function (cb) {
  534. var filter = {};
  535. if (doc.ID) {
  536. filter.ID = doc.ID;
  537. } else {
  538. filter.sectionId = sectionId;
  539. if (rationLibId) filter.rationRepId = rationLibId;
  540. filter.code = doc.code;
  541. }
  542. rationItemModel.update(filter, doc, cb);
  543. };
  544. })(items[i]));
  545. }
  546. functions.push((function () {
  547. return function (cb) {
  548. rationRepositoryDao.updateOprArr({ ID: rationLibId }, 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. async.parallel(functions, function (err, results) {
  559. callback(err, results);
  560. });
  561. };
  562. //ration round func
  563. function round(v, e) {
  564. var t = 1;
  565. for (; e > 0; t *= 10, e--);
  566. for (; e < 0; t /= 10, e++);
  567. return Math.round(v * t) / t;
  568. }
  569. rationItemDAO.prototype.updateRationBasePrc = function (basePrcArr, callback) {
  570. async.each(basePrcArr, function (basePrcObj, finalCb) {
  571. let adjGljId = basePrcObj.gljId, adjBasePrice = basePrcObj.basePrice, adjGljType = basePrcObj.gljType;
  572. async.waterfall([
  573. function (cb) {
  574. if (typeof basePrcObj.delete !== 'undefined' && basePrcObj.delete === 1) {
  575. rationItemModel.find({ 'rationGljList.gljId': adjGljId }, { ID: 1, rationGljList: 1 }, function (err, result) {
  576. if (err) {
  577. cb(err);
  578. }
  579. else {
  580. //删除
  581. rationItemModel.update({ 'rationGljList.gljId': adjGljId }, { $pull: { rationGljList: { gljId: adjGljId } } }, { multi: true }, function (err) {
  582. if (err) {
  583. cb(err);
  584. }
  585. else {
  586. //补充定额
  587. compleRationModel.find({ 'rationGljList.gljId': adjGljId }, { ID: 1, rationGljList: 1 }, function (err, compleRst) {
  588. if (err) {
  589. cb(err);
  590. }
  591. else {
  592. compleRationModel.update({ 'rationGljList.gljId': adjGljId }, { $pull: { rationGljList: { gljId: adjGljId } } }, { multi: true }, function (err) {
  593. if (err) {
  594. cb(err);
  595. }
  596. else {
  597. for (let i = 0, len = compleRst.length; i < len; i++) {
  598. compleRst[i]._doc.type = 'complementary';
  599. }
  600. cb(null, result.concat(compleRst));
  601. }
  602. });
  603. }
  604. });
  605. }
  606. });
  607. }
  608. });
  609. }
  610. else {
  611. rationItemModel.find({ 'rationGljList.gljId': adjGljId }, { ID: 1, rationGljList: 1 }, function (err, result) {
  612. if (err) {
  613. cb(err);
  614. }
  615. else {
  616. compleRationModel.find({ 'rationGljList.gljId': adjGljId }, { ID: 1, rationGljList: 1 }, function (err, compleRst) {
  617. if (err) {
  618. cb(err);
  619. }
  620. else {
  621. for (let i = 0, len = compleRst.length; i < len; i++) {
  622. compleRst[i]._doc.type = 'complementary';
  623. }
  624. cb(null, result.concat(compleRst));
  625. }
  626. });
  627. }
  628. });
  629. }
  630. },
  631. function (result, cb) {
  632. let compleRTasks = [], stdRTasks = [];
  633. //重算时需要用到的所有工料机,一次性取
  634. let compleGljIds = [], stdGljIds = [];
  635. for (let ration of result) {
  636. for (let glj of ration.rationGljList) {
  637. if (glj.type !== undefined && glj.type === 'complementary') {
  638. compleGljIds.push(glj.gljId);
  639. }
  640. else {
  641. stdGljIds.push(glj.gljId);
  642. }
  643. }
  644. }
  645. gljDao.getStdCompleGljItems(compleGljIds, stdGljIds, function (err, allGljs) {
  646. if (err) {
  647. cb(err);
  648. }
  649. else {
  650. let gljIndex = {};
  651. for (let glj of allGljs) {
  652. gljIndex[glj.ID] = glj;
  653. }
  654. async.each(result, function (rationItem, ecb) {
  655. let rationGljList = rationItem.rationGljList;
  656. let gljArr = [];
  657. for (let i = 0; i < rationGljList.length; i++) {
  658. let theGlj = gljIndex[rationGljList[i].gljId];
  659. if (theGlj !== undefined && theGlj) {
  660. if (theGlj.ID === adjGljId) {
  661. gljArr.push({ gljId: theGlj.ID, basePrice: adjBasePrice, consumeAmt: rationGljList[i].consumeAmt });
  662. } else {
  663. if (theGlj.priceProperty && Object.keys(theGlj.priceProperty).length > 0) {
  664. let priceKeys = Object.keys(theGlj.priceProperty);
  665. gljArr.push({ gljId: theGlj.ID, basePrice: parseFloat(theGlj.priceProperty[priceKeys[0]]), consumeAmt: rationGljList[i].consumeAmt });
  666. } else {
  667. gljArr.push({ gljId: theGlj.ID, basePrice: parseFloat(theGlj.basePrice), consumeAmt: rationGljList[i].consumeAmt });
  668. }
  669. }
  670. }
  671. }
  672. //recalculate the price of ration
  673. let basePrice = 0;
  674. gljArr.forEach(function (gljItem) {
  675. basePrice += gljItem.basePrice * gljItem.consumeAmt;
  676. });
  677. basePrice = scMathUtil.roundTo(basePrice, 0);
  678. let task = {
  679. updateOne: {
  680. filter: {
  681. ID: rationItem.ID
  682. },
  683. update: {
  684. basePrice: basePrice.toString()
  685. }
  686. }
  687. };
  688. //updateDataBase
  689. if (rationItem._doc.type !== undefined && rationItem._doc.type === 'complementary') {
  690. compleRTasks.push(task);
  691. ecb(null);
  692. }
  693. else {
  694. stdRTasks.push(task);
  695. ecb(null);
  696. }
  697. }, async function (err) {
  698. if (err) {
  699. cb(err);
  700. }
  701. else {
  702. //do sth
  703. try {
  704. if (compleRTasks.length > 0) {
  705. await compleRationModel.bulkWrite(compleRTasks);
  706. }
  707. if (stdRTasks.length > 0) {
  708. await rationItemModel.bulkWrite(stdRTasks);
  709. }
  710. }
  711. catch (e) {
  712. cb(err);
  713. }
  714. cb(null);
  715. }
  716. });
  717. }
  718. });
  719. },
  720. ], function (err) {
  721. if (err) {
  722. finalCb(err);
  723. }
  724. else {
  725. finalCb(null);
  726. }
  727. });
  728. }, function (err) {
  729. if (err) {
  730. callback(err, 'Error');
  731. }
  732. else {
  733. callback(null, '');
  734. }
  735. });
  736. };
  737. rationItemDAO.prototype.getRationGljIds = function (data, callback) {
  738. let repId = data.repId;
  739. rationItemModel.find({ rationRepId: repId }, function (err, result) {
  740. if (err) {
  741. callback(err, 'Error', null);
  742. }
  743. else {
  744. let rstIds = [], newRst = [];
  745. result.forEach(function (data) {
  746. if (data.rationGljList.length > 0) {
  747. data.rationGljList.forEach(function (gljObj) {
  748. rstIds.push(gljObj.gljId);
  749. })
  750. }
  751. });
  752. for (let i = 0; i < rstIds.length; i++) {
  753. if (newRst.indexOf(rstIds[i]) === -1) {
  754. newRst.push(rstIds[i]);
  755. }
  756. }
  757. callback(null, '', newRst);
  758. }
  759. });
  760. };
  761. rationItemDAO.prototype.getRationsCodes = function (data, callback) {
  762. let repId = data.repId;
  763. rationItemModel.find({ rationRepId: repId, isDeleted: false }, function (err, result) {
  764. if (err) {
  765. callback(err, 'Error', null);
  766. }
  767. else {
  768. let rstCodes = [];
  769. result.forEach(function (rationItem) {
  770. rstCodes.push(rationItem.code);
  771. });
  772. callback(null, 'get all rationCodes success', rstCodes);
  773. }
  774. })
  775. };
  776. rationItemDAO.prototype.updateJobContent = function (lastOpr, repId, updateArr, callback) {
  777. rationRepositoryDao.updateOprArr({ ID: repId }, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  778. async.each(updateArr, function (obj, cb) {
  779. rationItemModel.update({ rationRepId: repId, code: obj.code }, { $set: { jobContent: obj.jobContent } }, function (err) {
  780. if (err) {
  781. cb(err);
  782. }
  783. else {
  784. cb(null);
  785. }
  786. })
  787. }, function (err) {
  788. if (err) {
  789. callback(err);
  790. }
  791. else {
  792. callback(null);
  793. }
  794. });
  795. });
  796. }
  797. rationItemDAO.prototype.updateAnnotation = function (lastOpr, repId, updateArr, callback) {
  798. rationRepositoryDao.updateOprArr({ ID: repId }, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
  799. async.each(updateArr, function (obj, cb) {
  800. rationItemModel.update({ rationRepId: repId, code: obj.code }, { $set: { annotation: obj.annotation } }, function (err) {
  801. if (err) {
  802. cb(err);
  803. }
  804. else {
  805. cb(null);
  806. }
  807. })
  808. }, function (err) {
  809. if (err) {
  810. callback(err);
  811. }
  812. else {
  813. callback(null);
  814. }
  815. });
  816. });
  817. };
  818. //更新定额下模板关联
  819. rationItemDAO.prototype.updateRationTemplate = async function (rationRepId, rationID, templateData) {
  820. //自动匹配定额
  821. let matachCodes = [],
  822. matchRations = [];
  823. //要保存的数据
  824. let saveData = [];
  825. for (let data of templateData) {
  826. if (data.code) {
  827. matachCodes.push(data.code);
  828. }
  829. }
  830. matachCodes = Array.from(new Set(matachCodes));
  831. if (matachCodes.length > 0) {
  832. matchRations = await rationItemModel.find({ rationRepId: rationRepId, code: { $in: matachCodes } }, '-_id ID code name');
  833. }
  834. let validData = [];
  835. //设置展示数据
  836. for (let data of templateData) {
  837. let match = false;
  838. for (let ration of matchRations) {
  839. if (data.code && data.code === ration.code) {
  840. match = true;
  841. data.name = ration.name;
  842. data.rationID = ration.ID;
  843. break;
  844. }
  845. }
  846. if (!match) {
  847. data.code = '';
  848. data.name = '';
  849. }
  850. if (data.type || data.code || data.name || data.billsLocation) {
  851. validData.push(data);
  852. }
  853. }
  854. for (let data of validData) {
  855. saveData.push({ rationID: data.rationID ? data.rationID : null, type: data.type, billsLocation: data.billsLocation });
  856. }
  857. //更新
  858. await rationItemModel.update({ ID: rationID }, { $set: { rationTemplateList: saveData } });
  859. return validData;
  860. };
  861. //计算导入数据的价格
  862. rationItemDAO.prototype.calcForRation = function (stdGljList, ration) {
  863. let rationGljList = ration.rationGljList;
  864. let basePrice = 0;
  865. for (let rationGlj of rationGljList) {
  866. let glj = stdGljList[rationGlj.gljId];
  867. if (glj) {
  868. basePrice += glj.basePrice * rationGlj.consumeAmt;
  869. }
  870. }
  871. ration.basePrice = scMathUtil.roundTo(basePrice, 0).toString();
  872. };
  873. /**
  874. * 根据条件获取定额数据
  875. *
  876. * @param {Object} condition
  877. * @param {Object} fields
  878. * @param {String} indexBy
  879. * @return {Promise|Array}
  880. */
  881. rationItemDAO.prototype.getRationItemByCondition = async function (condition, fields = null, indexBy = null) {
  882. let result = [];
  883. if (Object.keys(condition).length <= 0) {
  884. return result;
  885. }
  886. result = await rationItemModel.find(condition, fields).sort({ code: 1 });
  887. if (indexBy !== null && result.length > 0) {
  888. let tmpResult = {};
  889. for (let tmp of result) {
  890. tmpResult[tmp[indexBy]] = tmp;
  891. }
  892. result = tmpResult;
  893. }
  894. return result;
  895. };
  896. /**
  897. * 从excel中批量新增数据
  898. *
  899. * @param {Number} rationRepId
  900. * @param {Array} data
  901. * @return {bool}
  902. */
  903. rationItemDAO.prototype.batchAddFromExcel = async function (rationRepId, data) {
  904. if (data.length <= 0) {
  905. return false;
  906. }
  907. // 获取定额库相关数据
  908. const rationRepository = await rationRepositoryDao.getRepositoryById(rationRepId);
  909. if (rationRepository.length !== 1 || rationRepository[0].gljLib === undefined) {
  910. return false;
  911. }
  912. // 获取标准工料机库数据
  913. const stdBillsLibListsModel = new STDGLJListModel();
  914. const stdGLJData = await stdBillsLibListsModel.getGljItemsByRepId(rationRepository[0].gljLib);
  915. // 整理标准工料机库数据
  916. let stdGLJList = {};
  917. let stdGLJListByID = {};
  918. for (const tmp of stdGLJData) {
  919. stdGLJList[tmp.code.toString()] = tmp.ID;
  920. stdGLJListByID[tmp.ID] = tmp;
  921. }
  922. let lastData = {};
  923. const rationData = [];
  924. // 编码列表,用于查找库中是否有对应数据
  925. let rationCodeList = [];
  926. let gljCodeList = [];
  927. // 插入失败的工料机列表(用于提示)
  928. this.failGLJList = [];
  929. for (const tmp of data) {
  930. if (tmp.length <= 0) {
  931. continue;
  932. }
  933. console.log(typeof tmp[0], tmp[0]);
  934. // 如果第一个字段为null则是工料机数据,放入上一个数据的工料机字段
  935. if (!tmp[0] && Object.keys(lastData).length > 0) {
  936. // 如果不存在对应的工料机库数据则跳过
  937. if (!stdGLJList[tmp[1]]) {
  938. const failString = '定额' + lastData.code + '下的' + tmp[1];
  939. this.failGLJList.push(failString);
  940. continue;
  941. }
  942. const tmpRationGlj = {
  943. gljId: stdGLJList[tmp[1]],
  944. consumeAmt: Math.abs(tmp[4]),
  945. proportion: 0,
  946. };
  947. lastData.rationGljList.push(tmpRationGlj);
  948. if (gljCodeList.indexOf(tmp[1]) < 0) {
  949. gljCodeList.push(tmp[1]);
  950. }
  951. continue;
  952. }
  953. if (tmp[0] === '定额' && Object.keys(lastData).length > 0) {
  954. rationData.push(lastData);
  955. }
  956. // 组装数据
  957. lastData = {
  958. code: tmp[1],
  959. name: tmp[2],
  960. unit: tmp[3],
  961. caption: tmp[2],
  962. rationRepId: rationRepId,
  963. sectionId: 0,
  964. labourPrice: '0',
  965. materialPrice: '0',
  966. machinePrice: '0',
  967. basePrice: '0',
  968. rationGljList: []
  969. };
  970. // 防止重复加入
  971. if (rationCodeList.indexOf(tmp[1]) < 0) {
  972. rationCodeList.push(tmp[1]);
  973. }
  974. }
  975. // 最后一个入数组
  976. rationData.push(lastData);
  977. // 查找数据库中是否已存在待插入数据
  978. const condition = {
  979. rationRepId: rationRepId,
  980. code: { $in: rationCodeList }
  981. };
  982. const existCodeList = await this.getRationItemByCondition(condition, ['code'], 'code');
  983. // 过滤插入数据
  984. let insertData = [];
  985. //已存在定额,则更新价格及rationGLjList字段
  986. let updateData = [];
  987. for (const ration of rationData) {
  988. if (existCodeList[ration.code] !== undefined) {
  989. updateData.push(ration);
  990. continue;
  991. }
  992. insertData.push(ration);
  993. }
  994. //更新定额
  995. let updateBulk = [];
  996. for (let ration of updateData) {
  997. this.calcForRation(stdGLJListByID, ration);
  998. updateBulk.push({
  999. updateOne: {
  1000. filter: { rationRepId: rationRepId, code: ration.code },
  1001. update: { $set: { rationGljList: ration.rationGljList, basePrice: ration.basePrice } }
  1002. }
  1003. });
  1004. }
  1005. //更新数据库
  1006. if (updateBulk.length > 0) {
  1007. await rationItemModel.bulkWrite(updateBulk);
  1008. }
  1009. // 如果都已经存在,直接返回
  1010. if (insertData.length <= 0) {
  1011. return true;
  1012. }
  1013. //计算价格
  1014. for (let ration of insertData) {
  1015. this.calcForRation(stdGLJListByID, ration);
  1016. }
  1017. // 组织id
  1018. const counterInfo = await counter.counterDAO.getIDAfterCount(counter.moduleName.rations, insertData.length);
  1019. let maxId = counterInfo.sequence_value;
  1020. maxId = parseInt(maxId);
  1021. let count = 0;
  1022. for (const index in insertData) {
  1023. insertData[index].ID = maxId - (insertData.length - 1) + count;
  1024. count++;
  1025. }
  1026. // 插入数据库
  1027. const result = await rationItemModel.create(insertData);
  1028. return result.length > 0;
  1029. };
  1030. /**
  1031. * 导出到excel的数据
  1032. *
  1033. * @param {Number} rationRepId
  1034. * @return {Array}
  1035. */
  1036. rationItemDAO.prototype.exportExcelData = async function (rationRepId) {
  1037. const condition = {
  1038. rationRepId: rationRepId
  1039. };
  1040. // @todo 限制导出的数量以防内存溢出
  1041. const rationDataList = await this.getRationItemByCondition(condition, ['name', 'code', 'ID', 'sectionId', 'feeType', 'caption', 'basePrice', 'jobContent', 'annotation', 'unit']);
  1042. // 整理数据
  1043. let rationData = [];
  1044. for (const tmp of rationDataList) {
  1045. const sectionId = tmp.sectionId <= 0 || tmp.sectionId === undefined ? null : tmp.sectionId;
  1046. const feeType = tmp.feeType === '' || tmp.feeType === undefined ? null : tmp.feeType;
  1047. const ration = [sectionId, feeType, tmp.ID, tmp.code, tmp.name, tmp.caption, tmp.basePrice, tmp.jobContent, tmp.annotation, tmp.unit];
  1048. rationData.push(ration);
  1049. }
  1050. //根据编号排序,优先级:number-number-..., number, Anumber....
  1051. /*let regConnector = /-/g,
  1052. regLetter = /[a-z,A-Z]/g,
  1053. regNum = /\d+/g;
  1054. rationData.sort(function (a, b) {
  1055. let aCode = a[3],
  1056. bCode = b[3],
  1057. rst = 0;
  1058. function compareConnector(arrA, arrB) {
  1059. let lessArr = arrA.length <= arrB ? arrA : arrB;
  1060. for (let i = 0; i < lessArr.length; i++) {
  1061. let result = compareUnit(arrA[i], arrB[i]);
  1062. if (result !== 0) {
  1063. return result;
  1064. } else {
  1065. }
  1066. }
  1067. function compareUnit(uA, uB) {
  1068. let uAV = parseFloat(uA),
  1069. uBV = parseFloat(uB);
  1070. if (uAV > uBV) {
  1071. return 1;
  1072. } else if (uAV < uBV) {
  1073. return -1;
  1074. }
  1075. return 0;
  1076. }
  1077. }
  1078. if (regConnector.test(a) && !regConnector.test(b)) {
  1079. rst = -1;
  1080. } else if (!regConnector.test(a) && regConnector.test(b)) {
  1081. rst = 1;
  1082. } else if (regConnector.test(a) && regConnector.test(b)) {
  1083. }
  1084. });
  1085. rationData.sort(function (a, b) {
  1086. let aCode = a[3],
  1087. bCode = b[3],
  1088. rst = 0,
  1089. splitA = aCode.split('-'),
  1090. splitB = bCode.split('-');
  1091. if(splitA[0] > splitB[0]){
  1092. rst = 1;
  1093. }
  1094. else if(splitA[0] < splitB[0]){
  1095. rst = -1;
  1096. }
  1097. else {
  1098. if(splitA[1] && splitB[1]){
  1099. let floatA = parseFloat(splitA[1]),
  1100. floatB = parseFloat(splitB[1]);
  1101. if(floatA > floatB){
  1102. rst = 1;
  1103. }
  1104. else if(floatA < floatB){
  1105. rst = -1;
  1106. }
  1107. }
  1108. }
  1109. return rst;
  1110. });*/
  1111. const excelData = [['树ID', '取费专业', '定额ID', '定额编码', '定额名', '定额显示名称', '基价', '工作内容', '附注', '单位']];
  1112. excelData.push.apply(excelData, rationData);
  1113. return excelData;
  1114. };
  1115. /**
  1116. * 批量更改章节id
  1117. *
  1118. * @param {Object} data
  1119. * @return {bool}
  1120. */
  1121. rationItemDAO.prototype.batchUpdateSectionIdFromExcel = async function (data) {
  1122. if (data.length <= 0) {
  1123. return false;
  1124. }
  1125. // 批量执行update
  1126. let rationTasks = [],
  1127. sectionIDs = [];
  1128. for (const tmp of data) {
  1129. let rationId = parseInt(tmp[2]);
  1130. rationId = isNaN(rationId) || rationId <= 0 ? 0 : rationId;
  1131. let sectionId = parseInt(tmp[0]);
  1132. sectionId = isNaN(sectionId) || sectionId <= 0 ? 0 : sectionId;
  1133. if (sectionId <= 0 || rationId <= 0) {
  1134. continue;
  1135. }
  1136. sectionIDs.push(sectionId);
  1137. // 取费专业
  1138. let feeType = tmp[1] || '';
  1139. let name = tmp[4];
  1140. name = name ? name : '';
  1141. let caption = tmp[5];
  1142. caption = caption ? caption : '';
  1143. let jobContent = tmp[7] ? tmp[7] : '';
  1144. let annotation = tmp[8] ? tmp[8] : '';
  1145. rationTasks.push({
  1146. updateOne: {
  1147. filter: { ID: rationId },
  1148. update: {
  1149. $set: {
  1150. sectionId,
  1151. feeType,
  1152. name,
  1153. caption,
  1154. jobContent,
  1155. annotation
  1156. }
  1157. }
  1158. }
  1159. });
  1160. }
  1161. if (rationTasks.length <= 0) {
  1162. throw '无有效数据(树ID、定额ID不为空、且为数值)';
  1163. }
  1164. // 更新定额数据
  1165. await rationItemModel.bulkWrite(rationTasks);
  1166. // 更新章节树工作内容、附注节点选项(全设置为ALL)
  1167. sectionIDs = Array.from(new Set(sectionIDs));
  1168. if (sectionIDs.length) {
  1169. await stdRationSectionModel.updateMany(
  1170. { ID: { $in: sectionIDs } },
  1171. {
  1172. $set: {
  1173. jobContentSituation: 'ALL',
  1174. annotationSituation: 'ALL'
  1175. }
  1176. }
  1177. )
  1178. }
  1179. };
  1180. module.exports = new rationItemDAO();