calc_base.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. /**
  2. * Created by Zhong on 2017/11/28.
  3. */
  4. //清单固定行
  5. const fixedFlag = {
  6. // 分部分项工程
  7. SUB_ENGINERRING: 1,
  8. // 措施项目
  9. MEASURE: 2,
  10. // 施工技术措施项目
  11. CONSTRUCTION_TECH: 3,
  12. // 安全文明施工按实计算费用
  13. SAFETY_CONSTRUCTION_ACTUAL: 4,
  14. // 施工组织措施专项费用
  15. CONSTRUCTION_ORGANIZATION: 5,
  16. // 安全文明施工专项费用
  17. SAFETY_CONSTRUCTION: 6,
  18. // 其他项目
  19. OTHER: 7,
  20. // 暂列金额
  21. PROVISIONAL: 8,
  22. // 暂估价
  23. ESTIMATE: 9,
  24. // 材料(工程设备)暂估价
  25. MATERIAL_PROVISIONAL: 10,
  26. // 专业工程暂估价
  27. ENGINEERING_ESITIMATE: 11,
  28. // 计日工
  29. DAYWORK: 12,
  30. // 总承包服务费
  31. TURN_KEY_CONTRACT: 13,
  32. // 索赔与现场签证
  33. CLAIM_VISA: 14,
  34. // 规费
  35. CHARGE: 15,
  36. // 社会保险费及住房公积金 Social insurance fee and housing accumulation fund
  37. SOCIAL_INSURANCE_HOUSING_FUND: 16,
  38. // 工程排污费 charges for disposing pollutants
  39. POLLUTANTS: 17,
  40. // 税金
  41. TAX: 18,
  42. //工程造价
  43. ENGINEERINGCOST: 19
  44. };
  45. let cbTools = {
  46. isDef: function (v) {
  47. return v !== undefined && v !== null;
  48. },
  49. isUnDef: function (v) {
  50. return v === undefined || v === null;
  51. },
  52. isNum: function (v) {
  53. return this.isDef(v) && !isNaN(v) && v !== Infinity;
  54. },
  55. isFlag: function (v) {
  56. return this.isDef(v) && this.isDef(v.flagsIndex) && this.isDef(v.flagsIndex.fixed);
  57. },
  58. returnV: function (v, r) {
  59. if(this.isDef(v)){
  60. return v;
  61. }
  62. return r;
  63. },
  64. findBill: function (fixedFlag) {
  65. let bills = projectObj.project.Bills.datas;
  66. for(let i = 0, len = bills.length; i < len; i++){
  67. if(bills[i].flagsIndex.flag === fixedFlag){
  68. return bills[i];
  69. }
  70. }
  71. },
  72. //需要用到计算基数的时候,先找出所有的固定清单,避免每个基数都要去遍历寻找清单
  73. setFixedBills: function (project, billsObj, fixedFlag) {
  74. let bills = project.Bills.datas;
  75. for(let i = 0, len = bills.length; i < len; i++){
  76. if(this.isDef(bills[i].flagsIndex.fixed)){
  77. for(let flag in fixedFlag){
  78. if(fixedFlag[flag] === bills[i].flagsIndex.fixed.flag){
  79. billsObj[fixedFlag[flag]] = Object.create(null);
  80. billsObj[fixedFlag[flag]]['base'] = Object.create(null);
  81. billsObj[fixedFlag[flag]]['bill'] = bills[i];
  82. }
  83. }
  84. }
  85. }
  86. },
  87. //清单基数设置所属固定清单属性
  88. setBaseBills: function (baseFigure, fixedBills) {
  89. for(let i in baseFigure){
  90. let calcBase = baseFigure[i];
  91. calcBase.fixedBill = null;
  92. if(cbTools.isDef(fixedBills[calcBase.fixedFlag])){
  93. fixedBills[calcBase.fixedFlag]['base'][i] = calcBase;
  94. calcBase.fixedBill = fixedBills[calcBase.fixedFlag];
  95. }
  96. }
  97. },
  98. //生成清单基数计算分类模板
  99. setBaseFigureClass: function (baseFigures, mapObj) {
  100. mapObj['CONSTRUCTION_ORGANIZATION'] = Object.create(null);
  101. mapObj['OTHER'] = Object.create(null);
  102. mapObj['CHARGE'] = Object.create(null);
  103. mapObj['TAX'] = Object.create(null);
  104. mapObj['OTHERS'] = Object.create(null);
  105. let filter = ['CSXMF', 'ZZCSXMF', 'ZZCSXMDEJJZJGCF', 'ZZCSXMDEJJRGF', 'ZZCSXMDEJJCLF', 'ZZCSXMDEJJJXF', 'QTXMF', 'GF', 'SJ'];
  106. for(let figure in baseFigures){
  107. if(filter.indexOf(baseFigures[figure]['base']) === -1){
  108. mapObj['CONSTRUCTION_ORGANIZATION'][figure] = baseFigures[figure];
  109. }
  110. if(baseFigures[figure]['base'] !== 'QTXMF'){
  111. mapObj['OTHER'][figure] = baseFigures[figure];
  112. }
  113. if(baseFigures[figure]['base'] !== 'GF'){
  114. mapObj['CHARGE'][figure] = baseFigures[figure];
  115. }
  116. if(baseFigures[figure]['base'] !== 'SJ'){
  117. mapObj['TAX'][figure] = baseFigures[figure];
  118. }
  119. mapObj['OTHERS'][figure] = baseFigures[figure];
  120. }
  121. },
  122. getFigure: function (node) {
  123. let calcBase = projectObj.project.calcBase;
  124. let parent = node.parent;
  125. if(this.isFlag(node.data) && (node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.SUB_ENGINERRING
  126. || node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_TECH)){
  127. //node.data.baseFigureClass = null;
  128. return null;
  129. }
  130. else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION){
  131. //node.data.baseFigureClass = 'CONSTRUCTION_ORGANIZATION';
  132. return calcBase.baseFigureClass.CONSTRUCTION_ORGANIZATION;
  133. }
  134. else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.OTHER){
  135. //node.data.baseFigureClass = 'OTHER';
  136. return calcBase.baseFigureClass.OTHER;
  137. }
  138. else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CHARGE){
  139. //node.data.baseFigureClass = 'CHARGE';
  140. return calcBase.baseFigureClass.CHARGE;
  141. }
  142. else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.TAX){
  143. //node.data.baseFigureClass = 'TAX';
  144. return calcBase.baseFigureClass.TAX;
  145. }
  146. else {
  147. if(!parent){
  148. //node.data.baseFigureClass = 'OTHERS';
  149. return calcBase.baseFigureClass.OTHERS;
  150. }
  151. else {
  152. return this.getFigure(parent);
  153. }
  154. }
  155. },
  156. getBaseBill: function (node) {
  157. let calcBase = projectObj.project.calcBase;
  158. let parent = node.parent;
  159. if(this.isFlag(node.data) && (node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.SUB_ENGINERRING
  160. || node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_TECH)){
  161. return node;
  162. }
  163. else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION){
  164. return node;
  165. }
  166. else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.OTHER){
  167. return node;
  168. }
  169. else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CHARGE){
  170. return node;
  171. }
  172. else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.TAX){
  173. return node;
  174. }
  175. else {
  176. if(!parent){
  177. return node;
  178. }
  179. else {
  180. return this.getBaseBill(parent);
  181. }
  182. }
  183. },
  184. //获取清单(有基数计算)引用了的其他清单,(循环引用栈中的一块)
  185. getStackBlock: function (billID) {
  186. let tempBases = [], block = [];//存引用的清单ID
  187. let node = getBill(billID);
  188. if(!node){
  189. return tempBases;
  190. }
  191. else {
  192. getBase(node);
  193. let bases = Array.from(new Set(tempBases));
  194. for(let i = 0, len = bases.length; i < len; i++){
  195. if(cbTools.isDef(calcBase.baseFigures[bases[i]])){
  196. block.push(calcBase.baseFigures[bases[i]]['fixedBill']['bill']['ID']);
  197. }
  198. }
  199. return Array.from(new Set(block));
  200. }
  201. function getBase(node){
  202. if(node && node.children.length === 0){
  203. if(cbTools.isDef(node.data.calcBase)){
  204. let figures = cbParser.getFigure(node.data.calcBase);
  205. tempBases = tempBases.concat(figures);
  206. }
  207. }
  208. else if(node && node.children.length > 0) {
  209. for(let i = 0, len = node.children.length; i < len; i++){
  210. getBase(node.children[i]);
  211. }
  212. }
  213. }
  214. function getBill(ID){
  215. for(let i = 0, len = calcBase.project.mainTree.items.length; i < len; i++){
  216. if(calcBase.project.mainTree.items[i].data.ID === ID && calcBase.project.mainTree.items[i].sourceType === calcBase.project.Bills.getSourceType()){
  217. return calcBase.project.mainTree.items[i];
  218. }
  219. }
  220. return null;
  221. }
  222. }
  223. };
  224. let baseFigureTemplate = {
  225. 'FBFXGCF': function () {
  226. let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['bill'];
  227. if(cbTools.isUnDef(bill)) return 0;
  228. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  229. return bill.feesIndex.common.totalFee || 0;
  230. },
  231. 'FBFXDEJJRGF': function () {
  232. let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['bill'];
  233. if(cbTools.isUnDef(bill)) return 0;
  234. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  235. return bill.feesIndex.labour.totalFee || 0;
  236. },
  237. 'FBFXDEJJCLF': function () {
  238. let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['bill'];
  239. if(cbTools.isUnDef(bill)) return 0;
  240. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  241. return bill.feesIndex.material.totalFee || 0;
  242. },
  243. 'FBFXDEJJJXF': function () {
  244. let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['bill'];
  245. if(cbTools.isUnDef(bill)) return 0;
  246. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  247. return bill.feesIndex.machine.totalFee || 0;
  248. },
  249. 'FBFXTZRGF': function () {
  250. let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['bill'];
  251. if(cbTools.isUnDef(bill)) return 0;
  252. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  253. return bill.feesIndex.adjustLabour.totalFee || 0;
  254. },
  255. 'FBFXTZJSRGF': function () {
  256. let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['bill'];
  257. if(cbTools.isUnDef(bill)) return 0;
  258. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  259. return bill.feesIndex.adjustMachineLabour.totalFee || 0;
  260. },
  261. 'FBFXZCF': function () {
  262. let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['bill'];
  263. if(cbTools.isUnDef(bill)) return 0;
  264. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  265. return bill.feesIndex.mainMaterial.totalFee || 0;
  266. },
  267. 'FBFXSBF': function () {
  268. let bill = calcBase.fixedBills[calcBase.fixedFlag.SUB_ENGINERRING]['bill'];
  269. if(cbTools.isUnDef(bill)) return 0;
  270. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  271. return bill.feesIndex.mainMaterial.totalFee || 0;
  272. },
  273. 'FBFXWJJCLF': function () {
  274. return 0;
  275. },
  276. 'FBFXRGGR': function () {
  277. return 0;
  278. },
  279. 'FBFXGCLQDJJZJGCF': function () {
  280. return (this['FBFXDEJJRGF']() + this['FBFXDEJJCLF']() + this['FBFXDEJJJXF']()).toDecimal(decimalObj.bills.totalPrice);
  281. },
  282. 'CSXMF': function () {
  283. let bill = calcBase.fixedBills[calcBase.fixedFlag.MEASURE]['bill'];
  284. if(cbTools.isUnDef(bill)) return 0;
  285. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  286. return bill.feesIndex.common.totalFee || 0;
  287. },
  288. 'ZZCSXMF': function () {
  289. let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION]['bill'];
  290. if(cbTools.isUnDef(bill)) return 0;
  291. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  292. return bill.feesIndex.common.totalFee || 0;
  293. },
  294. 'ZZCSXMDEJJZJGCF': function () {
  295. return (this['ZZCSXMDEJJRGF']() + this['ZZCSXMDEJJCLF']() + this['ZZCSXMDEJJJXF']()).toDecimal(decimalObj.bills.totalPrice);
  296. },
  297. 'ZZCSXMDEJJRGF': function () {
  298. let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION]['bill'];
  299. if(cbTools.isUnDef(bill)) return 0;
  300. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  301. return bill.feesIndex.labour.totalFee || 0;
  302. },
  303. 'ZZCSXMDEJJCLF': function () {
  304. let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION]['bill'];
  305. if(cbTools.isUnDef(bill)) return 0;
  306. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  307. return bill.feesIndex.material.totalFee || 0;
  308. },
  309. 'ZZCSXMDEJJJXF': function () {
  310. let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION]['bill'];
  311. if(cbTools.isUnDef(bill)) return 0;
  312. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  313. return bill.feesIndex.machine.totalFee || 0;
  314. },
  315. 'JSCSXMF': function () {
  316. let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['bill'];
  317. if(cbTools.isUnDef(bill)) return 0;
  318. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  319. return bill.feesIndex.common.totalFee || 0;
  320. },
  321. 'JSCSXMDEJJRGF': function () {
  322. let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['bill'];
  323. if(cbTools.isUnDef(bill)) return 0;
  324. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  325. return bill.feesIndex.labour.totalFee || 0;
  326. },
  327. 'JSCSXMDEJJCLF': function () {
  328. let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['bill'];
  329. if(cbTools.isUnDef(bill)) return 0;
  330. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  331. return bill.feesIndex.material.totalFee || 0;
  332. },
  333. 'JSCSXMDEJJJXF': function () {
  334. let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['bill'];
  335. if(cbTools.isUnDef(bill)) return 0;
  336. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  337. return bill.feesIndex.machine.totalFee || 0;
  338. },
  339. 'JSCSXMTZRGF': function () {
  340. let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['bill'];
  341. if(cbTools.isUnDef(bill)) return 0;
  342. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  343. return bill.feesIndex.adjustLabour.totalFee || 0;
  344. },
  345. 'JSCSXMTZJSRGF': function () {
  346. let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['bill'];
  347. if(cbTools.isUnDef(bill)) return 0;
  348. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  349. return bill.feesIndex.adjustMachineLabour.totalFee || 0;
  350. },
  351. 'JSCSXMZCF': function () {
  352. let bill = calcBase.fixedBills[calcBase.fixedFlag.CONSTRUCTION_TECH]['bill'];
  353. if(cbTools.isUnDef(bill)) return 0;
  354. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  355. return bill.feesIndex.mainMaterial.totalFee || 0;
  356. },
  357. 'JSCSXMSBF': function () {
  358. return 0;
  359. },
  360. 'JSCSXMWJJCLF': function () {
  361. return 0;
  362. },
  363. 'JSCSXMRGGR': function () {
  364. return 0;
  365. },
  366. 'JSCSXMQDDEJJZJGCF': function () {
  367. return (this['JSCSXMDEJJRGF']() + this['JSCSXMDEJJCLF']() + this['JSCSXMDEJJJXF']()).toDecimal(decimalObj.bills.totalPrice);
  368. },
  369. 'QTXMF': function () {
  370. let bill = calcBase.fixedBills[calcBase.fixedFlag.OTHER]['bill'];
  371. if(cbTools.isUnDef(bill)) return 0;
  372. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  373. return bill.feesIndex.common.totalFee || 0;
  374. },
  375. 'GF': function () {
  376. let bill = calcBase.fixedBills[calcBase.fixedFlag.CHARGE]['bill'];
  377. if(cbTools.isUnDef(bill)) return 0;
  378. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  379. return bill.feesIndex.common.totalFee || 0;
  380. },
  381. 'SJ': function () {
  382. let bill = calcBase.fixedBills[calcBase.fixedFlag.TAX]['bill'];
  383. if(cbTools.isUnDef(bill)) return 0;
  384. if(cbTools.isUnDef(bill.feesIndex) || Object.keys(bill.feesIndex).length === 0) return 0;
  385. return bill.feesIndex.common.totalFee || 0;
  386. }
  387. };
  388. let baseFigureMap = {
  389. '分部分项工程费': {base: 'FBFXGCF', fixedFlag: fixedFlag.SUB_ENGINERRING},
  390. '分部分项定额基价人工费': {base: 'FBFXDEJJRGF', fixedFlag: fixedFlag.SUB_ENGINERRING},
  391. '分部分项定额基价材料费': {base: 'FBFXDEJJCLF', fixedFlag: fixedFlag.SUB_ENGINERRING},
  392. '分部分项定额基价机械费': {base: 'FBFXDEJJJXF', fixedFlag: fixedFlag.SUB_ENGINERRING},
  393. '分部分项调整人工费': {base: 'FBFXTZRGF', fixedFlag: fixedFlag.SUB_ENGINERRING},
  394. '分部分项调整机上人工费': {base: 'FBFXTZJSRGF', fixedFlag: fixedFlag.SUB_ENGINERRING},
  395. '分部分项主材费': {base: 'FBFXZCF', fixedFlag: fixedFlag.SUB_ENGINERRING},
  396. '分部分项设备费': {base: 'FBFXSBF', fixedFlag: fixedFlag.SUB_ENGINERRING},
  397. '分部分项未计价材料费': {base: 'FBFXWJJCLF', fixedFlag: fixedFlag.SUB_ENGINERRING},
  398. '分部分项人工工日': {base: 'FBFXRGGR', fixedFlag: fixedFlag.SUB_ENGINERRING},
  399. '分部分项工程量清单中的基价直接工程费': {base: 'FBFXGCLQDJJZJGCF', fixedFlag: fixedFlag.SUB_ENGINERRING},
  400. '措施项目费': {base: 'CSXMF', fixedFlag: fixedFlag.MEASURE},
  401. '组织措施项目费': {base: 'ZZCSXMF', fixedFlag: fixedFlag.CONSTRUCTION_ORGANIZATION},
  402. '组织措施项目定额基价直接工程费': {base: 'ZZCSXMDEJJZJGCF', fixedFlag: fixedFlag.CONSTRUCTION_ORGANIZATION},
  403. '组织措施项目定额基价人工费': {base: 'ZZCSXMDEJJRGF', fixedFlag: fixedFlag.CONSTRUCTION_ORGANIZATION},
  404. '组织措施项目定额基价材料费': {base: 'ZZCSXMDEJJCLF', fixedFlag: fixedFlag.CONSTRUCTION_ORGANIZATION},
  405. '组织措施项目定额基价机械费': {base: 'ZZCSXMDEJJJXF', fixedFlag: fixedFlag.CONSTRUCTION_ORGANIZATION},
  406. '技术措施项目费': {base: 'JSCSXMF', fixedFlag: fixedFlag.CONSTRUCTION_TECH},
  407. '技术措施项目定额基价人工费': {base: 'JSCSXMDEJJRGF', fixedFlag: fixedFlag.CONSTRUCTION_TECH},
  408. '技术措施项目定额基价材料费': {base: 'JSCSXMDEJJCLF', fixedFlag: fixedFlag.CONSTRUCTION_TECH},
  409. '技术措施项目定额基价机械费': {base: 'JSCSXMDEJJJXF', fixedFlag: fixedFlag.CONSTRUCTION_TECH},
  410. '技术措施项目调整人工费': {base: 'JSCSXMTZRGF', fixedFlag: fixedFlag.CONSTRUCTION_TECH},
  411. '技术措施项目调整机上人工费': {base: 'JSCSXMTZJSRGF', fixedFlag: fixedFlag.CONSTRUCTION_TECH},
  412. '技术措施项目主材费': {base: 'JSCSXMZCF', fixedFlag: fixedFlag.CONSTRUCTION_TECH},
  413. '技术措施项目设备费': {base: 'JSCSXMSBF', fixedFlag: fixedFlag.CONSTRUCTION_TECH},
  414. '技术措施项目未计价材料费': {base: 'JSCSXMWJJCLF', fixedFlag: fixedFlag.CONSTRUCTION_TECH},
  415. '技术措施项目人工工日': {base: 'JSCSXMRGGR', fixedFlag: fixedFlag.CONSTRUCTION_TECH},
  416. '技术措施项目清单中的定额基价直接工程费': {base: 'JSCSXMQDDEJJZJGCF', fixedFlag: fixedFlag.CONSTRUCTION_TECH},
  417. '其他项目费': {base: 'QTXMF', fixedFlag: fixedFlag.OTHER},
  418. '规费': {base: 'GF', fixedFlag: fixedFlag.CHARGE},
  419. '税金': {base: 'SJ', fixedFlag: fixedFlag.TAX}
  420. };
  421. //输入式分析器
  422. let cbAnalyzer = {
  423. standar: function (exp) {
  424. //去空格
  425. exp = exp.replace(/\s/g, '');
  426. //( to (
  427. exp = exp.replace(/(/g, '(');
  428. //)to )
  429. exp = exp.replace(/)/g, ')');
  430. return exp;
  431. },
  432. //输入合法性
  433. inputLegal: function (exp) {
  434. let ilegalRex = /[^0-9,\u4e00-\u9fa5,\+,\-,\/,\*,\(,\),.]/g;
  435. return !ilegalRex.test(exp);
  436. },
  437. //基数合法性、存在性
  438. baseLegal: function (baseFigures, exp) {
  439. let expFigures = cbParser.getFigure(exp);
  440. for(let i = 0, len = expFigures.length; i < len; i++){
  441. if(cbTools.isUnDef(baseFigures[expFigures[i]])){
  442. return false;
  443. }
  444. }
  445. return true;
  446. },
  447. //循环计算
  448. cycleCalc: function (node, baseFigures, exp) {
  449. let stack = [];
  450. if(node.sourceType !== calcBase.project.Bills.getSourceType()){
  451. return false;
  452. }
  453. let sbillID = cbTools.getBaseBill(node).data.ID;
  454. let expFigures = cbParser.getFigure(exp);
  455. for(let i = 0, len = expFigures.length; i < len; i++){
  456. let figure = expFigures[i];
  457. if(cbTools.isDef(baseFigures[figure])){
  458. let bill = baseFigures[figure]['fixedBill']['bill'];
  459. if(checkStack(getRefStack([bill.ID]), sbillID)){
  460. console.log('循环计算');
  461. calcBase.errMsg = '表达式出现循环计算';
  462. return true;
  463. }
  464. }
  465. }
  466. return false;
  467. function checkStack(stack, startBillID){
  468. //引用栈发现了初始引用
  469. return stack.indexOf(startBillID) !== -1;
  470. }
  471. function getRefStack(billIDs){
  472. stack = Array.from(new Set(stack.concat(billIDs)));
  473. for(let i = 0, len = billIDs.length; i < len; i++){
  474. let block = cbTools.getStackBlock(billIDs[i]);
  475. if(block.length > 0){
  476. stack = Array.from(new Set(stack.concat(block)));
  477. getRefStack(block);
  478. }
  479. }
  480. return stack;
  481. }
  482. },
  483. //四则运算合法性,前端控制不允许重复出现运算符,这里主要判断()的使用问题,这里再判断一次
  484. arithmeticLeagl: function (exp) {
  485. let ilegalRex = /[\+,\-,\*,\/]{2}/g;
  486. return !ilegalRex.test(exp);
  487. },
  488. //
  489. legalExp: function (node) {
  490. let exp = this.standar(node.data.userCalcBase);
  491. if(this.inputLegal(exp)){
  492. if(this.baseLegal(cbTools.getFigure(node), exp)){
  493. if(!this.cycleCalc(node, cbTools.getFigure(node), exp)){
  494. if(this.arithmeticLeagl(exp)){
  495. return exp;
  496. }
  497. }
  498. }
  499. return null;
  500. }
  501. return null;
  502. }
  503. };
  504. //输入式转换器
  505. let cbParser = {
  506. //获取表达式中的基数
  507. getFigure: function(expr){
  508. let rst = [];
  509. let cnRex = /[^\u4e00-\u9fa5]/;
  510. let temp = expr.split(cnRex);
  511. for(let i = 0, len = temp.length; i < len; i++){
  512. if(temp[i] !== '' && rst.indexOf(temp[i]) === -1){
  513. rst.push(temp[i]);
  514. }
  515. }
  516. return rst;
  517. },
  518. //将表达式转换为可编译的表达式
  519. toCompileExpr: function(v){
  520. if(v === ''){
  521. return '$CBC.base(\'NONE\')';
  522. }
  523. let strs = this.getFigure(v);
  524. let exps = [];
  525. for(let i = 0, len = strs.length; i < len; i++){
  526. let exp = Object.create(null);
  527. exp.orgExp = strs[i];
  528. exps.push(exp);
  529. }
  530. for(let i = 0, len = exps.length;i < len; i++){
  531. exps[i].compileExp = '$CBC.base(\'' + exps[i].orgExp;
  532. exps[i].compileExp = exps[i].compileExp + '\')';
  533. v = v.replace(new RegExp(exps[i].orgExp,"g"), exps[i].compileExp);
  534. }
  535. return v;
  536. }
  537. };
  538. let cbCalctor = {
  539. //计算基数
  540. base: function (figure) {
  541. if(figure === 'NONE'){
  542. return 0;
  543. }
  544. return baseFigureTemplate[calcBase.baseFigures[figure]['base']]();
  545. },
  546. //计算
  547. exec: function () {
  548. }
  549. };
  550. let calcBase = {
  551. errMsg: '表达式不正确',
  552. success: false,
  553. //清单固定行
  554. fixedFlag: null,
  555. fixedBills: Object.create(null),
  556. //清单基数
  557. baseFigures: Object.create(null),
  558. //清单可选基数映射,分两类:组织措施项目:排除父项和计算的父项; 其他项目、规费、税金、工程造价,及新增部分:显示所有计算基数
  559. baseFigureClass: Object.create(null),
  560. //初始化
  561. init: function (project) {
  562. let me = this;
  563. me.project = project;
  564. me.fixedFlag = fixedFlag;
  565. cbTools.setFixedBills(project, me.fixedBills, me.fixedFlag);
  566. me.baseFigures = baseFigureMap;
  567. cbTools.setBaseBills(me.baseFigures, me.fixedBills);
  568. cbTools.setBaseFigureClass(me.baseFigures, me.baseFigureClass);
  569. },
  570. getBase: function (figure) {
  571. return cbCalctor.base(figure);
  572. },
  573. getBaseByClass: function (node) {
  574. return cbTools.getFigure(node);
  575. },
  576. getBaseBill: function (node) {
  577. return cbTools.getBaseBill(node);
  578. },
  579. calculate: function (node) {
  580. let me = calcBase,
  581. $CBA = cbAnalyzer,
  582. $CBP = cbParser,
  583. $CBC = cbCalctor;
  584. try {
  585. me.success = false;
  586. me.errMsg = '表达式不正确';
  587. //分析输入式合法性
  588. let exp = $CBA.legalExp(node);
  589. if(!cbTools.isDef(exp)){
  590. throw '表达式不正确';
  591. }
  592. //输入式转换表达式
  593. let compileExp = $CBP.toCompileExpr(exp);
  594. //计算
  595. let calcBaseValue = eval(compileExp);
  596. if(!cbTools.isNum(calcBaseValue)){
  597. throw '表达式不正确';
  598. }
  599. //存储
  600. me.success = true;
  601. node.data.calcBase = exp;
  602. node.data.calcBaseValue = parseFloat(calcBaseValue).toDecimal(decimalObj.decimal('totalPrice', node));
  603. /* me.project.calcProgram.calculate(node);
  604. me.project.calcProgram.saveNode(node);*/
  605. }
  606. catch (err){
  607. alert(me.errMsg);
  608. }
  609. }
  610. };