gljUtil.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. /**
  2. * Created by zhang on 2018/6/7.
  3. */
  4. let gljUtil = {
  5. calcProjectGLJQuantity:function (projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal,_,scMathUtil,isTender) {
  6. let project_gljs = projectGLJDatas.gljList;
  7. let mixRatioMap = projectGLJDatas.mixRatioMap;
  8. let rations = rationDatas;
  9. let rationMap = _.indexBy(rations,'ID');
  10. let quantityMap={};
  11. let rationGljGroup = _.groupBy(rationGLJDatas,'projectGLJID');
  12. let IDarray = this.getSubdivisionAndTechBillsLeavesID(billsDatas);//分别取分部分项和技术措施项目的所有叶子清单ID
  13. let billIDs = IDarray[0],tech_billIDS = IDarray[1];
  14. let sField = isTender==true?"tenderSubdivisionQuantity":"subdivisionQuantity";
  15. let tField = isTender==true?"tenderTechQuantity":"techQuantity";
  16. let qField = isTender==true?"tenderQuantity":"quantity";
  17. for(let pglj of project_gljs ){
  18. let pg_index = this.getIndex(pglj,this.gljKeyArray);
  19. pglj[sField] = 0;
  20. pglj[tField] = 0;
  21. pglj[qField] = 0;
  22. let gljGroup = rationGljGroup[pglj.id]?rationGljGroup[pglj.id]:[];//定额工料机没有,有可能是定额类型的工料机
  23. let result = this.getQuantityPerGLJ(gljGroup,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil,isTender);
  24. pglj[sField] = result.subdivisionQuantity;
  25. pglj[tField] = result.techQuantity;
  26. pglj[qField] = result.quantity;
  27. quantityMap[pg_index] = pglj;
  28. }
  29. //计算做为组成物的消耗量
  30. for(let pkey in mixRatioMap){
  31. let mixRatioList = mixRatioMap[pkey];
  32. for(let m of mixRatioList){
  33. let m_index = this.getIndex(m,this.gljKeyArray);
  34. let m_glj = quantityMap[m_index];
  35. let p_glj = quantityMap[pkey];
  36. if(m_glj&&p_glj){
  37. let quantity = scMathUtil.roundForObj(parseFloat(p_glj[qField])*parseFloat(m.consumption),q_decimal);
  38. let techQuantity = scMathUtil.roundForObj(parseFloat(p_glj[tField])*parseFloat(m.consumption),q_decimal);
  39. let subdivisionQuantity = scMathUtil.roundForObj(parseFloat(p_glj[sField])*parseFloat(m.consumption),q_decimal);
  40. m_glj[qField] = scMathUtil.roundForObj(parseFloat(m_glj[qField])+quantity,q_decimal);
  41. m_glj[tField] = scMathUtil.roundForObj(parseFloat(m_glj[tField])+techQuantity,q_decimal);
  42. m_glj[sField] = scMathUtil.roundForObj(parseFloat(m_glj[sField])+subdivisionQuantity,q_decimal);
  43. }
  44. }
  45. }
  46. },
  47. getQuantityPerGLJ : function (ration_glj_list,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil,isTender) {
  48. let result={};
  49. let quantity_sum=0;//工料机汇总消耗量
  50. let sum = 0;//分部分项总消耗量
  51. let tech_sum = 0;//技术措施总消耗量
  52. for(let rg of ration_glj_list){
  53. let tem_ration = rationMap[rg.rationID];
  54. let r_quantity = tem_ration?scMathUtil.roundForObj(tem_ration.quantity,q_decimal):0;
  55. let glj_quantity = scMathUtil.roundForObj(rg.quantity, q_decimal);
  56. if(!r_quantity){
  57. continue;
  58. }
  59. if(isTender == true){
  60. glj_quantity = this.getRationGLJTenderQuantity(rg,tem_ration,q_decimal,scMathUtil);
  61. r_quantity = this.getRationTenderQuantity(tem_ration,q_decimal,scMathUtil);
  62. }
  63. let total = scMathUtil.roundForObj(glj_quantity*r_quantity, q_decimal);
  64. quantity_sum = scMathUtil.roundForObj(quantity_sum+total,q_decimal);
  65. if(_.includes(billIDs,rg.billsItemID)){//计算分部分项
  66. sum = scMathUtil.roundForObj(sum+total,q_decimal);
  67. }
  68. if(_.includes(tech_billIDS,rg.billsItemID)){//计算技术措施项目消耗量
  69. tech_sum = scMathUtil.roundForObj(tech_sum+total,q_decimal);
  70. }
  71. }
  72. for(let ra of rations){//计算定额类型工料机的消耗量
  73. if(ra.type == this.rationType.gljRation&&ra.projectGLJID===pglj.id){
  74. let r_quantity = scMathUtil.roundForObj(ra.quantity,q_decimal);
  75. r_quantity = r_quantity?r_quantity:0;
  76. if(isTender == true){
  77. r_quantity = this.getRationTenderQuantity(ra,q_decimal,scMathUtil);
  78. }
  79. quantity_sum = scMathUtil.roundForObj(quantity_sum+r_quantity,q_decimal);
  80. if(_.includes(billIDs,ra.billsItemID)){//计算分部分项
  81. sum = scMathUtil.roundForObj(sum+r_quantity,q_decimal);
  82. }
  83. if(_.includes(tech_billIDS,ra.billsItemID)){//计算技术措施项目消耗量
  84. tech_sum = scMathUtil.roundForObj(tech_sum+r_quantity,q_decimal);
  85. }
  86. }
  87. }
  88. result.subdivisionQuantity = sum;
  89. result.techQuantity = tech_sum;
  90. result.quantity = quantity_sum;
  91. return result;
  92. },
  93. getRationGLJTenderQuantity:function (ration_glj,ration,q_decimal,scMathUtil) {
  94. let coeMap = {
  95. 1:'labour', //人工
  96. 2:'material',//材料
  97. 3:'machine',//机械
  98. 4:'main', //主材
  99. 5:'equipment'//设备
  100. };
  101. let typeString = ration_glj.type +"";
  102. let coeField = "";
  103. for(let key in coeMap){
  104. if(typeString.indexOf(key)!= -1){
  105. coeField = coeMap[key];
  106. }
  107. }
  108. let coe = ration.quantityCoe&&this.isNotEmpty(ration.quantityCoe[coeField])?ration.quantityCoe[coeField]:1;
  109. coe = parseFloat(coe);
  110. let glj_quantity = scMathUtil.roundForObj(ration_glj.quantity, q_decimal);
  111. return scMathUtil.roundForObj(glj_quantity * coe,q_decimal);
  112. },
  113. getRationTenderQuantity:function (ration,q_decimal,scMathUtil) {
  114. let rationQuantityCoe = this.isNotEmpty(ration.rationQuantityCoe)?ration.rationQuantityCoe:1;
  115. rationQuantityCoe = parseFloat(rationQuantityCoe);
  116. let r_quantity = ration?scMathUtil.roundForObj(ration.quantity,q_decimal):0;
  117. return scMathUtil.roundForObj(r_quantity * rationQuantityCoe,q_decimal);
  118. },
  119. isNotEmpty:function (str) {
  120. return this.isDef(str) && str!="";
  121. },
  122. getSubdivisionAndTechBillsLeavesID:function (billsDatas) {//分别取分部分项和技术措施项目的所有叶子清单ID
  123. if(typeof (projectObj) !== 'undefined'){//存在,说明在前端调用
  124. return [projectObj.project.Bills.getSubdivisionProjectLeavesID(),projectObj.project.Bills.getTechLeavesID()];
  125. }
  126. let parentMap ={};
  127. let subdivisionBillID = null,techBillID = null,sIDs = [],tIDS = [];
  128. for(let b of billsDatas){
  129. if(parentMap[b.ParentID]){
  130. parentMap[b.ParentID].push(b);
  131. }else {
  132. parentMap[b.ParentID]= [b];
  133. }
  134. let flag = this.getFlag(b);
  135. if(this.isDef(flag)&&flag.flag == this.fixedFlag.SUB_ENGINERRING){
  136. subdivisionBillID = b.ID;
  137. }
  138. if(this.isDef(flag)&&flag.flag == this.fixedFlag.CONSTRUCTION_TECH){
  139. techBillID = b.ID;
  140. }
  141. }
  142. getLeaveIDs(subdivisionBillID,parentMap,sIDs);
  143. getLeaveIDs(techBillID,parentMap,tIDS);
  144. return [sIDs,tIDS];
  145. function getLeaveIDs(ID,parentM,leaveIDs) {
  146. if(parentM[ID] && parentM[ID].length > 0){
  147. let children = parentM[ID];
  148. for(let c of children){
  149. if(parentM[c.ID]){
  150. getLeaveIDs(c.ID,parentM,leaveIDs);
  151. }else {
  152. leaveIDs.push(c.ID);
  153. }
  154. }
  155. }
  156. }
  157. },
  158. getFlag:function (b) {
  159. return _.find(b.flags,{"fieldName":"fixed"});
  160. },
  161. getGLJPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil) {
  162. let result = {};
  163. result.marketPrice = this.getMarketPrice(glj,projectGLJDatas,calcOptions,decimalObj,isRadio,_,scMathUtil);
  164. if(this.calcPriceDiff(glj,calcOptions)==true){//计取价差
  165. result.basePrice = this.getBasePrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
  166. result.adjustPrice = this.getAdjustPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
  167. }else {//不计价差
  168. result.basePrice = result.marketPrice;
  169. result.adjustPrice = result.marketPrice;
  170. }
  171. return result;
  172. },
  173. getMarketPrice:function (glj,projectGLJDatas,calcOptions,decimalObj,isRadio,_,scMathUtil,tenderCoe) {
  174. let price_decimal = decimalObj.glj.unitPrice;
  175. let price_hasM_decimal = decimalObj.glj.unitPriceHasMix?decimalObj.glj.unitPriceHasMix:decimalObj.glj.unitPrice;
  176. let quantity_decimal = decimalObj.glj.quantity;
  177. let process_decimal = decimalObj.process;
  178. let priceCoe = this.isDef(tenderCoe)?tenderCoe:1;
  179. if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
  180. let p =0;
  181. for(let ratio of glj.ratio_data){
  182. let tem = _.find(projectGLJDatas.gljList,{
  183. 'code': ratio.code,
  184. 'name': ratio.name,
  185. 'specs':ratio.specs,
  186. 'type': ratio.type,
  187. 'unit': ratio.unit
  188. });
  189. if(tem){
  190. let tem_marketPrice = this.getMarketPrice(tem,projectGLJDatas,calcOptions,decimalObj,true,_,scMathUtil); //let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
  191. let temP = scMathUtil.roundForObj(tem_marketPrice * priceCoe * scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
  192. p = scMathUtil.roundForObj(temP + p,process_decimal);
  193. }
  194. }
  195. return scMathUtil.roundForObj(p,price_hasM_decimal);
  196. }else {
  197. let tem_decimal =price_decimal; //isRadio==true?process_decimal:price_decimal;
  198. let tem_price = scMathUtil.roundForObj(glj.unit_price.market_price,price_decimal);
  199. return scMathUtil.roundForObj(tem_price*priceCoe,tem_decimal);
  200. }
  201. },
  202. getBasePrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil) {
  203. let price_decimal = decimalObj.glj.unitPrice;
  204. let price_hasM_decimal = decimalObj.glj.unitPriceHasMix?decimalObj.glj.unitPriceHasMix:decimalObj.glj.unitPrice;
  205. let quantity_decimal = decimalObj.glj.quantity;
  206. let process_decimal = decimalObj.process;
  207. if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
  208. //2018-09-07 需求修改,定额价不按组成物的量和价实时计算出来,直接取单价文件中的定额价
  209. /* let p =0;
  210. for(let ratio of glj.ratio_data){
  211. let tem = _.find( projectGLJDatas.gljList,{
  212. 'code': ratio.code,
  213. 'name': ratio.name,
  214. 'specs':ratio.specs,
  215. 'type': ratio.type,
  216. 'unit': ratio.unit
  217. });
  218. if(tem){
  219. let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
  220. let temP = scMathUtil.roundForObj(priceData.basePrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
  221. p = scMathUtil.roundForObj(temP + p,process_decimal);
  222. }
  223. }
  224. return scMathUtil.roundForObj(p,price_hasM_decimal);*/
  225. return scMathUtil.roundForObj(glj.unit_price.base_price,price_hasM_decimal);
  226. }else {
  227. let tem_decimal =price_decimal; //isRadio==true?process_decimal:price_decimal;
  228. return scMathUtil.roundForObj(glj.unit_price.base_price,tem_decimal);
  229. }
  230. },
  231. //这个函数isRadio目前看来没有用,如果后续改了方法,导致isRadio的值会影响结果的话,需要调整调用这个方法的地方.
  232. getAdjustPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil) {
  233. let decimal = decimalObj.glj.unitPrice;
  234. let price_hasM_decimal = decimalObj.glj.unitPriceHasMix?decimalObj.glj.unitPriceHasMix:decimalObj.glj.unitPrice;
  235. let quantity_decimal = decimalObj.glj.quantity;
  236. let process_decimal = decimalObj.process;
  237. let tem_decimal = isRadio==true?process_decimal:decimal;
  238. if (glj.unit_price.type == this.gljType.LABOUR || glj.unit_price.type == this.gljType.MACHINE_LABOUR) {//人工、机上人工,调整价根据定额价*调整系数计算得出。
  239. let labour = _.find(labourCoeDatas.coes,{'ID':glj.adjCoe});
  240. let coe = labour && labour.coe ? labour.coe : 1;
  241. return scMathUtil.roundTo(parseFloat(coe * scMathUtil.roundForObj(glj.unit_price.base_price,decimal)), -decimal);
  242. } else if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班,调整价根据组成物计算得出。
  243. let p =0;
  244. for(let ratio of glj.ratio_data){
  245. let tem = _.find( projectGLJDatas.gljList,{
  246. 'code': ratio.code,
  247. 'name': ratio.name,
  248. 'specs':ratio.specs,
  249. 'type': ratio.type,
  250. 'unit': ratio.unit
  251. })
  252. if(tem){
  253. let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
  254. let temP = scMathUtil.roundForObj(priceData.adjustPrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
  255. p = scMathUtil.roundForObj(temP + p,process_decimal);
  256. }
  257. }
  258. return scMathUtil.roundForObj(p,price_hasM_decimal);
  259. } else {//对于其他普通材料等,无调整系数,调整价=定额价。
  260. return scMathUtil.roundForObj(glj.unit_price.base_price,decimal)
  261. }
  262. },
  263. calcPriceDiff:function (glj,calcOptions) {
  264. if(glj.is_evaluate==1){//先按是否暂估判断
  265. return calcOptions.calc_est;
  266. }
  267. if(glj.type==gljType.MAIN_MATERIAL||glj.type==gljType.EQUIPMENT){//再判断是否是主材和设备
  268. return calcOptions.calc_main;
  269. }
  270. if(glj.unit_price.is_add==1){//再判断是否新增
  271. return calcOptions.calc_add;
  272. }
  273. return true;
  274. },
  275. isFlag : function (v) {
  276. return this.isDef(v.flagsIndex) && this.isDef(v.flagsIndex.fixed) && this.isDef(v.flagsIndex.fixed.flag);
  277. },
  278. isDef:function (v) {
  279. return v !== undefined && v !== null;
  280. },
  281. getIndex(obj, pops){
  282. let t_index = '';
  283. let k_arr = [];
  284. if(!pops) pops = this.gljKeyArray;
  285. for (let p of pops) {
  286. let tmpK = (obj[p] == undefined || obj[p] == null || obj[p] == '') ? 'null' : obj[p];
  287. k_arr.push(tmpK);
  288. }
  289. t_index = k_arr.join("|-|");
  290. return t_index;
  291. },
  292. getGljTypeSeq:function () {
  293. let gljType = this.gljType;
  294. return [gljType.LABOUR,gljType.MAIN_MATERIAL,gljType.CONCRETE,gljType.MORTAR,gljType.MIX_RATIO,gljType.COMMERCIAL_CONCRETE,
  295. gljType.COMMERCIAL_MORTAR,gljType.GENERAL_MATERIAL,gljType.OTHER_MATERIAL,gljType.GENERAL_MACHINE,gljType.INSTRUMENT,gljType.OTHER_MACHINE_USED,
  296. gljType.MACHINE_COMPOSITION,gljType.MACHINE_LABOUR,gljType.FUEL_POWER_FEE,gljType.DEPRECIATION_FEE,gljType.INSPECTION_FEE,gljType.MAINTENANCE,
  297. gljType.DISMANTLING_FREIGHT_FEE,gljType.VERIFICATION_FEE,gljType.OTHER_FEE,gljType.EQUIPMENT,gljType.MANAGEMENT_FEE,gljType.PROFIT,gljType.GENERAL_RISK_FEE]
  298. },
  299. sortRationGLJ:function (list,std) {
  300. list = _.sortByAll(list, [function (item) {
  301. let typeField = std == true?"gljType":"type";
  302. return _.indexOf(gljUtil.getGljTypeSeq(),item[typeField])
  303. }, "code"]);
  304. return list;
  305. },
  306. getTotalQuantity:function(glj,ration,rd,gd){
  307. if(ration){
  308. let quantity = ration.quantity;
  309. quantity = (quantity == 0 || quantity == undefined || quantity == null || quantity == "") ? 0 : quantity;
  310. quantity = scMathUtil.roundForObj(quantity, rd);//计算前进行4舍5入
  311. glj.quantity = scMathUtil.roundForObj(glj.quantity, gd);
  312. return scMathUtil.roundToString(quantity * glj.quantity, gd);
  313. }
  314. },
  315. getEngineerCostData:function(property,bills,fixedFlag,scMathUtil){
  316. let priceIndex = {
  317. name:"工程造价指标",
  318. attrs:[],
  319. children:[],
  320. };
  321. let fixMap = {};
  322. let buildingArea = this.getBuildArea(property.engineerFeatures); //tender.property.projectFeature?getItemValueBykey(tender.property.projectFeature,"buildingArea"):1;//建筑面积
  323. for(let b of bills){
  324. if(b.flags && b.flags.length > 0){
  325. let f = _.find(b.flags,{"fieldName":"fixed"});
  326. if(f) fixMap[f.flag] = this.getTotalFee(b,scMathUtil,property.decimal);
  327. }
  328. }
  329. //计算其他组织措施费 = 施工组织措施项目下的子项,除了 安全文明施工费、建设工程竣工档案编制费以外的项
  330. let CONSTRUCTION_ORGANIZATION = fixMap[fixedFlag.CONSTRUCTION_ORGANIZATION]?fixMap[fixedFlag.CONSTRUCTION_ORGANIZATION]:0;
  331. let SAFETY_CONSTRUCTION = fixMap[fixedFlag.SAFETY_CONSTRUCTION]?fixMap[fixedFlag.SAFETY_CONSTRUCTION]:0;
  332. let PROJECT_COMPLETE_ARCH_FEE = fixMap[fixedFlag.PROJECT_COMPLETE_ARCH_FEE]? fixMap[fixedFlag.PROJECT_COMPLETE_ARCH_FEE]:0;
  333. let other_org_fee = CONSTRUCTION_ORGANIZATION - SAFETY_CONSTRUCTION - PROJECT_COMPLETE_ARCH_FEE;
  334. other_org_fee = other_org_fee >0 ?other_org_fee:0;
  335. let engineerCost = fixMap[fixedFlag.ENGINEERINGCOST]?fixMap[fixedFlag.ENGINEERINGCOST]:1;
  336. priceIndex.children.push(this.getEngineerFlag("分部分项工程费",fixMap[fixedFlag.SUB_ENGINERRING],engineerCost,buildingArea,scMathUtil));
  337. priceIndex.children.push(this.getEngineerFlag("技术措施费",fixMap[fixedFlag.CONSTRUCTION_TECH],engineerCost,buildingArea,scMathUtil));
  338. priceIndex.children.push(this.getEngineerFlag("安全文明施工费",fixMap[fixedFlag.SAFETY_CONSTRUCTION],engineerCost,buildingArea,scMathUtil));
  339. priceIndex.children.push(this.getEngineerFlag("建设工程竣工档案编制费",fixMap[fixedFlag.PROJECT_COMPLETE_ARCH_FEE],engineerCost,buildingArea,scMathUtil));
  340. priceIndex.children.push(this.getEngineerFlag("其他组织措施费",other_org_fee,engineerCost,buildingArea,scMathUtil));
  341. priceIndex.children.push(this.getEngineerFlag("暂列金额",fixMap[fixedFlag.PROVISIONAL],engineerCost,buildingArea,scMathUtil));
  342. priceIndex.children.push(this.getEngineerFlag("专业工程暂估价",fixMap[fixedFlag.ENGINEERING_ESITIMATE],engineerCost,buildingArea,scMathUtil));
  343. priceIndex.children.push(this.getEngineerFlag("计日工",fixMap[fixedFlag.DAYWORK],engineerCost,buildingArea,scMathUtil));
  344. priceIndex.children.push(this.getEngineerFlag("总承包服务费",fixMap[fixedFlag.TURN_KEY_CONTRACT],engineerCost,buildingArea,scMathUtil));
  345. priceIndex.children.push(this.getEngineerFlag("索赔与现场签证",fixMap[fixedFlag.CLAIM_VISA],engineerCost,buildingArea,scMathUtil));
  346. priceIndex.children.push(this.getEngineerFlag("规费",fixMap[fixedFlag.CHARGE],engineerCost,buildingArea,scMathUtil));
  347. priceIndex.children.push(this.getEngineerFlag("税金",fixMap[fixedFlag.TAX],engineerCost,buildingArea,scMathUtil));
  348. priceIndex.children.push(this.getEngineerFlag("工程造价",fixMap[fixedFlag.ENGINEERINGCOST],engineerCost,buildingArea,scMathUtil));
  349. return priceIndex;
  350. },
  351. getBuildArea:function (features) {
  352. if(features){
  353. let areas = [];
  354. for(let f of features){
  355. if(f.index == true && f.value && f.value !=="" && this.IsNumber(f.value)) areas.push(f.value);
  356. }
  357. return areas.length==0?1:areas;
  358. }
  359. return 1
  360. },
  361. getEngineerFlag: function (name,totalCost,engineerCost,buildingArea,scMathUtil) {
  362. totalCost = totalCost?totalCost:0;
  363. let flag = {
  364. name:name,
  365. attrs:[
  366. {name: "金额", value: scMathUtil.roundToString(totalCost,3)},
  367. {name: "单方造价", value: scMathUtil.roundToString(this.calcUnitB(totalCost,buildingArea,scMathUtil),2)},
  368. {name: "占造价比例", value: scMathUtil.roundToString(totalCost/engineerCost * 100,2)},
  369. ],
  370. };
  371. return flag;
  372. },
  373. getTotalFee:function (b,scMathUtil,decimal) {
  374. let total = 0;
  375. if(b.fees && b.fees.length > 0){
  376. for(let f of b.fees){
  377. if(f.fieldName == "common"){
  378. total = scMathUtil.roundForObj(f.totalFee,decimal?decimal.bills.totalPrice:getDecimal("bills.totalPrice"));
  379. }
  380. }
  381. }
  382. return total;
  383. },
  384. IsNumber : function(pstrVal){
  385. let dblNo = Number.NaN;
  386. dblNo = new Number(pstrVal);
  387. if (isNaN(dblNo)) return false;
  388. return true;
  389. },
  390. calcUnitB:function (total,building,scMathUtil,coe,decimal = 3) {
  391. if(Array.isArray(building)){
  392. for(let b of building){
  393. total = scMathUtil.roundForObj(total/b,6);
  394. }
  395. }else {
  396. total = scMathUtil.roundForObj(total/building,6);
  397. }
  398. coe = gljUtil.isDef(coe)?coe:1;
  399. return scMathUtil.roundForObj(total*coe,decimal);
  400. },
  401. getEconomicDatas:function(engineerFeatures,economics,billsList,fixedFlag,_,scMathUtil,decimal){
  402. let datas = [];
  403. let [bills,totalFee] = gljUtil.getIndexBills(billsList,fixedFlag,_,scMathUtil,decimal);
  404. let billsGroup = _.groupBy(bills,'economicType');
  405. if(!economics) return datas;
  406. for(let e of economics){
  407. let tem = {
  408. name:e.name,
  409. cost:0,
  410. unitCost:0,
  411. per:0
  412. };
  413. if(billsGroup[e.name]) setEconomics(billsGroup[e.name],totalFee,tem);
  414. datas.push(tem);
  415. }
  416. function setEconomics(items,engineerCost,data) {
  417. let cost = 0;
  418. let priceDe = decimal?decimal.bills.totalPrice:getDecimal("bills.totalPrice");//getDecimal("bills.totalPrice");
  419. for(let i of items){
  420. i.totalFee = scMathUtil.roundForObj(i.totalFee,priceDe);
  421. cost = scMathUtil.roundForObj(cost + i.totalFee,decimal?decimal.process:getDecimal("process"))//getDecimal("process");
  422. }
  423. data.cost = scMathUtil.roundForObj(cost,priceDe,_);
  424. data.unitCost = gljUtil.calUnitWidthCoe(data.cost,true,engineerFeatures,_,scMathUtil);//noNeedCoe = true 这里不需要乘以系数
  425. data.per = engineerCost?scMathUtil.roundForObj(data.cost/engineerCost * 100,2):0;
  426. }
  427. return datas;
  428. },
  429. calUnitWidthCoe:function (total,noNeedCoe,engineerFeatures,_,scMathUtil) {
  430. let areas = gljUtil.getBuildArea(engineerFeatures);
  431. let f = _.find(engineerFeatures,{index:true});
  432. return f && noNeedCoe!==true?gljUtil.calcUnitB(total,areas,scMathUtil,f.coe):gljUtil.calcUnitB(total,areas,scMathUtil);
  433. },
  434. getIndexBills:function (bills,fixedFlag,_,scMathUtil,decimal) {
  435. let parentMap = {},datas = [],totalCost = 0;
  436. let FBFX_b = null,teh_b = null,costNode=null;
  437. for(let b of bills) {
  438. parentMap[b.ParentID] ? parentMap[b.ParentID].push(b) : parentMap[b.ParentID] = [b];//有添加,无则生成
  439. if(b.flags && b.flags.length > 0){
  440. let f = _.find(b.flags,{"fieldName":"fixed"});
  441. if(!f) continue;
  442. if(f.flag == fixedFlag.SUB_ENGINERRING) FBFX_b = b;//过滤出分部分项工程;
  443. if(f.flag == fixedFlag.CONSTRUCTION_TECH) teh_b = b;//过滤出技术措施项目;
  444. if(f.flag == fixedFlag.ENGINEERINGCOST) costNode = b;//过滤出工程造价项目;
  445. }
  446. }
  447. if(FBFX_b) getChildren(FBFX_b,parentMap,datas);
  448. if(teh_b) getChildren(teh_b,parentMap,datas);
  449. if(costNode) totalCost = gljUtil.getTotalFee(costNode,scMathUtil,decimal);
  450. for(let td of datas){
  451. if(parentMap[td.ID]){
  452. td.economicType = "";
  453. td.quantityIndexType = "";
  454. td.quantityIndexUnit = "";
  455. td.quantityIndexCoe = "";
  456. }
  457. }
  458. return [datas,totalCost];
  459. function getChildren(d,map,arr) {
  460. let tem = {
  461. ID:d.ID,
  462. ParentID:d.ParentID,
  463. code:d.code,
  464. name:d.name,
  465. unit:d.unit,
  466. quantity:d.quantity,
  467. totalFee:gljUtil.getTotalFee(d,scMathUtil,decimal),
  468. economicType:d.economicType,
  469. quantityIndexType:d.quantityIndexType,
  470. quantityIndexUnit:d.quantityIndexUnit,
  471. quantityIndexCoe:d.quantityIndexCoe,
  472. };
  473. arr.push(tem);
  474. if(map[d.ID]){
  475. for(let s of map[d.ID]){
  476. getChildren(s,map,arr)
  477. }
  478. }
  479. }
  480. },
  481. getMainMaterialDatas:function (engineerFeatures,materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil) {
  482. let datas = [];
  483. let materialGroup = _.groupBy(projectGLJData.gljList,'materialIndexType');
  484. if(!materials) return datas;
  485. for(let m of materials){
  486. let tem = {
  487. name:m.name,
  488. unit:m.unit,
  489. unitPrice:0,
  490. quantity:0,
  491. unitIndex:0
  492. };
  493. if(materialGroup[m.name]) setMainMaterial(materialGroup[m.name],tem);
  494. datas.push(tem);
  495. }
  496. function setMainMaterial(gljs,data) {
  497. let quantity = 0 ,unitPrice=0;
  498. for(let g of gljs){
  499. if(!g.quantity || g.quantity=="") continue;
  500. let marketPrice = gljUtil.getMarketPrice(g,projectGLJData,calcOptions,decimalObj,false,_,scMathUtil); // gljOprObj.setGLJPrice(tem,g);
  501. let materialIndexCoe = g.materialIndexCoe?scMathUtil.roundForObj(g.materialIndexCoe,decimalObj.process):0;
  502. let t_quantity = scMathUtil.roundForObj(g.quantity * materialIndexCoe,decimalObj.process);
  503. quantity = scMathUtil.roundForObj(t_quantity + quantity,decimalObj.process);
  504. let temPrice = scMathUtil.roundForObj(g.quantity * marketPrice,decimalObj.process);
  505. unitPrice = scMathUtil.roundForObj(temPrice + unitPrice,decimalObj.process);
  506. }
  507. data.quantity = scMathUtil.roundForObj(quantity,2);
  508. if(data.quantity) data.unitPrice = scMathUtil.roundForObj(unitPrice/data.quantity,2);
  509. data.unitIndex = gljUtil.calUnitWidthCoe(data.quantity,false,engineerFeatures,_,scMathUtil);
  510. }
  511. return datas;
  512. },
  513. getQuantityDatas:function (engineerFeatures,mainQuantities,billsList,fixedFlag,_,scMathUtil,decimal) {//主要工程量指标
  514. let datas = [];
  515. let [bills,totalFee] = gljUtil.getIndexBills(billsList,fixedFlag,_,scMathUtil,decimal);//bills,fixedFlag,_,scMathUtil
  516. let billsGroup = _.groupBy(bills,'quantityIndexType');
  517. if(!mainQuantities) return datas;
  518. for(let m of mainQuantities){
  519. let tem = {
  520. name : m.name,
  521. quantityIndexUnit:m.unit,
  522. quantity:0
  523. };
  524. if(billsGroup[m.name]) setQuantities(billsGroup[m.name],tem);
  525. datas.push(tem);
  526. }
  527. function setQuantities(items,data) {
  528. let quantity = 0;
  529. for (let i of items){
  530. let coe = i.quantityIndexCoe && i.quantityIndexCoe!=""?parseFloat(i.quantityIndexCoe):0;
  531. i.quantity = scMathUtil.roundForObj(parseFloat(i.quantity)*coe,decimal.process);
  532. quantity = scMathUtil.roundForObj(quantity + i.quantity,decimal.process);
  533. }
  534. data.quantity = gljUtil.calUnitWidthCoe(quantity,false,engineerFeatures,_,scMathUtil);
  535. }
  536. return datas;
  537. },
  538. fixedFlag : {
  539. // 分部分项工程
  540. SUB_ENGINERRING: 1,
  541. // 措施项目
  542. MEASURE: 2,
  543. // 施工技术措施项目
  544. CONSTRUCTION_TECH: 3
  545. },
  546. gljType : {
  547. LABOUR: 1, // 人工
  548. // ==============材料类型 ↓=================
  549. GENERAL_MATERIAL: 201, // 普通材料
  550. CONCRETE: 202, // 混凝土
  551. MORTAR: 203, // 砂浆
  552. MIX_RATIO: 204, // 配合比
  553. COMMERCIAL_CONCRETE: 205, // 商品混凝土
  554. COMMERCIAL_MORTAR: 206, // 商品砂浆
  555. OTHER_MATERIAL: 207, // 其它材料
  556. // ==============材料类型 ↑=================
  557. // ==============机械类型 ↓=================
  558. GENERAL_MACHINE: 301, // 机械台班
  559. MACHINE_COMPOSITION: 302, // 机械组成物
  560. MACHINE_LABOUR: 303, // 机上人工
  561. INSTRUMENT: 304, // 仪器仪表
  562. FUEL_POWER_FEE:305, // 燃料动力费
  563. DEPRECIATION_FEE:306, // 折旧费
  564. INSPECTION_FEE:307, // 检修费
  565. MAINTENANCE:308, // 维护费
  566. DISMANTLING_FREIGHT_FEE:309, // 安拆费及场外运费
  567. VERIFICATION_FEE:310, // 校验费
  568. OTHER_FEE:311, // 其他费用
  569. OTHER_MACHINE_USED:312, // 其他施工机具使用费
  570. // ==============机械类型 ↑=================
  571. MAIN_MATERIAL: 4, // 主材
  572. EQUIPMENT: 5, // 设备
  573. MANAGEMENT_FEE: 6, // 企业管理费
  574. PROFIT: 7, // 利润
  575. GENERAL_RISK_FEE: 8 // 一般风险费
  576. },
  577. extraType:[6,7,8],//一些其它的工料机类型
  578. notEditType : [202,203,204,301,304,4],
  579. gljKeyArray : ['code','name','specs','unit','type'],
  580. rationType : {
  581. ration: 1,
  582. volumePrice: 2,
  583. gljRation: 3,
  584. install:4
  585. },
  586. hasCompMaterial:[202, 203, 204],//有组成物的材料
  587. hasCompMachine:[301],//有组成物的机械
  588. machineComposition:[302,303]//可以做为机械组成物的类型
  589. }