glj_list_model.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. /**
  2. * 项目工料机列表数据模型
  3. *
  4. * @author CaiAoLin
  5. * @date 2017/6/22
  6. * @version
  7. */
  8. import BaseModel from "../../common/base/base_model";
  9. import {default as GLJSchemas, collectionName as gljCollectionName} from "./schemas/glj";
  10. import CounterModel from "./counter_model";
  11. import UnitPriceModel from "./unit_price_model";
  12. import UnitPriceFileModel from "./unit_price_file_model";
  13. import GLJTypeConst from "../../common/const/glj_type_const";
  14. import RationGLJFacade from "../../ration_glj/facade/ration_glj_facade";
  15. import STDGLJLibGLJListModel from "../../common/std/std_glj_lib_glj_list_model";
  16. import MixRatioModel from "./mix_ratio_model";
  17. import GljModel from "../../complementary_glj_lib/models/gljModel";
  18. const ProjectModel = require('../../pm/models/project_model').project;
  19. const scMathUtil = require('../../../public/scMathUtil').getUtil();
  20. class GLJListModel extends BaseModel {
  21. /**
  22. * 材料、主材、设备类型id
  23. *
  24. * @var {Array}
  25. */
  26. materialIdList = [GLJTypeConst.GENERAL_MATERIAL, GLJTypeConst.CONCRETE, GLJTypeConst.MORTAR, GLJTypeConst.MIX_RATIO,
  27. GLJTypeConst.COMMERCIAL_CONCRETE, GLJTypeConst.COMMERCIAL_MORTAR, GLJTypeConst.MAIN_MATERIAL,
  28. GLJTypeConst.EQUIPMENT];
  29. /**
  30. * 拥有组成物的工料机类型id
  31. *
  32. * @var {Array}
  33. */
  34. ownCompositionTypes = [GLJTypeConst.CONCRETE, GLJTypeConst.MORTAR, GLJTypeConst.MIX_RATIO,
  35. GLJTypeConst.COMMERCIAL_CONCRETE, GLJTypeConst.COMMERCIAL_MORTAR, GLJTypeConst.GENERAL_MACHINE];
  36. /**
  37. * 构造函数
  38. *
  39. * @return {void}
  40. */
  41. constructor() {
  42. let parent = super();
  43. parent.model = GLJSchemas;
  44. parent.init();
  45. }
  46. /**
  47. * 设置场景
  48. *
  49. * @param {string} scene
  50. * @return {void}
  51. */
  52. setScene(scene = '') {
  53. switch (scene) {
  54. // 新增数据的验证规则
  55. case 'add':
  56. this.model.schema.path('glj_id').required(true);
  57. this.model.schema.path('project_id').required(true);
  58. this.model.schema.path('code').required(true);
  59. // this.model.schema.path('name').required(true);
  60. break;
  61. }
  62. }
  63. /**
  64. * 根据标段对应项目工料机列表
  65. *
  66. * @param {Number} projectId
  67. * @param {Number} unitPriceFileId
  68. * @return {Promise}
  69. */
  70. async getListByProjectId(projectId, unitPriceFileId) {
  71. let gljData = null;
  72. let mixRatioConnectData = {};
  73. let mixRationMap={};
  74. try {
  75. // 首先获取对应标段下所有的项目工料机数据
  76. let condition = {project_id: projectId};
  77. let fields = {_id: 0};
  78. gljData = await this.db.find(condition, fields);
  79. // 没有数据则直接返回空
  80. if (gljData.length <= 0) {
  81. throw '无数据';
  82. }
  83. // 获取标段设置的单价文件数据
  84. let unitPriceModel = new UnitPriceModel();
  85. let unitPriceList = await unitPriceModel.getDataByFileId(unitPriceFileId);
  86. // 整理获取工料机ID list
  87. let gljIdList = [];
  88. for(let tmp of gljData) {
  89. gljIdList.push(tmp.id);
  90. }
  91. // 从定额工料机库中获取消耗量
  92. condition = {
  93. projectID: projectId,
  94. projectGLJIDList: gljIdList
  95. };
  96. let quantityData = await RationGLJFacade.getQuantityByProjectGLJ(condition);
  97. let quantityList = {};
  98. // 整理数据
  99. for (let tmp of quantityData) {
  100. let tmpNum = parseFloat(tmp.rationQuantity);
  101. tmpNum = isNaN(tmpNum) ||tmpNum==0? 1 : tmpNum;
  102. if (quantityList[tmp.projectGLJID] === undefined) {
  103. quantityList[tmp.projectGLJID] = tmp.quantity * tmpNum;
  104. } else {
  105. quantityList[tmp.projectGLJID] += tmp.quantity * tmpNum;
  106. }
  107. }
  108. // 整理获取有组成物的项目工料机的数据
  109. let connect_keys = [];
  110. for(let tmp of gljData) {
  111. // 有组成物的类型且消耗量大于0才查找
  112. if (quantityList[tmp.id] !== undefined) {
  113. let key = this.getIndex(tmp,['code','name','specs','unit','type']);
  114. connect_keys.push(key);
  115. }
  116. }
  117. // 查找组成物的消耗量
  118. let totalComposition = {};
  119. let mixRatioData = {};
  120. if (connect_keys.length > 0) {
  121. let mixRatioModel = new MixRatioModel();
  122. condition = {connect_key: {"$in": connect_keys}, unit_price_file_id: unitPriceFileId};
  123. let mixRatioList = await mixRatioModel.findDataByCondition(condition, null, false);
  124. for (let tmp of mixRatioList) {
  125. let t_index = tmp.connect_key;
  126. let consumption=parseFloat(tmp.consumption);
  127. totalComposition[t_index] = totalComposition[t_index] === undefined ? consumption :
  128. totalComposition[t_index] + consumption;
  129. totalComposition[t_index] = scMathUtil.roundTo(totalComposition[t_index], -4);
  130. if (mixRatioData[t_index] !== undefined) {
  131. mixRatioData[t_index].push(tmp);
  132. } else {
  133. mixRatioData[t_index] = [tmp];
  134. }
  135. if(mixRationMap[t_index]!=undefined){
  136. mixRationMap[t_index].push(tmp);
  137. }else {
  138. mixRationMap[t_index]=[tmp];
  139. }
  140. if (mixRatioConnectData[tmp.glj_id] !== undefined) {
  141. mixRatioConnectData[tmp.glj_id].push(tmp.connect_key);
  142. } else {
  143. mixRatioConnectData[tmp.glj_id] = [tmp.connect_key];
  144. }
  145. }
  146. }
  147. // 组合单价数据
  148. gljData = this.combineData(gljData, unitPriceList, quantityList, mixRatioData, totalComposition);
  149. // 排序
  150. gljData.sort(function (a, b) {
  151. a.unit_price = a.unit_price === null ? 0 : a.unit_price;
  152. b.unit_price = b.unit_price === null ? 0 : b.unit_price;
  153. return a.unit_price.type - b.unit_price.type;
  154. });
  155. } catch (error) {
  156. console.log("glj_list_model:" + error);
  157. gljData = [];
  158. }
  159. return [gljData, mixRatioConnectData,mixRationMap];
  160. }
  161. /**
  162. * 组合工料机数据和单价文件数据
  163. *
  164. * @param {object} gljList
  165. * @param {object} unitPriceList
  166. * @param {object} quantityList
  167. * @param {object} mixRatioData 组合物明细数据
  168. * @param {object} totalComposition 组合物父工料机统计数据
  169. * @return {Array}
  170. */
  171. combineData(gljList, unitPriceList, quantityList = {}, mixRatioData = {}, totalComposition = {}) {
  172. // 整理组成物消耗量(只有在总列表显示的时候才需用到,获取单项项目工料机内容则忽略)
  173. let compositionConsumption = {};
  174. if (Object.keys(mixRatioData).length > 0 && Object.keys(totalComposition).length > 0) {
  175. for(let index in mixRatioData) {
  176. for(let tmp of mixRatioData[index]) {
  177. let t_index = this.getIndex(tmp,['code','name','specs','unit','type']);//取做为组成物的工料机的总消耗量
  178. compositionConsumption[t_index] = compositionConsumption[t_index] === undefined ? tmp.consumption :
  179. compositionConsumption[t_index] + tmp.consumption;
  180. }
  181. }
  182. }
  183. let result = [];
  184. // 循环组合数据
  185. for(let index in gljList) {
  186. let glj = gljList[index];
  187. if (glj.code === undefined) {
  188. continue;
  189. }
  190. let g_index = this.getIndex(glj,['code','name','specs','unit','type']);
  191. glj.unit_price = unitPriceList !== null && unitPriceList[g_index] !== undefined ? unitPriceList[g_index] : null;
  192. if (glj.unit_price === null) {
  193. continue;
  194. }
  195. let gljId = glj.glj_id + '';
  196. let projectGljId = glj.id + '';
  197. // 消耗量赋值
  198. glj.quantity = quantityList[projectGljId] !== undefined ? quantityList[projectGljId] : 0;
  199. glj.quantity = totalComposition[g_index] !== undefined ? totalComposition[g_index] : glj.quantity;
  200. glj.quantity = compositionConsumption[g_index] !== undefined ? glj.quantity + compositionConsumption[g_index] : glj.quantity;
  201. glj.quantity = scMathUtil.roundTo(parseFloat(glj.quantity), -3);
  202. // 组成物数据
  203. gljList[index].ratio_data = mixRatioData[g_index] !== undefined ? mixRatioData[g_index] : [];
  204. //因为schema中设置base_price 为string 类型,所以要通过中间变量转换为数字再做计算,不然会自动变成字符串类型
  205. this.getGLJPrice(glj);
  206. result.push(glj);
  207. }
  208. return result;
  209. }
  210. getGLJPrice(glj){
  211. let glj_basePrice = scMathUtil.roundTo(parseFloat(glj.unit_price.base_price), -2);
  212. glj.unit_price.base_price = glj_basePrice;
  213. glj.unit_price.market_price = scMathUtil.roundTo(parseFloat(glj.unit_price.market_price), -2);
  214. // 计算调整基价
  215. switch (glj.unit_price.type + '') {
  216. // 人工: 调整基价=基价单价*调整系数
  217. case GLJTypeConst.LABOUR:
  218. glj.adjust_price = scMathUtil.roundTo(parseFloat(glj.adjustment * glj_basePrice), -2);
  219. break;
  220. // 机械类型的算法
  221. case GLJTypeConst.MACHINE:
  222. console.log('机械');
  223. break;
  224. // 材料、主材、设备
  225. default:
  226. glj.adjust_price = glj.unit_price.base_price;
  227. }
  228. }
  229. /**
  230. * 新增项目工料机数据(包括新增单价文件) 定额工料机新增时调用
  231. *
  232. * @param {object} data
  233. * @return {Promise} 返回插入成功的数据id
  234. */
  235. async addList(data) {
  236. let result = null;
  237. try {
  238. if (Object.keys(data).length <= 0) {
  239. throw '新增数据为空';
  240. }
  241. let condition={
  242. code: data.code,
  243. project_id: data.project_id,
  244. name:data.name,
  245. specs:data.specs,
  246. type:data.type,
  247. unit:data.unit
  248. };
  249. let projectGljData = await this.findDataByCondition(condition);
  250. let isAddProjectGLJ = false;
  251. // 如果找不到数据则新增
  252. if (!projectGljData) {
  253. // 新增单条记录 (两个操作本来应该是事务操作,然而mongodb事务支持比较弱,就当作是都可以顺利执行)
  254. let gljInsertData = await this.add(data);
  255. if (!gljInsertData) {
  256. throw '新增项目工料机失败!';
  257. }
  258. isAddProjectGLJ = true;
  259. projectGljData = gljInsertData;
  260. }
  261. // 获取标段对应的单价文件id
  262. let unitPriceFileId = await ProjectModel.getUnitPriceFileId(data.project_id);
  263. if (unitPriceFileId <= 0) {
  264. throw '没有对应的单价文件';
  265. }
  266. let CompositionGLJ=[];
  267. // 判断类型,如果是混凝土、砂浆或者配合比则查找对应的组成物(前提是没有对应的项目工料机数据)
  268. if (data.type === GLJTypeConst.CONCRETE || data.type === GLJTypeConst.MORTAR ||
  269. data.type === GLJTypeConst.MIX_RATIO || data.type === GLJTypeConst.GENERAL_MACHINE) {
  270. //如果是新增
  271. if(isAddProjectGLJ ){
  272. await this.compositionInit(data, unitPriceFileId);
  273. }
  274. CompositionGLJ=await this.getCompositionGLJByData(data,unitPriceFileId);
  275. }
  276. projectGljData.subList=CompositionGLJ;
  277. // 新增单价文件
  278. let unitPriceModel = new UnitPriceModel();
  279. let [unitPriceInsertData, isAdd] = await unitPriceModel.addUnitPrice(data, unitPriceFileId);
  280. if (!unitPriceInsertData) {
  281. throw '新增单价失败!';
  282. }
  283. projectGljData.unit_price = unitPriceInsertData;
  284. result = projectGljData;
  285. } catch (error) {
  286. console.log(error);
  287. result = null;
  288. }
  289. return result;
  290. }
  291. /**
  292. * 新增单条工料机数据
  293. *
  294. * @param {object} data
  295. * @return {Promise}
  296. */
  297. async add(data) {
  298. if (Object.keys(data).length <= 0) {
  299. throw '新增数据为空';
  300. }
  301. let counterModel = new CounterModel();
  302. if (data instanceof Array) {
  303. // 如果是批量新增
  304. for(let tmp in data) {
  305. data[tmp].id = await counterModel.getId(gljCollectionName);
  306. }
  307. } else {
  308. data.id = await counterModel.getId(gljCollectionName);
  309. }
  310. this.setScene('add');
  311. let result = await this.db.create(data);
  312. return result;
  313. }
  314. /**
  315. * 修改名称、规格型号、单位、市场单价等
  316. * @param data
  317. * @returns {Promise.<void>}
  318. */
  319. async modifyGLJ(data,ration_glj){
  320. let unitPriceFileModel = new UnitPriceFileModel();
  321. let unitPriceFile = await unitPriceFileModel.getDataByProject(data.project_id);
  322. if (!unitPriceFile) {
  323. throw '没有对应的单价文件';
  324. }
  325. //查找单价信息,有则返回,没有则新增并返回
  326. let unitPriceFileId = unitPriceFile.id;
  327. let unitPriceModel = new UnitPriceModel();
  328. let [unitPriceData, isAdd] = await unitPriceModel.addUnitPrice(data, unitPriceFileId);
  329. let gljData={};
  330. if(isAdd){ //如果是新增,则新增一条新的项目工料机
  331. data.code = unitPriceData.code;
  332. gljData = await this.insertGLJWhenIsAdd(data,ration_glj,unitPriceFileId);
  333. }else { //如果不是新增,则查找是否有对应的项目工料机,有则返回,没有则新增
  334. let condition = {
  335. project_id:data.project_id,
  336. original_code: data.original_code,
  337. name:data.name,
  338. specs:data.specs,
  339. type:data.type,
  340. unit:data.unit
  341. }
  342. gljData = await this.findDataByCondition(condition,{_id: 0});
  343. if(!gljData){
  344. data.code = unitPriceData.code;
  345. gljData = await this.insertGLJWhenIsAdd(data,ration_glj,unitPriceFileId);
  346. }
  347. }
  348. gljData.unit_price = unitPriceData;
  349. return gljData
  350. }
  351. //修改属性后插入项目工料机
  352. async insertGLJWhenIsAdd(glj,ration_glj,unitPriceFileId){
  353. //新增项目工料机
  354. let gljData = await this.add(glj);
  355. //查看是否是有配合比的工料机类型
  356. if (glj.type === GLJTypeConst.CONCRETE || glj.type === GLJTypeConst.MORTAR ||
  357. glj.type === GLJTypeConst.MIX_RATIO || glj.type === GLJTypeConst.GENERAL_MACHINE){
  358. // 配合比数据插入
  359. let connect_key =this.getIndex(ration_glj,['code','name','specs','unit','type']);
  360. let connect_key_n =this.getIndex(glj,['code','name','specs','unit','type']);
  361. //先查找配合比数据是否已经存在
  362. let mixRatioModel = new MixRatioModel();
  363. let mixRatios_o = await mixRatioModel.findDataByCondition({connect_key: connect_key_n, unit_price_file_id: unitPriceFileId}, {_id: 0}, false);
  364. if(mixRatios_o&&mixRatios_o.length>0){//已经存在,不用再插入配合比数据,直接返回
  365. return gljData;
  366. }
  367. //不存在,则查找原始的配合比数据,并为新工料机增加配合比数据
  368. let mixRatios = await mixRatioModel.findDataByCondition({connect_key: connect_key, unit_price_file_id: unitPriceFileId}, {_id: 0}, false);
  369. let mixInsertResult ={};
  370. if(mixRatios&&mixRatios.length>0){
  371. let newMixRatioData = [];
  372. for(let m of mixRatios){
  373. let tem ={
  374. consumption: m.consumption,
  375. glj_id: m.glj_id,
  376. unit_price_file_id: m.unit_price_file_id,
  377. connect_key: connect_key_n,
  378. type: m.type,
  379. code: m.code,
  380. specs:m.specs,
  381. name:m.name,
  382. unit:m.unit
  383. };
  384. newMixRatioData.push(tem);
  385. }
  386. mixInsertResult= mixRatioModel.add(newMixRatioData);
  387. }
  388. }
  389. return gljData;
  390. }
  391. /**
  392. * 根据工料机id修改市场单价
  393. *
  394. * @param {Object} updateData
  395. * @return {Promise}
  396. */
  397. async modifyMarketPrice(updateData) {
  398. let result = {};
  399. try {
  400. if (updateData.code === undefined || updateData.market_price === undefined ||
  401. updateData.name === undefined || updateData.project_id === undefined) {
  402. throw '参数有误!';
  403. }
  404. // 先查是否有对应code的数据
  405. let gljListData = await this.findDataByCondition({code: updateData.code,
  406. project_id: updateData.project_id}, {_id: 0}, false);
  407. if (!gljListData) {
  408. throw '不存在对应code数据';
  409. }
  410. // 获取标段对应的单价文件id
  411. let unitPriceFileModel = new UnitPriceFileModel();
  412. let unitPriceFile = await unitPriceFileModel.getDataByProject(updateData.project_id);
  413. if (!unitPriceFile) {
  414. throw '没有对应的单价文件';
  415. }
  416. let unitPriceFileId = unitPriceFile.id;
  417. let unitPriceModel = new UnitPriceModel();
  418. let gljCount = gljListData.length;
  419. let [unitPriceData, isAdd] = await unitPriceModel.addUnitPrice(updateData, unitPriceFileId, gljCount);
  420. // 判断是否已存在对应数据
  421. let includeField = [
  422. {field: 'name', value: unitPriceData.name}
  423. ];
  424. let gljIndex = this.isIncluded(gljListData, includeField);
  425. let gljData = isAdd ? {} : gljListData[gljIndex];
  426. // 如果单价数据新增则工料机也需要新增
  427. if (isAdd) {
  428. // 如果没有对应的记录则新增一条工料机数据,并更改name
  429. let regular = /\(\d+\)/;
  430. let changeString = '(' + gljCount + ')';
  431. updateData.name = regular.test(updateData.name) ? updateData.name.replace(regular, changeString) :
  432. updateData.name + changeString;
  433. // 获取第一条数据作为数据源
  434. let originalData = gljListData[0];
  435. // 更改名称
  436. originalData.name = updateData.name;
  437. originalData = JSON.stringify(originalData);
  438. gljData = await this.add(JSON.parse(originalData));
  439. if (!gljData) {
  440. throw '新增工料机数据失败!';
  441. }
  442. }
  443. gljData.unit_price = unitPriceData;
  444. result = gljData;
  445. } catch (error) {
  446. console.log(error);
  447. result = {};
  448. }
  449. return result;
  450. }
  451. /**
  452. * 判断数据中是否包含某个数据
  453. *
  454. * @param {Array} data
  455. * @param {Array} includeField
  456. * @return {Number}
  457. */
  458. isIncluded(data, includeField) {
  459. let index = -1;
  460. if (data.length <= 0) {
  461. return index;
  462. }
  463. for(let tmp in data) {
  464. let counter = 0;
  465. for (let includeTmp of includeField) {
  466. if (data[tmp][includeTmp.field] === includeTmp.value) {
  467. counter++;
  468. }
  469. }
  470. if (counter === includeField.length) {
  471. index = tmp;
  472. break;
  473. }
  474. }
  475. return index;
  476. }
  477. /**
  478. * 工料机中组成物操作
  479. * 该方法只在确保没有对应项目工料机的时候才会调用
  480. *
  481. * @param {Object} data
  482. * @param {Number} projectId
  483. * @return {void}
  484. */
  485. async compositionInit(data, unitPriceFileId) {
  486. let gljId = data.glj_id === undefined ? 0 : data.glj_id;
  487. let projectId = data.project_id === undefined ? 0 : data.project_id;
  488. if (gljId === 0 || projectId === 0) {
  489. throw '参数错误';
  490. }
  491. let fromTable = data.from === undefined ? 'std' : data.from;
  492. // 查找对应组成物的项目工料机数据
  493. let indexs=['code','name','specs','unit','type'];
  494. let [projectGljList, compositionGljList] = await this.getCompositionGLJList(gljId, projectId, indexs, fromTable);
  495. // 整理配合比待插入数据
  496. let mixRatioInsertData = [];
  497. for (let tmp of compositionGljList) {
  498. // 配合比数据插入
  499. var connect_key =this.getIndex(data,['code','name','specs','unit','type']);
  500. let mixRatioData = {
  501. consumption: tmp.consumption,
  502. glj_id: tmp.ID,
  503. unit_price_file_id: unitPriceFileId,
  504. connect_key: connect_key,
  505. type: tmp.gljType,
  506. code: tmp.code,
  507. specs:tmp.specs,
  508. name:tmp.name,
  509. unit:tmp.unit
  510. };
  511. mixRatioInsertData.push(mixRatioData);
  512. }
  513. // 插入配合比表
  514. // 因为有可能项目工料机与单价数据已存在,但配合比数据不存在,所以先插入配合比,后续判断如果存在项目工料机则可以省下数据库操作
  515. let mixRatioModel = new MixRatioModel();
  516. let addMixRatioResult = await mixRatioModel.add(mixRatioInsertData);
  517. if (!addMixRatioResult) {
  518. throw '组成物插入单价数据失败!';
  519. }
  520. // 如果已经存在则后续操作停止
  521. if(Object.getOwnPropertyNames(projectGljList).length === compositionGljList.length) {
  522. return
  523. }
  524. // 整理插入的数据
  525. let gljInsertData = [];
  526. let unitPriceInsertData = [];
  527. for(let tmp of compositionGljList) {
  528. let key = this.getIndex(tmp,['code','name','specs','unit','gljType']);
  529. if (projectGljList[key] !== undefined) {
  530. continue;
  531. }
  532. // 项目工料机插入的数据
  533. let gljData = {
  534. glj_id: tmp.ID,
  535. project_id: projectId,
  536. code: tmp.code,
  537. name: tmp.name,
  538. specs: tmp.specs,
  539. unit: tmp.unit === undefined ? '' : tmp.unit,
  540. type: tmp.gljType,
  541. original_code:tmp.code
  542. };
  543. gljInsertData.push(gljData);
  544. let basePrice = scMathUtil.roundTo(tmp.basePrice,-6);
  545. // 单价文件插入的数据
  546. let unitPriceData = {
  547. base_price: basePrice,
  548. // 初始市场价=基价
  549. market_price: basePrice,
  550. code: tmp.code,
  551. name: tmp.name,
  552. unit_price_file_id: unitPriceFileId,
  553. type: tmp.gljType,
  554. short_name: tmp.shortName === undefined ? '' : tmp.shortName,
  555. glj_id: tmp.ID,
  556. specs: tmp.specs,
  557. unit: tmp.unit === undefined ? '' : tmp.unit,
  558. original_code:tmp.code
  559. };
  560. unitPriceInsertData.push(unitPriceData);
  561. }
  562. // 整理完后开始插入数据
  563. let addResult = await this.add(gljInsertData);
  564. if (!addResult) {
  565. throw '组成物插入项目工料机失败!';
  566. }
  567. // 插入单价数据表
  568. let unitPriceModel = new UnitPriceModel();
  569. let addUnitPriceResult = await unitPriceModel.add(unitPriceInsertData);
  570. if (!addUnitPriceResult) {
  571. throw '组成物插入单价数据失败!';
  572. }
  573. return
  574. }
  575. /**
  576. * 获取组成物具体数据
  577. *
  578. * @param {Number} projectGLJId
  579. * @param {Number} unitPriceFileId
  580. * @return {Promise}
  581. */
  582. async getCompositionList(projectGLJId, unitPriceFileId) {
  583. let result = [];
  584. try {
  585. // 查找对应的项目工料机数据
  586. let projectGLJData = await this.getDataById(projectGLJId,unitPriceFileId);
  587. let allowType = [GLJTypeConst.MIX_RATIO, GLJTypeConst.CONCRETE, GLJTypeConst.MORTAR,
  588. GLJTypeConst.GENERAL_MACHINE];
  589. if (projectGLJData.unit_price === null || allowType.indexOf(projectGLJData.unit_price.type) < 0) {
  590. throw '找不到相关项目工料机';
  591. }
  592. // 查找对应的项目工料机数据配合比,单价数据
  593. let [gljData, mixRatioData,unitPriceData] = await this.getCompositionListByGLJ(projectGLJData, unitPriceFileId);
  594. if (gljData.length <= 0) {
  595. throw '没有对应的组成物项目工料机';
  596. }
  597. gljData = this.combineData(gljData, unitPriceData, [], mixRatioData);
  598. // 排序
  599. gljData.sort(function (a, b) {
  600. return parseInt(a.code) - parseInt(b.code);
  601. });
  602. result = gljData;
  603. } catch (error) {
  604. console.log(error);
  605. result = [];
  606. }
  607. return result;
  608. }
  609. /**
  610. * 获取混凝土等有组成物相关工料机对应的组成物项目工料机数据
  611. *
  612. * @param {Number} gljId
  613. * @param {Number} projectId
  614. * @param {String} indexBy
  615. * @param {String} fromTable
  616. * @return {Promise} 返回组成物工料机数据和组成物列表数据
  617. */
  618. async getCompositionGLJList(gljId, projectId, indexBy = null, fromTable = 'std') {
  619. // 获取对应的组成物数据
  620. let gljListModel = fromTable === 'std' ? new STDGLJLibGLJListModel() : new GljModel();
  621. let componentGljList = await gljListModel.getComponent(gljId);
  622. if (componentGljList.length <= 0) {
  623. throw '不存在对应的组成物';
  624. }
  625. let codeList = [];
  626. let nameList = [];
  627. let specsList= [];
  628. let typeList = [];
  629. let unitList = [];
  630. for(let tmp of componentGljList) {
  631. codeList.push(tmp.code);
  632. nameList.push(tmp.name);
  633. specsList.push(tmp.specs);
  634. typeList.push(tmp.gljType);
  635. unitList.push(tmp.unit);
  636. }
  637. // 查找对应的项目工料机数据
  638. let condition = {project_id: projectId,code: {"$in": codeList}, name: {"$in": nameList},specs:{"$in": specsList},type:{"$in": typeList},unit:{"$in": unitList} };
  639. let gljData = await this.findDataByCondition(condition, {_id: 0}, false, indexBy);
  640. return [gljData, componentGljList];
  641. }
  642. async getCompositionGLJByData(glj,unitPriceFileId){
  643. let [gljData,mixRatioData,unitPriceData] = await this.getCompositionListByGLJ(glj,unitPriceFileId);
  644. gljData = this.combineData(gljData, unitPriceData, [], mixRatioData);
  645. return gljData;
  646. }
  647. /**
  648. * 反回组成物工料机和配合比数据
  649. * @param glj
  650. * @param unitPriceFileId
  651. * @returns {Promise.<void>}
  652. */
  653. async getCompositionListByGLJ(glj,unitPriceFileId){
  654. let t_index = this.getIndex(glj,['code','name','specs','unit','type']);
  655. // 查找对应的配合比数据
  656. let mixRatioModel = new MixRatioModel();
  657. let condition = {connect_key: t_index, unit_price_file_id: unitPriceFileId};
  658. let mixRatios = await mixRatioModel.findDataByCondition(condition, {_id: 0}, false);
  659. let codeList = [];
  660. let nameList = [];
  661. let specsList= [];
  662. let typeList = [];
  663. let unitList = [];
  664. if(mixRatios.length<=0){
  665. throw '不存在对应的组成物';
  666. }
  667. let mixRatioData={};
  668. for(let tmp of mixRatios) {
  669. codeList.push(tmp.code);
  670. nameList.push(tmp.name);
  671. specsList.push(tmp.specs);
  672. typeList.push(tmp.type);
  673. unitList.push(tmp.unit);
  674. let m_index = this.getIndex(tmp,['code','name','specs','unit','type']);
  675. mixRatioData[m_index]=tmp;
  676. }
  677. // 查找对应的项目工料机数据
  678. let gcondition = {project_id: glj.project_id,code: {"$in": codeList}, name: {"$in": nameList},specs:{"$in": specsList},type:{"$in": typeList},unit:{"$in": unitList} };
  679. let gljData = await this.findDataByCondition(gcondition, {_id: 0}, false);
  680. // 查找对应的单价数据
  681. let unitPriceModel = new UnitPriceModel();
  682. let ucondition = { unit_price_file_id: unitPriceFileId,code: {"$in": codeList}, name: {"$in": nameList},specs:{"$in": specsList},type:{"$in": typeList},unit:{"$in": unitList}};
  683. let unitPriceList = await unitPriceModel.findDataByCondition(ucondition, {_id: 0}, false);
  684. // 整理数据
  685. let unitPriceData = {};
  686. for(let tmp of unitPriceList) {
  687. let u_index = this.getIndex(tmp,['code','name','specs','unit','type'])
  688. unitPriceData[u_index] = tmp;
  689. }
  690. return [gljData,mixRatioData,unitPriceData];
  691. }
  692. /**
  693. * 根据条件获取对应项目工料机数据
  694. *
  695. * @param {Number} id
  696. * @return {Promise}
  697. */
  698. async getDataById(id,unitPriceFileId) {
  699. // 查找对应的项目工料机数据
  700. let projectGLJData = await this.findDataByCondition({id: id});
  701. if (projectGLJData === null) {
  702. throw '没有找到对应数据';
  703. }
  704. // 查找对应的单价数据
  705. let unitPriceModel = new UnitPriceModel();
  706. let condition={
  707. unit_price_file_id:unitPriceFileId,
  708. code: projectGLJData.code,
  709. name:projectGLJData.name,
  710. specs:projectGLJData.specs,
  711. type:projectGLJData.type,
  712. unit:projectGLJData.unit
  713. }
  714. let unitPrice = await unitPriceModel.findDataByCondition(condition);
  715. projectGLJData.unit_price = unitPrice;
  716. return projectGLJData;
  717. }
  718. }
  719. export default GLJListModel;