sum_load.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Mai
  6. * @date
  7. * @version
  8. */
  9. const Ledger = require('../lib/ledger');
  10. class loadGclBaseTree {
  11. /**
  12. * 构造函数
  13. * @param {Array} tempData - 清单模板数据
  14. */
  15. constructor (ctx, setting) {
  16. this.ctx = ctx;
  17. this.parent = setting.parent;
  18. this.defaultData = setting.defaultData;
  19. // 常量
  20. this.splitChar = '-';
  21. // 索引
  22. // 以code为索引
  23. this.items = [];
  24. // 缓存
  25. this.keyNodeId = setting.maxId ? setting.maxId + 1 : 1;
  26. }
  27. /**
  28. * 根据 编号 查找 父项项目节
  29. * @param {String} code - 子项编号
  30. * @returns {*}
  31. */
  32. findNode(node, parent) {
  33. parent = parent || this.parent;
  34. if (!parent.children) return null;
  35. for (const child of parent.children) {
  36. const checkLeaf = (child.is_leaf && node.is_leaf) || (!child.is_leaf && !node.is_leaf);
  37. if (child.b_code === node.b_code && child.name === node.name && child.unit === node.unit && checkLeaf) return child;
  38. }
  39. return null;
  40. }
  41. /**
  42. * 添加 树节点 并完善该节点的树结构
  43. * @param {Object} node - 添加节点
  44. * @param {Object} parent - 父项
  45. * @returns {*}
  46. */
  47. addNode(source, parent) {
  48. if (source.b_code === '101') console.log('101 parent', parent);
  49. parent = parent ? parent : this.parent;
  50. let node = this.findNode(source, parent);
  51. if (source.b_code === '101') console.log('101 cur', node);
  52. if (!node) {
  53. if (!parent.children) parent.children = [];
  54. node = {
  55. id: this.ctx.app.uuid.v4(),
  56. tender_id: this.ctx.tender.id,
  57. ledger_id: this.keyNodeId,
  58. ledger_pid: parent.ledger_id,
  59. level: parent.level +1,
  60. full_path: parent.full_path + '-' + this.keyNodeId,
  61. order: parent.children.length + 1,
  62. children: [],
  63. b_code: source.b_code,
  64. name: source.name,
  65. unit: source.unit,
  66. sgfh_qty: 0,
  67. qtcl_qty: 0,
  68. sjcl_qyt: 0,
  69. quantity: 0,
  70. };
  71. this.keyNodeId += 1;
  72. parent.children.push(node);
  73. this.items.push(node);
  74. }
  75. return node;
  76. }
  77. gather(source, parent) {}
  78. getUpdateData() {}
  79. }
  80. class loadLedgerGclTree extends loadGclBaseTree {
  81. gather(source, parent) {
  82. const node = this.addNode(source, parent);
  83. node.sgfh_qty = this.ctx.helper.add(node.sgfh_qty, source.sgfh_qty);
  84. node.qtcl_qty = this.ctx.helper.add(node.qtcl_qty, source.qtcl_qty);
  85. node.sjcl_qty = this.ctx.helper.add(node.sjcl_qty, source.sjcl_qty);
  86. node.quantity = this.ctx.helper.add(node.quantity, source.quantity);
  87. return node;
  88. }
  89. getUpdateData() {
  90. const update = {id: this.parent.id, is_leaf: false};
  91. const create = [];
  92. for (const i of this.items) {
  93. create.push({
  94. id: i.id, tender_id: i.tender_id, ledger_id: i.ledger_id, ledger_pid: i.ledger_pid,
  95. level: i.level, order: i.order, full_path: i.full_path, is_leaf: !i.children || i.children.length === 0,
  96. b_code: i.b_code, name: i.name, unit: i.unit,
  97. sgfh_qty: i.sgfh_qty, sjcl_qty: i.sjcl_qty, qtcl_qty: i.qtcl_qty, quantity: i.quantity,
  98. })
  99. }
  100. return {update, create};
  101. }
  102. }
  103. class updateReviseGclTree extends loadGclBaseTree {
  104. constructor (ctx, setting) {
  105. super(ctx, setting);
  106. this.baseNodes = [];
  107. }
  108. loadBase(datas) {
  109. datas.sort((x, y) => { return x.level === y.level ? x.order - y.order : x.level - y.level; });
  110. const Index = {};
  111. for (const d of datas) {
  112. const parent = this.parent.ledger_id === d.ledger_pid ? this.parent : Index[d.ledger_pid];
  113. if (!parent) continue;
  114. if (!parent.children) parent.children = [];
  115. const baseNode = {
  116. id: d.id,
  117. ledger_id: d.ledger_id,
  118. ledger_pid: d.ledger_pid,
  119. level: d.level,
  120. is_leaf: d.is_leaf,
  121. full_path: d.full_path,
  122. b_code: d.b_code,
  123. name: d.name,
  124. unit: d.unit,
  125. unit_price: d.unit_price,
  126. org_sgfh_qty: d.sgfh_qty || 0,
  127. org_sjcl_qty: d.sjcl_qty || 0,
  128. org_qtcl_qty: d.qtcl_qty || 0,
  129. org_qty: d.quantity || 0,
  130. org_order: d.order,
  131. sgfh_qty: 0,
  132. sjcl_qty: 0,
  133. qtcl_qty: 0,
  134. quantity: 0,
  135. };
  136. parent.children.push(baseNode);
  137. Index[baseNode.ledger_id] = baseNode;
  138. this.baseNodes.push(baseNode);
  139. }
  140. }
  141. gather(source, parent) {
  142. const node = this.addNode(source, parent);
  143. if (source.b_code === '207-2-1') console.log('207-2-1', node, source);
  144. node.sgfh_qty = this.ctx.helper.add(node.sgfh_qty, source.sgfh_qty);
  145. node.qtcl_qty = this.ctx.helper.add(node.qtcl_qty, source.qtcl_qty);
  146. node.sjcl_qty = this.ctx.helper.add(node.sjcl_qty, source.sjcl_qty);
  147. node.quantity = this.ctx.helper.add(node.quantity, source.quantity);
  148. return node;
  149. }
  150. getUpdateData() {
  151. const result = {update: [], errors: [], create: []};
  152. if (this.baseNodes.length === 0) {
  153. result.update = [{id: this.parent.id, is_leaf: false}];
  154. } else {
  155. for (const bn of this.baseNodes) {
  156. if (bn.children && bn.children.length > 0) continue;
  157. if (bn.sjcl_qty < bn.org_sjcl_qty || bn.qtcl_qty < bn.org_qtcl_qty || bn.sgfh_qty < bn.org_sgfh_qty) {
  158. result.errors.push(bn);
  159. } else if (bn.sjcl_qty !== bn.org_sjcl_qty || bn.qtcl_qty !== bn.org_qtcl_qty || bn.sgfh_qty !== bn.org_sgfh_qty) {
  160. result.update.push({
  161. id: bn.id, sgfh_qty: bn.sgfh_qty, sjcl_qty: bn.sjcl_qty, qtcl_qty: bn.qtcl_qty, quantity: bn.quantity,
  162. })
  163. }
  164. }
  165. }
  166. for (const i of this.items) {
  167. result.create.push({
  168. id: i.id, tender_id: i.tender_id, ledger_id: i.ledger_id, ledger_pid: i.ledger_pid,
  169. level: i.level, order: i.order, full_path: i.full_path, is_leaf: !i.children || i.children.length === 0,
  170. b_code: i.b_code, name: i.name, unit: i.unit,
  171. sgfh_qty: i.sgfh_qty, sjcl_qty: i.sjcl_qty, qtcl_qty: i.qtcl_qty, quantity: i.quantity,
  172. })
  173. }
  174. return result;
  175. }
  176. }
  177. class sumLoad {
  178. constructor (ctx) {
  179. this.ctx = ctx;
  180. }
  181. recusiveLoadGatherGcl(node, parent) {
  182. const cur = node.b_code ? this.loadTree.gather(node, parent) : parent;
  183. if (!node.children || node.children.length === 0) return;
  184. for (const child of node.children) {
  185. this.recusiveLoadGatherGcl(child, cur);
  186. }
  187. }
  188. async loadGatherGcl(select, maxId, tenders, defaultData) {
  189. this.loadTree = new loadLedgerGclTree(this.ctx, {
  190. parent: select, maxId, type: 'ledger', defaultData,
  191. });
  192. for (const tender of tenders) {
  193. const billsData = await this.ctx.service.ledger.getData(tender.tid);
  194. const billsTree = new Ledger.billsTree(this.ctx, {
  195. id: 'ledger_id',
  196. pid: 'ledger_pid',
  197. order: 'order',
  198. level: 'level',
  199. rootId: -1,
  200. keys: ['id', 'tender_id', 'ledger_id'],
  201. stageId: 'id',
  202. });
  203. billsTree.loadDatas(billsData);
  204. for (const top of billsTree.children) {
  205. if ([1].indexOf(top.node_type) < 0) continue;
  206. this.recusiveLoadGatherGcl(top, null);
  207. }
  208. }
  209. return this.loadTree;
  210. }
  211. async updateGatherGcl(select, maxId, tenders, defaultData) {
  212. this.loadTree = new updateReviseGclTree(this.ctx, {
  213. parent: select, maxId, type: 'ledger', defaultData,
  214. });
  215. const posterity = await this.ctx.service.reviseBills.getPosterityByParentId(this.ctx.tender.id, select.ledger_id);
  216. this.loadTree.loadBase(posterity);
  217. for (const tender of tenders) {
  218. const billsData = await this.ctx.service.ledger.getData(tender.tid);
  219. const billsTree = new Ledger.billsTree(this.ctx, {
  220. id: 'ledger_id',
  221. pid: 'ledger_pid',
  222. order: 'order',
  223. level: 'level',
  224. rootId: -1,
  225. keys: ['id', 'tender_id', 'ledger_id'],
  226. stageId: 'id',
  227. });
  228. billsTree.loadDatas(billsData);
  229. for (const top of billsTree.children) {
  230. if ([1].indexOf(top.node_type) < 0) continue;
  231. this.recusiveLoadGatherGcl(top, null);
  232. }
  233. }
  234. return this.loadTree;
  235. }
  236. }
  237. module.exports = sumLoad;