ration_item.js 47 KB

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