ledger_check.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Mai
  6. * @date
  7. * @version
  8. */
  9. const ledgerCheckType = {
  10. sibling: {value: 1, text: '项目节、清单同层'},
  11. empty_code: {value: 2, text: '项目节、清单编号同时为空'},
  12. calc: {value: 3, text: '清单数量不等于计量单元之和'},
  13. zero: {value: 4, text: '清单数量或单价为0'},
  14. tp: {value: 5, text: '清单金额≠数量×单价'},
  15. over: {value: 6, text: '超计'},
  16. };
  17. const ledgerCheckUtil = {
  18. checkSibling: function (ledgerTree) {
  19. const error = [];
  20. for (const node of ledgerTree.nodes) {
  21. if (!node.children || node.children.length === 0) continue;
  22. let hasXmj, hasGcl;
  23. for (const child of node.children) {
  24. if (child.b_code) hasXmj = true;
  25. if (!child.b_code) hasGcl = true;
  26. }
  27. if (hasXmj && hasGcl) error.push(node);
  28. }
  29. return error;
  30. },
  31. checkCodeEmpty: function (ledgerTree) {
  32. const error = [];
  33. const checkNodeCode = function (node) {
  34. if ((!node.code || node.code === '') && (!node.b_code || node.b_code === '')) error.push(node);
  35. if (node.children && node.children.length > 0) {
  36. for (const child of node.children) {
  37. checkNodeCode(child);
  38. }
  39. }
  40. }
  41. for (const topLevel of ledgerTree.children) {
  42. if (topLevel.node_type !== 1) continue;
  43. checkNodeCode(topLevel);
  44. }
  45. return error;
  46. },
  47. checkCalc: function (ledgerTree, ledgerPos, option) {
  48. const error = [];
  49. for (const node of ledgerTree.nodes) {
  50. if (node.children && node.children.length > 0) continue;
  51. const nodePos = ledgerPos.getLedgerPos(node.id);
  52. if (!nodePos || nodePos.length === 0) continue;
  53. const checkData = {}, calcData = {};
  54. for (const f of option.fields) {
  55. checkData[f] = node[f] || 0;
  56. calcData[f] = 0;
  57. }
  58. for (const np of nodePos) {
  59. for (const f of option.fields) {
  60. calcData[f] = ZhCalc.add(calcData[f], np[f]) || 0;
  61. }
  62. }
  63. if (!_.isMatch(checkData, calcData)) error.push(node);
  64. }
  65. return error;
  66. },
  67. checkZero: function (ledgerTree) {
  68. const error = [];
  69. for (const node of ledgerTree.nodes) {
  70. if ((!node.b_code || node.b_code === '')) continue;
  71. if (node.children && node.children.length > 0) continue;
  72. if ((checkZero(node.sgfh_qty) && checkZero(node.qtcl_qty) && checkZero(node.sjcl_qty)
  73. && checkZero(node.deal_qty) && checkZero(node.quantity))
  74. || checkZero(node.unit_price)) error.push(node);
  75. }
  76. return error;
  77. },
  78. checkTp: function (ledgerTree, decimal, option) {
  79. const error = [];
  80. for (const node of ledgerTree.nodes) {
  81. if (node.children && node.children.length > 0) continue;
  82. if (option.filter && option.filter(node)) continue;
  83. const checkData = {}, calcData = {};
  84. for (const f of option.fields) {
  85. checkData[f.tp] = node[f.tp] || 0;
  86. calcData[f.tp] = ZhCalc.mul(node.unit_price, node[f.qty], decimal.tp) || 0;
  87. }
  88. if (!_.isMatch(checkData, calcData)) error.push(node);
  89. }
  90. return error;
  91. },
  92. checkOver: function(ledgerTree, ledgerPos, option) {
  93. const error = [];
  94. for (const node of ledgerTree.nodes) {
  95. if (node.children && node.children.length > 0) continue;
  96. if (option.isTz) {
  97. const posRange = ledgerPos.getLedgerPos(node.id) || [];
  98. if (posRange.length > 0) {
  99. for (const p of posRange) {
  100. if (p.end_contract_qty > p.quantity) {
  101. error.push(node);
  102. continue;
  103. }
  104. }
  105. }
  106. }
  107. if (node.is_tp) {
  108. if (option.isTz) {
  109. if (node.end_contract_tp > node.total_price) error.push(node);
  110. } else {
  111. if (node.end_contract_tp > node.deal_tp) error.push(node);
  112. }
  113. } else {
  114. if (option.isTz) {
  115. if (node.end_contract_qty > node.quantity) error.push(node);
  116. } else {
  117. if (node.end_contract_qty > node.deal_qty) error.push(node);
  118. }
  119. }
  120. }
  121. return error;
  122. },
  123. };
  124. const ledgerCheck2 = function (setting) {
  125. const ledger = setting.ledgerTree, ledgerPos = setting.ledgerPos, decimal = setting.decimal;
  126. const checkOption = setting.checkOption;
  127. const assignWarningData = function (nodes, checkType, warningData) {
  128. for (const node of nodes) {
  129. warningData.push({
  130. type: checkType,
  131. ledger_id: node.ledger_id,
  132. code: node.code,
  133. b_code: node.b_code,
  134. name: node.name,
  135. })
  136. }
  137. };
  138. const checkData = {
  139. check_time: new Date(),
  140. warning_data: [],
  141. };
  142. const progressData = [];
  143. if (checkOption.sibling.enable) {
  144. const sibling = ledgerCheckUtil.checkSibling(ledger, checkOption.sibling) || [];
  145. assignWarningData(sibling, ledgerCheckType.sibling.value, checkData.warning_data);
  146. progressData.push({key: 'sibling', caption: ledgerCheckType.sibling.text, error: sibling.length});
  147. }
  148. if (checkOption.empty_code.enable) {
  149. const empty_code = ledgerCheckUtil.checkCodeEmpty(ledger, checkOption.empty_code) || [];
  150. assignWarningData(empty_code, ledgerCheckType.empty_code.value, checkData.warning_data);
  151. progressData.push({key: 'empty_code', caption: ledgerCheckType.empty_code.text, error: empty_code.length});
  152. }
  153. if (checkOption.calc.enable) {
  154. const calc = ledgerCheckUtil.checkCalc(ledger, ledgerPos, checkOption.calc) || [];
  155. assignWarningData(calc, ledgerCheckType.calc.value, checkData.warning_data);
  156. progressData.push({key: 'calc', caption: ledgerCheckType.calc.text, error: calc.length});
  157. }
  158. if (checkOption.zero.enable) {
  159. const zero = ledgerCheckUtil.checkZero(ledger, checkOption.zero) || [];
  160. assignWarningData(zero, ledgerCheckType.zero.value, checkData.warning_data);
  161. progressData.push({key: 'zero', caption: ledgerCheckType.zero.text, error: zero.length});
  162. }
  163. if (checkOption.tp.enable) {
  164. const tp = ledgerCheckUtil.checkTp(ledger, decimal, checkOption.tp) || [];
  165. assignWarningData(tp, ledgerCheckType.tp.value, checkData.warning_data);
  166. progressData.push({key: 'tp', caption: ledgerCheckType.tp.text, error: tp.length});
  167. }
  168. if (checkOption.over && checkOption.over.enable) {
  169. const over = ledgerCheckUtil.checkOver(ledger, ledgerPos, checkOption.over) || [];
  170. assignWarningData(over, ledgerCheckType.over.value, checkData.warning_data);
  171. progressData.push({key: 'over', caption: ledgerCheckType.over.text, error: over.length});
  172. }
  173. setting.checkList.clearCheckData();
  174. if (checkData.warning_data.length > 0) {
  175. setting.checkList.loadCheckData(checkData);
  176. } else {
  177. setting.checkList.hide();
  178. }
  179. return progressData;
  180. };
  181. const getCheckType = function (option) {
  182. const result = {};
  183. for (const o in option) {
  184. if (option[o].enable) {
  185. result[o] = ledgerCheckType[o];
  186. }
  187. }
  188. return result;
  189. };