ration_item.js 46 KB

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