gljUtil.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. /**
  2. * Created by zhang on 2018/6/7.
  3. */
  4. let gljUtil = {
  5. calcProjectGLJQuantity: function (projectGLJDatas, rationGLJDatas, rationDatas, billsDatas, q_decimal, _, scMathUtil, isReport) {
  6. let project_gljs = projectGLJDatas.gljList,
  7. mixRatioMap = projectGLJDatas.mixRatioMap,
  8. com_electrovalence = projectGLJDatas.com_electrovalence;
  9. let rations = rationDatas;
  10. let rationMap = _.indexBy(rations, 'ID');
  11. let billsMap = _.indexBy(billsDatas,'ID');
  12. let quantityMap = {};
  13. let rationGljGroup = _.groupBy(rationGLJDatas, 'projectGLJID');
  14. let IDarray = this.getSubdivisionAndTechBillsLeavesID(billsDatas); //分别取分部分项和技术措施项目的所有叶子清单ID
  15. let billIDs = IDarray[0],
  16. tech_billIDS = IDarray[1];
  17. let materialCalcMap = {};
  18. //养护没有分部分项消耗量这一说的所以不用管
  19. let qField = "quantity";
  20. let mField = "materialQuantity"; //材料计算的工料机消耗量
  21. let elecIndex = ""; //记住电的标识
  22. for (let pglj of project_gljs) {
  23. let pg_index = this.getIndex(pglj, this.gljKeyArray);
  24. pglj[qField] = 0;
  25. pglj[mField] = 0;
  26. let gljGroup = rationGljGroup[pglj.id] ? rationGljGroup[pglj.id] : []; //定额工料机没有,有可能是定额类型的工料机
  27. let result = this.getQuantityPerGLJ(gljGroup, rations, rationMap, pglj, billIDs, tech_billIDS,billsMap, q_decimal, _, scMathUtil);
  28. pglj[qField] = result.quantity;
  29. pglj.tenderQuantity = result.tenderQuantity;
  30. quantityMap[pg_index] = pglj;
  31. if (pglj.code == gljUtil.getElecCode() && pglj.name == '电' && pglj.unit == "kW·h") elecIndex = pg_index;
  32. if (pglj.unit_price.calcMaterial == 1) materialCalcMap[pg_index] = true;
  33. }
  34. //计算做为组成物的消耗量
  35. for (let pkey in mixRatioMap) {
  36. let mixRatioList = mixRatioMap[pkey];
  37. for (let m of mixRatioList) {
  38. let m_index = this.getIndex(m, this.gljKeyArray);
  39. let m_glj = quantityMap[m_index];
  40. let p_glj = quantityMap[pkey];
  41. if (m_glj && p_glj && !gljUtil.isConcreteType(p_glj.type)) { //混凝土、砂浆、配合比组成物的消耗量在定额下已经有体现了,不用再计算进去
  42. let quantity = scMathUtil.roundForObj(parseFloat(p_glj[qField]) * parseFloat(m.consumption), q_decimal);
  43. let tenderQuantity = scMathUtil.roundForObj(parseFloat(p_glj.tenderQuantity) * parseFloat(m.consumption), q_decimal);
  44. m_glj[qField] = scMathUtil.roundForObj(parseFloat(m_glj[qField]) + quantity, q_decimal);
  45. m_glj.tenderQuantity = scMathUtil.roundForObj(parseFloat(m_glj.tenderQuantity) + tenderQuantity, q_decimal);
  46. }
  47. }
  48. }
  49. //计算经过场外运输损耗后的总消耗量
  50. for (let pglj of project_gljs) {
  51. let offSiteTransportLossRate = this.getOffSiteTransportLossRate(pglj);
  52. pglj.offSiteTransportLossRate = parseFloat(offSiteTransportLossRate); //scMathUtil.roundForObj(offSiteTransportLossRate,getDecimal("glj.unitPrice")) ;这里再取小数位数太麻烦了,暂时用保存的吧
  53. offSiteTransportLossRate = offSiteTransportLossRate / 100;
  54. pglj.transportLossQuantity = scMathUtil.roundForObj(pglj.quantity * offSiteTransportLossRate, q_decimal);
  55. pglj.quantity = scMathUtil.roundForObj(pglj.quantity + pglj.transportLossQuantity, q_decimal);
  56. pglj.tenderTransportLossQuantity = scMathUtil.roundForObj(pglj.tenderQuantity * offSiteTransportLossRate, q_decimal);
  57. pglj.tenderQuantity = scMathUtil.roundForObj(pglj.tenderQuantity + pglj.tenderTransportLossQuantity, q_decimal);
  58. if (isReport)
  59. pglj.quantity = pglj.tenderQuantity;
  60. }
  61. //材料计算中,工料机的消耗量
  62. //材料计算中,有可能A包含B,B包含C。。。。。等情况,为避免循环计算,只多计算一次,不做再深的嵌套处理
  63. // 1.先计算做为父工料机的材料计算消耗量
  64. if (projectGLJDatas.freightList) this.setMaterialCalcQuantity(quantityMap, materialCalcMap, true, projectGLJDatas.freightList, q_decimal, _, scMathUtil); //运费计算中工料机的消耗量
  65. if (projectGLJDatas.originalList) this.setMaterialCalcQuantity(quantityMap, materialCalcMap, true, projectGLJDatas.originalList, q_decimal, _, scMathUtil); //原价计算中工料机的消耗量
  66. // 2.再计算做为子工料机的材料计算消耗量
  67. if (projectGLJDatas.freightList) this.setMaterialCalcQuantity(quantityMap, materialCalcMap, false, projectGLJDatas.freightList, q_decimal, _, scMathUtil); //运费计算中工料机的消耗量
  68. if (projectGLJDatas.originalList) this.setMaterialCalcQuantity(quantityMap, materialCalcMap, false, projectGLJDatas.originalList, q_decimal, _, scMathUtil); //原价计算中工料机的消耗量
  69. //因为材料计算里自采材料产生的消耗量和进行材料计算的父工料机的消耗量有关,所以材料计算中的组成物的消耗量要在上一步的组成物计算完后,再计算自采材料里组成物的消耗量,所认两个组成物计算不能合并,而且乘的值也不同
  70. for (let pkey in mixRatioMap) {
  71. let mixRatioList = mixRatioMap[pkey];
  72. for (let m of mixRatioList) {
  73. let m_index = this.getIndex(m, this.gljKeyArray);
  74. let m_glj = quantityMap[m_index];
  75. let p_glj = quantityMap[pkey];
  76. if (m_glj && p_glj && !gljUtil.isConcreteType(p_glj.type) && p_glj[mField] > 0) { //混凝土、砂浆、配合比组成物的消耗量在定额下已经有体现了,不用再计算进去
  77. let materialQuantity = scMathUtil.roundForObj(parseFloat(p_glj[mField]) * parseFloat(m.consumption), q_decimal);
  78. m_glj[qField] = scMathUtil.roundForObj(parseFloat(m_glj[qField]) + materialQuantity, q_decimal);
  79. m_glj[mField] = scMathUtil.roundForObj(parseFloat(m_glj[mField]) + materialQuantity, q_decimal);
  80. }
  81. }
  82. }
  83. //计算综合电价中,电网电和机械台班的消耗量 - 电有可能做为组成物存在,计算综合电价的各消耗量时,要以电的总消耗量为基础,所以这步要放在最后,即电都计算完成以后
  84. if (com_electrovalence && com_electrovalence.gljList && quantityMap[elecIndex]) {
  85. for (let cg of com_electrovalence.gljList) {
  86. //网电的消耗量=电的总消耗量×加权系数
  87. let eq = scMathUtil.roundForObj(quantityMap[elecIndex][qField] * parseFloat(cg.coe), q_decimal);
  88. if (cg.name == '电网电') {
  89. quantityMap[this.getIndex(cg)][qField] = eq;
  90. } else {
  91. let tquantity = 0;
  92. let w = parseInt(cg.name);
  93. if (w) tquantity = scMathUtil.roundForObj(eq / w, 6);
  94. tquantity = scMathUtil.roundForObj(tquantity * this.getElecCoe(), q_decimal);
  95. let ekey = this.getIndex(cg);
  96. quantityMap[ekey][qField] = tquantity;
  97. //计算机械台班下的组成物的消耗量
  98. if (mixRatioMap[ekey]) {
  99. for (let m of mixRatioMap[ekey]) {
  100. let cmkey = this.getIndex(m);
  101. if (quantityMap[cmkey] && tquantity > 0) { //混凝土、砂浆、配合比组成物的消耗量在定额下已经有体现了,不用再计算进去
  102. let c_m_quantity = scMathUtil.roundForObj(tquantity * parseFloat(m.consumption), 6);
  103. quantityMap[cmkey][qField] = scMathUtil.roundForObj(parseFloat(quantityMap[cmkey][qField]) + c_m_quantity, q_decimal);
  104. }
  105. }
  106. }
  107. }
  108. }
  109. }
  110. },
  111. setMaterialCalcQuantity: function (quantityMap, materialCalcMap, isParent, calcList, q_decimal, _, scMathUtil) {
  112. let qField = "quantity";
  113. let p_decimal = 6; //自采定额这里计算结果都看成是中间过程,取6位小数
  114. for (let t of calcList) {
  115. if (quantityMap[t.connect_key] && quantityMap[t.connect_key][qField] > 0) {
  116. let rationIDMap = _.indexBy(t.rations, "ID");
  117. if (t.ration_gljs) {
  118. for (let rg of t.ration_gljs) {
  119. let rIndex = this.getIndex(rg);
  120. let pglj = quantityMap[rIndex];
  121. let ration = rationIDMap[rg.rationID];
  122. if (isParent == true) { //当计算做为材料计算父消耗量时,忽略子消耗量
  123. if (!materialCalcMap[rIndex]) continue
  124. } else { //当计算做为材料计算子消耗量时,忽略父消耗量
  125. if (materialCalcMap[rIndex]) continue
  126. }
  127. if (pglj && ration) {
  128. let rg_quantity = scMathUtil.roundForObj(rg.quantity, q_decimal);
  129. let r_quantity = scMathUtil.roundForObj(ration.quantity, q_decimal);
  130. let result = scMathUtil.roundForObj(rg_quantity * r_quantity, p_decimal);
  131. result = scMathUtil.roundForObj(quantityMap[t.connect_key][qField] * result, p_decimal);
  132. pglj.quantity = scMathUtil.roundForObj(pglj.quantity + result, q_decimal);
  133. pglj.materialQuantity = scMathUtil.roundForObj(pglj.materialQuantity + result, q_decimal);
  134. }
  135. }
  136. }
  137. }
  138. }
  139. },
  140. getOffSiteTransportLossRate: function (pglj) {
  141. let offSiteTransportLossRate; //场外运输损耗率
  142. let handlingLossRate; //每增加一次装卸损耗率
  143. let totalLoadingTimes = 1; //没有材料计算,获取不到装卸总次数,则按1计算
  144. //场外总损耗率=场外运输损耗率%+(装卸总次数-1)*每增加一次装卸损耗率%。
  145. if (pglj.unit_price) {
  146. if (pglj.unit_price.calcMaterial == 1) { //如果是材料计算,则用修改过的新值
  147. offSiteTransportLossRate = pglj.unit_price.offSiteTransportLossRate_n;
  148. handlingLossRate = pglj.unit_price.handlingLossRate_n;
  149. if (pglj.unit_price.totalLoadingTimes && pglj.unit_price.totalLoadingTimes > 1) totalLoadingTimes = parseFloat(pglj.unit_price.totalLoadingTimes)
  150. } else {
  151. offSiteTransportLossRate = pglj.unit_price.offSiteTransportLossRate;
  152. handlingLossRate = pglj.unit_price.handlingLossRate;
  153. }
  154. }
  155. offSiteTransportLossRate = offSiteTransportLossRate ? parseFloat(offSiteTransportLossRate) : 0;
  156. handlingLossRate = handlingLossRate ? parseFloat(handlingLossRate) : 0;
  157. // 场外运输损耗率%+(装卸总次数-1)*每增加一次装卸损耗率%
  158. return (offSiteTransportLossRate + (totalLoadingTimes - 1) * handlingLossRate);
  159. },
  160. getQuantityPerGLJ: function (ration_glj_list, rations, rationMap, pglj, billIDs, tech_billIDS,billsMap, q_decimal, _, scMathUtil) {
  161. let result = {};
  162. let quantity_sum = 0; //工料机汇总消耗量
  163. let tender_qantity_sum = 0;
  164. for (let rg of ration_glj_list) {
  165. let tem_ration = rationMap[rg.rationID];
  166. if(tem_ration){
  167. if(!billsMap[tem_ration.billsItemID]) continue;//如果定额工料的父项没有找到,则忽略
  168. }
  169. let r_quantity = tem_ration ? scMathUtil.roundForObj(tem_ration.quantity, q_decimal) : 0;
  170. let glj_quantity = scMathUtil.roundForObj(rg.quantity, q_decimal);
  171. let tender_r_quantity = r_quantity;
  172. let tender_glj_quantity = glj_quantity;
  173. if (!r_quantity) {
  174. continue;
  175. }
  176. if (!pglj.is_adjust_price) {
  177. tender_glj_quantity = this.getRationGLJTenderQuantity(rg, tem_ration, q_decimal, scMathUtil, pglj);
  178. tender_r_quantity = this.getRationTenderQuantity(tem_ration, q_decimal, scMathUtil);
  179. }
  180. let total = scMathUtil.roundForObj(glj_quantity * r_quantity, q_decimal);
  181. let tender_total = scMathUtil.roundForObj(tender_glj_quantity * tender_r_quantity, q_decimal);
  182. quantity_sum = scMathUtil.roundForObj(quantity_sum + total, q_decimal);
  183. tender_qantity_sum = scMathUtil.roundForObj(tender_qantity_sum + tender_total, q_decimal);
  184. }
  185. for (let ra of rations) { //计算定额类型工料机的消耗量
  186. if(!billsMap[ra.billsItemID]) continue;//如果定额工料的父项没有找到,则忽略
  187. if (ra.type == this.rationType.gljRation && ra.projectGLJID === pglj.id) {
  188. let r_quantity = scMathUtil.roundForObj(ra.quantity, q_decimal);
  189. r_quantity = r_quantity ? r_quantity : 0;
  190. let tender_r_quantity = r_quantity;
  191. if (!pglj.is_adjust_price) {
  192. tender_r_quantity = this.getRationTenderQuantity(ra, q_decimal, scMathUtil);
  193. }
  194. quantity_sum = scMathUtil.roundForObj(quantity_sum + r_quantity, q_decimal);
  195. tender_qantity_sum = scMathUtil.roundForObj(tender_qantity_sum + tender_r_quantity, q_decimal);
  196. }
  197. }
  198. result.quantity = quantity_sum;
  199. result.tenderQuantity = tender_qantity_sum;
  200. return result;
  201. },
  202. getRationGLJTenderQuantity: function (ration_glj, ration, q_decimal, scMathUtil, projectGLJ) {
  203. let coeMap = {
  204. 1: 'labour', //人工
  205. 2: 'material', //材料
  206. 3: 'machine', //机械
  207. 4: 'main', //主材
  208. 5: 'equipment' //设备
  209. };
  210. let typeString = ration_glj.type + "";
  211. let coeField = "";
  212. for (let key in coeMap) {
  213. if (typeString.indexOf(key) == 0) {
  214. coeField = coeMap[key];
  215. break;
  216. }
  217. }
  218. let coe = 1;
  219. if (projectGLJ && projectGLJ.is_adjust_price == 0) {
  220. coe = ration.quantityCoe && this.isNotEmpty(ration.quantityCoe[coeField]) ? ration.quantityCoe[coeField] : 1;
  221. coe = parseFloat(coe);
  222. } else {
  223. coe = 1;
  224. }
  225. if (coe == 0) coe = 1;
  226. let glj_quantity = scMathUtil.roundForObj(ration_glj.quantity, q_decimal);
  227. return scMathUtil.roundForObj(glj_quantity * coe, q_decimal);
  228. },
  229. getRationTenderQuantity: function (ration, q_decimal, scMathUtil) {
  230. let rationQuantityCoe = this.isNotEmpty(ration.rationQuantityCoe) ? ration.rationQuantityCoe : 1;
  231. rationQuantityCoe = parseFloat(rationQuantityCoe);
  232. if (rationQuantityCoe == 0) rationQuantityCoe = 1;
  233. let r_quantity = ration ? scMathUtil.roundForObj(ration.quantity, q_decimal) : 0;
  234. return scMathUtil.roundForObj(r_quantity * rationQuantityCoe, q_decimal);
  235. },
  236. isNotEmpty: function (str) {
  237. return this.isDef(str) && str != "";
  238. },
  239. getSubdivisionAndTechBillsLeavesID: function (billsDatas) { //分别取分部分项和技术措施项目的所有叶子清单ID
  240. if (typeof (projectObj) !== 'undefined') { //存在,说明在前端调用
  241. return [projectObj.project.Bills.getSubdivisionProjectLeavesID(), projectObj.project.Bills.getTechLeavesID()];
  242. }
  243. let parentMap = {};
  244. let subdivisionBillID = null,
  245. techBillID = null,
  246. sIDs = [],
  247. tIDS = [];
  248. for (let b of billsDatas) {
  249. if (parentMap[b.ParentID]) {
  250. parentMap[b.ParentID].push(b);
  251. } else {
  252. parentMap[b.ParentID] = [b];
  253. }
  254. let flag = this.getFlag(b);
  255. if (this.isDef(flag) && flag.flag == this.fixedFlag.SUB_ENGINERRING) {
  256. subdivisionBillID = b.ID;
  257. }
  258. if (this.isDef(flag) && flag.flag == this.fixedFlag.CONSTRUCTION_TECH) {
  259. techBillID = b.ID;
  260. }
  261. }
  262. getLeaveIDs(subdivisionBillID, parentMap, sIDs);
  263. getLeaveIDs(techBillID, parentMap, tIDS);
  264. return [sIDs, tIDS];
  265. function getLeaveIDs(ID, parentM, leaveIDs) {
  266. if (parentM[ID] && parentM[ID].length > 0) {
  267. let children = parentM[ID];
  268. for (let c of children) {
  269. if (parentM[c.ID]) {
  270. getLeaveIDs(c.ID, parentM, leaveIDs);
  271. } else {
  272. leaveIDs.push(c.ID);
  273. }
  274. }
  275. }
  276. }
  277. },
  278. getFlag: function (b) {
  279. let lo_sh = typeof _ !== 'undefined' ? _ : this._;
  280. return lo_sh.find(b.flags, {
  281. "fieldName": "fixed"
  282. });
  283. },
  284. getGLJPrice: function (glj, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, isRadio, _, scMathUtil, ext, tenderCoe, isReport) {
  285. let result = {};
  286. if (isReport) {
  287. result.marketPrice = this.getMarketPrice(glj, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, isRadio, _, scMathUtil, tenderCoe, ext);
  288. } else {
  289. result.marketPrice = this.getMarketPrice(glj, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, isRadio, _, scMathUtil);
  290. result.tenderPrice = this.getMarketPrice(glj, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, isRadio, _, scMathUtil, tenderCoe);
  291. }
  292. if (this.calcPriceDiff(glj, calcOptions) == true) { //计取价差
  293. result.basePrice = this.getBasePrice(glj, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, isRadio, _, scMathUtil);
  294. result.adjustPrice = this.getAdjustPrice(glj, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, isRadio, _, scMathUtil);
  295. } else { //不计价差
  296. result.basePrice = result.marketPrice;
  297. result.adjustPrice = result.marketPrice;
  298. }
  299. return result;
  300. },
  301. getMarketPrice: function (glj, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, isRadio, _, scMathUtil, tenderCoe, ext) {
  302. let price_decimal = decimalObj.glj.unitPrice;
  303. let price_hasM_decimal = decimalObj.glj.unitPriceHasMix ? decimalObj.glj.unitPriceHasMix : decimalObj.glj.unitPrice;
  304. let quantity_decimal = decimalObj.glj.quantity;
  305. let process_decimal = this.isDef(decimalObj.marketPriceProcess) ? decimalObj.marketPriceProcess : decimalObj.process; //20200722 旧的项目还是默认6位,新的用两位
  306. let feeRate_decimal = decimalObj.feeRate;
  307. let priceCoe = this.isDef(tenderCoe) ? tenderCoe : 1;
  308. if (priceCoe == '0' || priceCoe == 0) priceCoe = 1; // 这里加个保护
  309. if (['GLF', 'LR', 'FXF'].includes(glj.code)) priceCoe = 1; // 类型是“企业管理费”、“利润”、“一般风险费”的,不应调整单价。
  310. if (!this.isConcreteType(glj.unit_price.type) && this.notEditType.indexOf(glj.unit_price.type) != -1 && glj.ratio_data.length > 0) { //对于机械台班等有组成物的材料,价格需根据组成物计算得出(排除混凝土、配合比、砂浆这几个类型直接为0)。
  311. let p = 0;
  312. let consSum = 0; //不变费用总和
  313. let temSum = 0;//可变费用总和
  314. //不变费用组成物包括:折旧费、检修费、维护费、安拆辅助费,这几个材料只能通过名称判断了,类型没有细分。
  315. let constNames = ['折旧费','检修费','维护费','安拆辅助费'];
  316. let constCoe = scMathUtil.roundForObj(projectGLJDatas.constData.machineConstCoe,feeRate_decimal);
  317. for (let ratio of glj.ratio_data) {
  318. let rIndex = gljUtil.getIndex(ratio);
  319. let tem = null;
  320. if(projectGLJDatas.gljMap){
  321. tem = projectGLJDatas.gljMap[rIndex]
  322. }
  323. if(!tem){
  324. tem = _.find(projectGLJDatas.gljList, function (item) {
  325. return rIndex == gljUtil.getIndex(item);
  326. });
  327. }
  328. if (tem) {
  329. let tem_marketPrice = this.getMarketPrice(tem, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, true, _, scMathUtil);
  330. if (ext && ext[tem.id] && this.isDef(ext[tem.id].marketPrice)) { //在修改组成物的价格或消耗量时,影响了父工料机的价格,这时以父工料机的价格应当用组成物的新值来记算
  331. tem_marketPrice = ext[tem.id].marketPrice;
  332. };
  333. let temP = scMathUtil.roundForObj(tem_marketPrice * priceCoe, price_decimal) * scMathUtil.roundForObj(ratio.consumption, quantity_decimal);
  334. if(decimalObj.temProcess) temP = scMathUtil.roundForObj(temP, decimalObj.temProcess);//取两次防止中间过程使用两位导致 4舍5入后少0.01的情况
  335. temP = scMathUtil.roundForObj(temP,process_decimal);
  336. if(constNames.includes(tem.name) && constCoe !== 1){//不等于1的时候才要另外计算
  337. temP = scMathUtil.roundForObj(temP*constCoe,process_decimal);
  338. consSum = scMathUtil.roundForObj(temP + consSum,process_decimal);
  339. }else {
  340. temSum = scMathUtil.roundForObj(temP + temSum, process_decimal);
  341. }
  342. }
  343. }
  344. return scMathUtil.roundForObj(temSum + consSum, price_hasM_decimal);
  345. } else {
  346. let tem_decimal = price_decimal; //isRadio==true?process_decimal:price_decimal;
  347. let tem_price = scMathUtil.roundForObj(glj.unit_price.market_price, price_decimal);
  348. return scMathUtil.roundForObj(tem_price * priceCoe, tem_decimal);
  349. }
  350. },
  351. getBasePrice: function (glj, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, isRadio, _, scMathUtil) {
  352. let price_decimal = decimalObj.glj.unitPrice;
  353. let price_hasM_decimal = decimalObj.glj.unitPriceHasMix ? decimalObj.glj.unitPriceHasMix : decimalObj.glj.unitPrice;
  354. let quantity_decimal = decimalObj.glj.quantity;
  355. let process_decimal = decimalObj.process;
  356. if (this.notEditType.indexOf(glj.unit_price.type) != -1 && glj.ratio_data.length > 0) { //对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
  357. //2018-09-07 需求修改,定额价不按组成物的量和价实时计算出来,直接取单价文件中的定额价
  358. /* let p =0;
  359. for(let ratio of glj.ratio_data){
  360. let tem = _.find( projectGLJDatas.gljList,{
  361. 'code': ratio.code,
  362. 'name': ratio.name,
  363. 'specs':ratio.specs,
  364. 'type': ratio.type,
  365. 'unit': ratio.unit
  366. });
  367. if(tem){
  368. let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
  369. let temP = scMathUtil.roundForObj(priceData.basePrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
  370. p = scMathUtil.roundForObj(temP + p,process_decimal);
  371. }
  372. }
  373. return scMathUtil.roundForObj(p,price_hasM_decimal);*/
  374. return scMathUtil.roundForObj(glj.unit_price.base_price, price_hasM_decimal);
  375. } else {
  376. let tem_decimal = price_decimal; //isRadio==true?process_decimal:price_decimal;
  377. return scMathUtil.roundForObj(glj.unit_price.base_price, tem_decimal);
  378. }
  379. },
  380. getAdjustPrice: function (glj, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, isRadio, _, scMathUtil) {
  381. let decimal = decimalObj.glj.unitPrice;
  382. let price_hasM_decimal = decimalObj.glj.unitPriceHasMix ? decimalObj.glj.unitPriceHasMix : decimalObj.glj.unitPrice;
  383. let quantity_decimal = decimalObj.glj.quantity;
  384. let process_decimal = this.isDef(decimalObj.marketPriceProcess) ? decimalObj.marketPriceProcess : decimalObj.process;
  385. let tem_decimal = isRadio == true ? process_decimal : decimal;
  386. if (glj.unit_price.type == this.gljType.LABOUR || glj.unit_price.type == this.gljType.MACHINE_LABOUR) { //人工、机上人工,调整价根据定额价*调整系数计算得出。
  387. let labour = _.find(labourCoeDatas.coes, {
  388. 'ID': glj.adjCoe
  389. });
  390. let coe = labour && labour.coe ? labour.coe : 1;
  391. return scMathUtil.roundForObj(coe * scMathUtil.roundForObj(glj.unit_price.base_price, decimal), decimal);
  392. } else if (this.notEditType.indexOf(glj.unit_price.type) != -1 && glj.ratio_data.length > 0) { //对于混凝土、配合比、砂浆、机械台班,调整价根据组成物计算得出。
  393. let p = 0;
  394. for (let ratio of glj.ratio_data) {
  395. let rIndex = gljUtil.getIndex(ratio);
  396. let tem = null;
  397. if(projectGLJDatas.gljMap){
  398. tem = projectGLJDatas.gljMap[rIndex]
  399. }
  400. if(!tem){
  401. tem = _.find(projectGLJDatas.gljList,function(item){
  402. return rIndex == gljUtil.getIndex(item);
  403. });
  404. }
  405. if (tem) {
  406. let priceData = this.getGLJPrice(tem, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, true, _, scMathUtil);
  407. let temP = scMathUtil.roundForObj(priceData.adjustPrice * scMathUtil.roundForObj(ratio.consumption, quantity_decimal), process_decimal);
  408. p = scMathUtil.roundForObj(temP + p, process_decimal);
  409. }
  410. }
  411. return scMathUtil.roundForObj(p, price_hasM_decimal);
  412. } else { //对于其他普通材料等,无调整系数,调整价=定额价。
  413. return scMathUtil.roundForObj(glj.unit_price.base_price, decimal)
  414. }
  415. },
  416. calcPriceDiff: function (glj, calcOptions) {
  417. if (glj.is_evaluate == 1) { //先按是否暂估判断
  418. return calcOptions.calc_est;
  419. }
  420. if (glj.type == this.gljType.MAIN_MATERIAL || glj.type == this.gljType.EQUIPMENT) { //再判断是否是主材和设备
  421. return calcOptions.calc_main;
  422. }
  423. if (glj.unit_price.is_add == 1) { //再判断是否新增
  424. return calcOptions.calc_add;
  425. }
  426. return true;
  427. },
  428. isFlag: function (v) {
  429. return this.isDef(v.flagsIndex) && this.isDef(v.flagsIndex.fixed) && this.isDef(v.flagsIndex.fixed.flag);
  430. },
  431. isDef: function (v) {
  432. return v !== undefined && v !== null;
  433. },
  434. nullString(key){
  435. return (key === undefined || key === null || key === '') ? 'null' : key
  436. },
  437. getIndex(obj, pops) {
  438. let t_index = '';
  439. let k_arr = [];
  440. if(!pops) pops = this.gljKeyArray;
  441. if(pops.length === 5){
  442. return `${this.nullString(obj[pops[0]])}|-|${this.nullString(obj[pops[1]])}|-|${this.nullString(obj[pops[2]])}|-|${this.nullString(obj[pops[3]])}|-|${this.nullString(obj[pops[4]])}`
  443. }else{
  444. for (let p of pops) {
  445. let tmpK = (obj[p] == undefined || obj[p] == null || obj[p] == '') ? 'null' : obj[p];
  446. k_arr.push(tmpK);
  447. }
  448. t_index = k_arr.join("|-|");
  449. return t_index;
  450. }
  451. },
  452. getMainType: function (type) {
  453. let str = type + "";
  454. return parseInt(str.substr(0, 1));
  455. },
  456. sortRationGLJ: function (list, std) {
  457. const field = std ? 'gljType' : 'type';
  458. let lo_sh = typeof _ !== 'undefined' ? _ : this._;
  459. list = lo_sh.sortByAll(list, [function (item) {
  460. return gljUtil.getMainType(item[field]);
  461. }, gljUtil.getCodeSortMath()]);
  462. return list;
  463. },
  464. sortMixRatio: function (list) {
  465. let lo_sh = typeof _ !== 'undefined' ? _ : this._;
  466. return lo_sh.sortByAll(list, ["code"]);
  467. },
  468. //项目工料机 混凝土、砂浆、配合比排序与定额工料机不一样,同时,type取值的地方不一样
  469. sortProjectGLJ: function (list, lodash) {
  470. let lo = lodash ? lodash : _;
  471. let specialMap = {
  472. 1: -1,
  473. 303: 0,
  474. 202: 9,
  475. 203: 10,
  476. 204: 11
  477. }; //,人工、机械工排在最前,混凝土、砂浆、配合比 排到最后
  478. list = lo.sortByAll(list, [function (item) {
  479. let unit_price = item.unit_price ? item.unit_price : item;
  480. if (specialMap[unit_price.type] != undefined) return specialMap[unit_price.type];
  481. return gljUtil.getMainType(unit_price.type);
  482. }, gljUtil.getCodeSortMath()]);
  483. return list;
  484. },
  485. getCodeSortMath: function () {
  486. return "code"
  487. },
  488. isConcreteType: function (type) {
  489. let concreteType = [gljUtil.gljType.CONCRETE, gljUtil.gljType.MORTAR, gljUtil.gljType.MIX_RATIO]; //混凝土大类:混凝土、砂浆,配合比
  490. return concreteType.indexOf(type) != -1
  491. },
  492. isCommercialConcreteType: function (type) {
  493. let commercialType = [gljUtil.gljType.COMMERCIAL_CONCRETE, gljUtil.gljType.COMMERCIAL_MORTAR]; //商品混凝土、商品砂浆
  494. return commercialType.indexOf(type) != -1
  495. },
  496. //是否从混凝土改成商品混凝土,并且混凝土的定额消耗量不为空,则原混凝土的自定义消耗改成0,插入一条新的商品混凝土自定义消耗量为原自定义或定额消耗
  497. isAddCommercialForReplace: function (oldType, newType, rationItemQuantity) {
  498. return this.isConcreteToCommercialConcrete(oldType, newType) && rationItemQuantity && rationItemQuantity != '0';
  499. },
  500. isMaterialType: function (type) {
  501. let materialType = [gljType.GENERAL_MATERIAL, gljType.GREEN_SEEDLING, gljType.PURCHASE_COMPONENT, gljType.COMMERCIAL_CONCRETE, gljType.COMMERCIAL_MORTAR]; //可以添加材料计算的类型普通材料”、“绿化苗木”、“外购砼构件”、“商品混凝土”、“商品砂浆”
  502. return materialType.indexOf(type) != -1
  503. },
  504. isConcreteToCommercialConcrete: function (oldType, newType) {
  505. return gljUtil.isConcreteType(oldType) && gljUtil.isCommercialConcreteType(newType)
  506. },
  507. hasComposition: function (ration_glj, isRationType) { //判断是否有组成物,有则返回true 现在主材类型的工料机也有可能有组成物。
  508. let type = isRationType == true ? ration_glj.subType : ration_glj.type;
  509. if (this.notEditType.indexOf(type) != -1 || type == gljType.MAIN_MATERIAL) {
  510. let keyArray = isRationType == true ? rationKeyArray : gljKeyArray;
  511. let con_key = this.getIndex(ration_glj, keyArray);
  512. var mixRatioMap = projectObj.project.projectGLJ.datas.mixRatioMap;
  513. if (mixRatioMap[con_key] && mixRatioMap[con_key].length > 0) {
  514. return true;
  515. }
  516. }
  517. return false;
  518. },
  519. getCCSProjectGLJ: function (unitFileID, project_id) {
  520. return {
  521. "ratio_data": [],
  522. "unit_price": {
  523. "base_price": "1",
  524. "market_price": "1",
  525. "code": "80CCS",
  526. "name": "车船税",
  527. "unit_price_file_id": unitFileID,
  528. "type": 302,
  529. "short_name": "机",
  530. "glj_id": -99,
  531. "unit": "元",
  532. "original_code": "80CCS",
  533. "id": -99,
  534. "is_add": 0,
  535. "specs": ""
  536. },
  537. "glj_id": -99,
  538. "project_id": project_id,
  539. "code": "80CCS",
  540. "unit": "元",
  541. "type": 302,
  542. "original_code": "80CCS",
  543. "id": -99,
  544. "from": "std",
  545. "is_main_material": 1,
  546. "specs": "",
  547. "is_adjust_price": 0,
  548. "delivery_address": "",
  549. "delivery": "",
  550. "supply_quantity": 0,
  551. "supply": 0,
  552. "is_evaluate": 0,
  553. "name": "车船税"
  554. }
  555. },
  556. getBaseCCSMixRatio: function (unitFileID, consumption, connect_key) {
  557. return {
  558. glj_id: -99,
  559. unit_price_file_id: unitFileID,
  560. connect_key: connect_key,
  561. consumption: consumption,
  562. code: '80CCS',
  563. name: '车船税',
  564. unit: '元',
  565. type: 302,
  566. specs: '',
  567. from: "cpt"
  568. }
  569. },
  570. updateProperty: function (obj, doc) {
  571. let lo_sh = typeof _ !== 'undefined' ? _ : this._;
  572. lo_sh.forEach(doc, function (n, key) {
  573. obj[key] = n;
  574. });
  575. },
  576. getTotalQuantity: function (glj, ration, rd, gd) {
  577. if (ration) {
  578. let quantity = ration.quantity;
  579. quantity = (quantity == 0 || quantity == undefined || quantity == null || quantity == "") ? 0 : quantity;
  580. quantity = scMathUtil.roundForObj(quantity, rd); //计算前进行4舍5入
  581. glj.quantity = scMathUtil.roundForObj(glj.quantity, gd);
  582. let pglj = calcTools.getProjectGLJ(glj);
  583. glj.tenderQuantity = this.getRationGLJTenderQuantity(glj, ration, gd, scMathUtil, pglj);
  584. return scMathUtil.roundForObj(quantity * glj.quantity, gd)+'';
  585. }
  586. },
  587. setMaterialCalcRationFee: function (ration, ration_gljs, projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, _, scMathUtil) {
  588. let pMap = _.indexBy(projectGLJDatas.gljList, 'id');
  589. let process_decimal = decimalObj.process;
  590. let ration_quantity_decimal = decimalObj.ration.quantity;
  591. let glj_quantity_decimal = decimalObj.glj.quantity;
  592. let glj_unitPrice_decimal = decimalObj.glj.unitPrice;
  593. let assFeeRate = scMathUtil.roundForObj(projectGLJDatas.constData.assistProductionFeeRate, decimalObj.feeRate) * 0.01; //辅助生产间接费费率
  594. let rationLaberFee = 0; //定额人工费(市场价)
  595. let rationMachineFee = 0; //定额施工机械使用费(市场价)
  596. let rationLaberFee_b = 0; //定额人工费(定额价)
  597. let rationMachineFee_b = 0; //定额施工机械使用费(定额价)
  598. let directFee = 0; //直接费
  599. let rationQuantity = scMathUtil.roundForObj(ration.quantity, ration_quantity_decimal);
  600. for (let g of ration_gljs) {
  601. let result = this.getGLJPrice(pMap[g.projectGLJID], projectGLJDatas, calcOptions, labourCoeDatas, decimalObj, false, _, scMathUtil);
  602. g.marketPrice = result.marketPrice;
  603. g.basePrice = result.basePrice;
  604. let quantity = scMathUtil.roundForObj(g.quantity, glj_quantity_decimal);
  605. let t = scMathUtil.roundForObj(quantity * g.marketPrice * rationQuantity, process_decimal); //市场价
  606. let rt = scMathUtil.roundForObj(quantity * g.basePrice * rationQuantity, process_decimal); //定额价
  607. if (g.type == this.gljType.LABOUR) {
  608. rationLaberFee = scMathUtil.roundForObj(rationLaberFee + t, process_decimal);
  609. rationLaberFee_b = scMathUtil.roundForObj(rationLaberFee_b + rt, process_decimal);
  610. } else if (this.getMainType(g.type) == 3) {
  611. rationMachineFee = scMathUtil.roundForObj(rationMachineFee + t, process_decimal);
  612. rationMachineFee_b = scMathUtil.roundForObj(rationMachineFee_b + rt, process_decimal);
  613. }
  614. directFee = scMathUtil.roundForObj(directFee + t, process_decimal);
  615. }
  616. ration.assistProductionFee = scMathUtil.roundForObj(rationLaberFee_b * assFeeRate, glj_unitPrice_decimal); //辅助生产间接费
  617. ration.rationLaberFee = scMathUtil.roundForObj(rationLaberFee, glj_unitPrice_decimal); //定额人工费(市场价)
  618. ration.rationMachineFee = scMathUtil.roundForObj(rationMachineFee, glj_unitPrice_decimal); //定额施工机械使用费(市场价)
  619. ration.directFee = scMathUtil.roundForObj(directFee, glj_unitPrice_decimal); //直接费
  620. //to do 高原取费类别的情况待确认
  621. //let hs = scMathUtil.roundForObj(tt*hightFeeRate,process_decimal);//(人工定额消耗量*定额价*定额工程量+机械定额消耗量*定额价*定额工程量)*高原取费类别费率
  622. },
  623. getAssUsedPrice: function (g) {
  624. return g.basePrice;
  625. },
  626. getElecCoe: function () {
  627. return 0.15;
  628. },
  629. getElecCode: function () {
  630. return '3005002';
  631. },
  632. getTenderPriceCoe: function (glj, tproperty) {
  633. let tenderCoe = 1;
  634. let property = tproperty ? tproperty : projectObj.project.property;
  635. if (!glj.is_adjust_price && property.tenderSetting && isDef(property.tenderSetting.gljPriceTenderCoe)) {
  636. tenderCoe = parseFloat(property.tenderSetting.gljPriceTenderCoe);
  637. if (tenderCoe == 0) tenderCoe = 1;
  638. }
  639. return tenderCoe;
  640. function isDef(v) {
  641. return v !== undefined && v !== null;
  642. }
  643. },
  644. setProperty: function (Obj, updateData) {
  645. let lo_sh = typeof _ !== 'undefined' ? _ : this._;
  646. for (let ukey in updateData) {
  647. if (lo_sh.isObject(updateData[ukey]) && lo_sh.isObject(Obj[ukey]) && !lo_sh.isArray(updateData[ukey])) {
  648. setProperty(Obj[ukey], updateData[ukey]);
  649. } else {
  650. Obj[ukey] = updateData[ukey];
  651. }
  652. }
  653. },
  654. isKGtoT: function (bills_unit, ration_unit) { //是否由KG转成T,b_unit清单单位,t_unit定额单位
  655. let t_unit = ration_unit ? ration_unit : "";
  656. let b_unit = bills_unit ? bills_unit : "";
  657. return (/.*kg$/i).test(b_unit) && (/.*t$/i).test(t_unit);
  658. },
  659. fixedFlag: {
  660. // 分部分项工程
  661. SUB_ENGINERRING: 1,
  662. // 措施项目
  663. MEASURE: 2,
  664. // 施工技术措施项目
  665. CONSTRUCTION_TECH: 3
  666. },
  667. gljType: {
  668. LABOUR: 1, // 人工
  669. // ==============材料类型 ↓=================
  670. GENERAL_MATERIAL: 201, // 普通材料
  671. CONCRETE: 202, // 混凝土
  672. MORTAR: 203, // 砂浆
  673. MIX_RATIO: 204, // 配合比
  674. COMMERCIAL_CONCRETE: 205, // 商品混凝土
  675. COMMERCIAL_MORTAR: 206, // 商品砂浆
  676. OTHER_MATERIAL: 207, // 其它材料
  677. PURCHASE_COMPONENT: 208, // 外购砼构件
  678. GREEN_SEEDLING: 209, // 绿化苗木
  679. // ==============材料类型 ↑=================
  680. // ==============机械类型 ↓=================
  681. GENERAL_MACHINE: 301, // 机械台班
  682. MACHINE_COMPOSITION: 302, // 机械组成物
  683. MACHINE_LABOUR: 303, // 机上人工
  684. INSTRUMENT: 304, // 仪器仪表
  685. FUEL_POWER_FEE: 305, // 燃料动力费
  686. DEPRECIATION_FEE: 306, // 折旧费
  687. INSPECTION_FEE: 307, // 检修费
  688. MAINTENANCE: 308, // 维护费
  689. DISMANTLING_FREIGHT_FEE: 309, // 安拆费及场外运费
  690. VERIFICATION_FEE: 310, // 校验费
  691. OTHER_FEE: 311, // 其他费用
  692. OTHER_MACHINE_USED: 312, // 其他施工机具使用费
  693. // ==============机械类型 ↑=================
  694. MAIN_MATERIAL: 4, // 主材
  695. EQUIPMENT: 5, // 设备
  696. MANAGEMENT_FEE: 6, // 企业管理费
  697. PROFIT: 7, // 利润
  698. GENERAL_RISK_FEE: 8 // 一般风险费
  699. },
  700. extraType: [6, 7, 8], //一些其它的工料机类型
  701. notEditType: [202, 203, 204, 301, 304, 4],
  702. gljKeyArray: ['code', 'name', 'specs', 'unit', 'type'],
  703. rationType: {
  704. ration: 1,
  705. volumePrice: 2,
  706. gljRation: 3,
  707. install: 4
  708. },
  709. hasCompMaterial: [202, 203, 204], //有组成物的材料
  710. hasCompMachine: [301], //有组成物的机械
  711. machineComposition: [201, 302, 303] //可以做为机械组成物的类型
  712. }
  713. if (typeof module !== 'undefined') {
  714. gljUtil._ = require("lodash");
  715. module.exports = gljUtil;
  716. }