glj_list_model.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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. class GLJListModel extends BaseModel {
  15. /**
  16. * 材料类型id
  17. *
  18. * @var {Array}
  19. */
  20. materialIdList = [GLJTypeConst.GENERAL_MATERIAL, GLJTypeConst.CONCRETE, GLJTypeConst.MORTAR, GLJTypeConst.MIX_RATIO,
  21. GLJTypeConst.COMMERCIAL_CONCRETE, GLJTypeConst.COMMERCIAL_MORTAR];
  22. /**
  23. * 构造函数
  24. *
  25. * @return {void}
  26. */
  27. constructor() {
  28. let parent = super();
  29. parent.model = GLJSchemas;
  30. parent.init();
  31. }
  32. /**
  33. * 设置场景
  34. *
  35. * @param {string} scene
  36. * @return {void}
  37. */
  38. setScene(scene = '') {
  39. switch (scene) {
  40. // 新增数据的验证规则
  41. case 'add':
  42. this.model.schema.path('glj_repository_id').required(true);
  43. this.model.schema.path('project_id').required(true);
  44. this.model.schema.path('code').required(true);
  45. this.model.schema.path('name').required(true);
  46. break;
  47. }
  48. }
  49. /**
  50. * 根据标段对应工料机数据
  51. *
  52. * @param {Number} projectId
  53. * @param {Number} unitPriceFileId
  54. * @return {Promise}
  55. */
  56. async getListByProjectId(projectId, unitPriceFileId) {
  57. let gljData = null;
  58. try {
  59. // 首先获取对应标段下所有的项目工料机数据
  60. let condition = {project_id: projectId};
  61. let fields = {_id: 0};
  62. gljData = await this.db.find(condition, fields);
  63. // 没有数据则直接返回空
  64. if (gljData.length <= 0) {
  65. throw '无数据';
  66. }
  67. // 获取标段设置的单价文件数据
  68. let unitPriceModel = new UnitPriceModel();
  69. let unitPriceList = await unitPriceModel.getDataByFileId(unitPriceFileId);
  70. // 组合数据
  71. this.combineUnitPrice(gljData, unitPriceList);
  72. // 排序
  73. gljData.sort(function (a, b) {
  74. return a.unit_price.type - b.unit_price.type;
  75. });
  76. } catch (error) {
  77. console.log("glj_list_model:" + error);
  78. gljData = [];
  79. }
  80. return gljData;
  81. }
  82. /**
  83. * 组合工料机数据和单价文件数据
  84. *
  85. * @param {object} gljList
  86. * @param {object} unitPriceList
  87. * @return {void}
  88. */
  89. combineUnitPrice(gljList, unitPriceList) {
  90. // 循环组合数据
  91. for(let glj of gljList) {
  92. if (glj.code === undefined) {
  93. continue;
  94. }
  95. glj.unit_price = unitPriceList !== null && unitPriceList[glj.code + glj.name] !== undefined ? unitPriceList[glj.code + glj.name] : null;
  96. if (glj.unit_price === null) {
  97. continue;
  98. }
  99. // 计算调整基价
  100. switch (glj.unit_price.type + '') {
  101. // 人工: 调整基价=基价单价*调整系数
  102. case GLJTypeConst.LABOUR:
  103. glj.adjust_price = glj.adjustment * glj.unit_price.base_price;
  104. break;
  105. // 机械类型的算法
  106. case GLJTypeConst.MACHINE:
  107. console.log('机械');
  108. break;
  109. // 材料、主材、设备
  110. default:
  111. glj.adjust_price = glj.unit_price.base_price;
  112. }
  113. }
  114. }
  115. /**
  116. * 新增项目工料机数据(包括新增单价文件) 定额工料机新增时调用
  117. *
  118. * @param {object} data
  119. * @return {Promise} 返回插入成功的数据id
  120. */
  121. async addList(data) {
  122. let result = null;
  123. try {
  124. if (Object.keys(data).length <= 0) {
  125. throw '新增数据为空';
  126. }
  127. // 首先查找是否有同编码同名称的工料机数据
  128. let projectGljData = await this.findDataByCondition({code: data.code, project_id: data.project_id});
  129. // 如果找不到数据则新增
  130. if (!projectGljData) {
  131. // 新增单条记录 (两个操作本来应该是事务操作,然而mongodb事务支持比较弱,就当作是都可以顺利执行)
  132. let gljInsertData = await this.add(data);
  133. if (!gljInsertData) {
  134. throw '新增项目工料机失败!';
  135. }
  136. projectGljData = gljInsertData;
  137. }
  138. // 获取标段对应的单价文件id
  139. let unitPriceFileModel = new UnitPriceFileModel();
  140. let unitPriceFile = await unitPriceFileModel.getDataByProject(data.project_id);
  141. if (!unitPriceFile) {
  142. throw '没有对应的单价文件';
  143. }
  144. let unitPriceFileId = unitPriceFile.id;
  145. // 新增单价文件
  146. let unitPriceModel = new UnitPriceModel();
  147. let [unitPriceInsertData, isAdd] = await unitPriceModel.addUnitPrice(data, unitPriceFileId);
  148. if (!unitPriceInsertData) {
  149. throw '新增单价失败!';
  150. }
  151. projectGljData.unit_price = unitPriceInsertData;
  152. result = projectGljData;
  153. } catch (error) {
  154. console.log(error);
  155. result = null;
  156. }
  157. return result;
  158. }
  159. /**
  160. * 新增单条工料机数据
  161. *
  162. * @param {object} data
  163. * @return {Promise}
  164. */
  165. async add(data) {
  166. if (Object.keys(data).length <= 0) {
  167. throw '新增数据为空';
  168. }
  169. let counterModel = new CounterModel();
  170. data.id = await counterModel.getId(gljCollectionName);
  171. this.setScene('add');
  172. let result = await this.db.create(data);
  173. return result;
  174. }
  175. /**
  176. * 根据工料机id修改市场单价
  177. *
  178. * @param {Object} updateData
  179. * @return {Promise}
  180. */
  181. async modifyMarketPrice(updateData) {
  182. let result = {};
  183. try {
  184. if (updateData.code === undefined || updateData.market_price === undefined ||
  185. updateData.name === undefined || updateData.project_id === undefined) {
  186. throw '参数有误!';
  187. }
  188. // 先查是否有对应code的数据
  189. let gljListData = await this.findDataByCondition({code: updateData.code,
  190. project_id: updateData.project_id}, {_id: 0}, false);
  191. if (!gljListData) {
  192. throw '不存在对应code数据';
  193. }
  194. // 获取标段对应的单价文件id
  195. let unitPriceFileModel = new UnitPriceFileModel();
  196. let unitPriceFile = await unitPriceFileModel.getDataByProject(updateData.project_id);
  197. if (!unitPriceFile) {
  198. throw '没有对应的单价文件';
  199. }
  200. let unitPriceFileId = unitPriceFile.id;
  201. let unitPriceModel = new UnitPriceModel();
  202. let gljCount = gljListData.length;
  203. let [unitPriceData, isAdd] = await unitPriceModel.addUnitPrice(updateData, unitPriceFileId, gljCount);
  204. // 判断是否已存在对应数据
  205. let includeField = [
  206. {field: 'name', value: unitPriceData.name}
  207. ];
  208. let gljIndex = this.isIncluded(gljListData, includeField);
  209. let gljData = isAdd ? {} : gljListData[gljIndex];
  210. // 如果单价数据新增则工料机也需要新增
  211. if (isAdd) {
  212. // 如果没有对应的记录则新增一条工料机数据,并更改name
  213. let regular = /\(\d\)/;
  214. let changeString = '(' + gljCount + ')';
  215. updateData.name = regular.test(updateData.name) ? updateData.name.replace(regular, changeString) :
  216. updateData.name + changeString;
  217. // 获取第一条数据作为数据源
  218. let originalData = gljListData[0];
  219. // 更改名称
  220. originalData.name = updateData.name;
  221. originalData = JSON.stringify(originalData);
  222. gljData = await this.add(JSON.parse(originalData));
  223. if (!gljData) {
  224. throw '新增工料机数据失败!';
  225. }
  226. }
  227. gljData.unit_price = unitPriceData;
  228. result = gljData;
  229. } catch (error) {
  230. console.log(error);
  231. result = {};
  232. }
  233. return result;
  234. }
  235. /**
  236. * 判断数据中是否包含某个数据
  237. *
  238. * @param {Array} data
  239. * @param {Array} includeField
  240. * @return {Number}
  241. */
  242. isIncluded(data, includeField) {
  243. let index = -1;
  244. if (data.length <= 0) {
  245. return index;
  246. }
  247. for(let tmp in data) {
  248. let counter = 0;
  249. for (let includeTmp of includeField) {
  250. if (data[tmp][includeTmp.field] === includeTmp.value) {
  251. counter++;
  252. }
  253. }
  254. if (counter === includeField.length) {
  255. index = tmp;
  256. break;
  257. }
  258. }
  259. return index;
  260. }
  261. }
  262. export default GLJListModel;