glj.ts 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /* eslint-disable no-param-reassign */
  2. import {
  3. ConfigMaterialKey,
  4. GljType,
  5. IBaseGlj,
  6. ICalcOption,
  7. IComponent,
  8. IConfigMaterial,
  9. IDecimal,
  10. IInfoPriceItem,
  11. IProjectGlj,
  12. IProperty,
  13. ITenderSetting,
  14. TaxType,
  15. } from '@sc/types';
  16. import { roundForObj } from '@sc/util';
  17. import { find } from 'lodash';
  18. export const getInfoMarketPrice = (info: IInfoPriceItem, taxType: TaxType) => {
  19. // 1: 一般计税 2: 简易计税
  20. const fieldArray = ['noTaxPrice']; // 一般计税 - 不含税价 || 简易计税 - 含税价
  21. if (taxType === TaxType.GENERAL) {
  22. fieldArray.push('taxPrice');
  23. } else {
  24. fieldArray.unshift('taxPrice');
  25. }
  26. // 一个放后面,一个放前面
  27. let infoPrice = (info as any)[fieldArray[0]];
  28. if (infoPrice === null || infoPrice === undefined) infoPrice = (info as any)[fieldArray[1]]; // 信息价只有一个价格(含税价/不含税价),则不分计税方式,套用仅有的价格。
  29. return parseFloat(infoPrice);
  30. };
  31. // 计算采保费率后的市场价
  32. export const calcMarketPriceByInfoPrice = (infoPrice: number, purchaseFeeRate: number, decimal: number) => {
  33. if (!purchaseFeeRate) return infoPrice;
  34. return roundForObj(infoPrice * (1 + purchaseFeeRate / 100), decimal);
  35. };
  36. // roundForObj()
  37. // 返回五大项组成的索引
  38. export const getIndex = (obj: IBaseGlj, pops = ['code', 'name', 'specs', 'unit', 'type']): string => {
  39. let index = '';
  40. const arr = [];
  41. for (const p of pops) {
  42. const tmpK = obj[p] === undefined || obj[p] === null || obj[p] === '' ? 'null' : obj[p];
  43. arr.push(tmpK);
  44. }
  45. index = arr.join('|-|');
  46. return index;
  47. };
  48. // 是否是人工
  49. export const isLabour = (type: GljType) => {
  50. return type === GljType.LABOUR;
  51. };
  52. // 是否是材料
  53. export const isMaterial = (type: GljType) => {
  54. const rootType = +String(type).charAt(0);
  55. return rootType === 2;
  56. };
  57. // 是否是机械
  58. export const isMachine = (type: GljType) => {
  59. const rootType = +String(type).charAt(0);
  60. return rootType === 3;
  61. };
  62. /**
  63. * 判断工料机类型是否有组成物
  64. *
  65. * @param projectGlj 可以不传这个,默认会按glj去取
  66. *
  67. */
  68. export const hasComponent = (projectGlj?: IProjectGlj) => {
  69. // 有组成物的类型
  70. const typeMap: { [key: number]: boolean } = {
  71. 202: true,
  72. 203: true,
  73. 204: true,
  74. 301: true,
  75. 304: true,
  76. 4: true,
  77. };
  78. if (projectGlj) {
  79. return typeMap[projectGlj.type] === true && projectGlj.components && projectGlj.components.length > 0;
  80. }
  81. return false;
  82. };
  83. const getProjectGlj = (glj: IBaseGlj, projectGljMap: Record<string, IBaseGlj>, index?: string) => {
  84. index = index || getIndex(glj);
  85. const projectGlj = projectGljMap[index] as IProjectGlj;
  86. if (projectGlj) return projectGlj;
  87. return undefined;
  88. };
  89. /**
  90. *
  91. * @param fieldID 如"glj.unitPrice"
  92. *
  93. */
  94. export const getDecimal = (fieldID: string, decimal?: any) => {
  95. if (decimal) {
  96. if (fieldID.indexOf('.') !== -1) {
  97. const keyArray = fieldID.split('.');
  98. return decimal[keyArray[0]][keyArray[1]];
  99. }
  100. return decimal[fieldID];
  101. }
  102. return 0;
  103. };
  104. export const getMarketPrice = (
  105. projectGlj: IProjectGlj,
  106. tenderCoe = 1,
  107. projectGljMap: Record<string, IBaseGlj>,
  108. decimalObj: IDecimal
  109. ) => {
  110. if (hasComponent(projectGlj)) {
  111. let parentPrice = 0;
  112. for (const c of projectGlj.components as IComponent[]) {
  113. const cProjectGlj = getProjectGlj(c, projectGljMap);
  114. if (cProjectGlj) {
  115. let cMarketPrice = getMarketPrice(cProjectGlj, 1, projectGljMap, decimalObj);
  116. if (tenderCoe !== 1) cMarketPrice = roundForObj(cMarketPrice * tenderCoe, decimalObj.glj.unitPrice);
  117. const quantity = roundForObj(c.consumption, decimalObj.glj.quantity);
  118. const sumPrice = roundForObj(cMarketPrice * quantity, decimalObj.process);
  119. parentPrice = roundForObj(parentPrice + sumPrice, decimalObj.process);
  120. }
  121. }
  122. return roundForObj(parentPrice, decimalObj.glj.unitPriceHasMix);
  123. }
  124. const marketPrice = roundForObj(projectGlj.marketPrice, decimalObj.glj.unitPrice);
  125. // 调价的时候还要乘以调价系数
  126. if (tenderCoe !== 1) return roundForObj(marketPrice * tenderCoe, decimalObj.glj.unitPrice);
  127. return marketPrice;
  128. };
  129. // 取工料机基价(定额价)
  130. export const getBasePrice = (projectGlj: IProjectGlj, decimalObj: IDecimal) => {
  131. let decimalKey = 'glj.unitPrice';
  132. if (hasComponent(projectGlj)) decimalKey = 'glj.unitPriceHasMix';
  133. const decimal = getDecimal(decimalKey, decimalObj);
  134. return roundForObj(projectGlj.basePrice, decimal);
  135. };
  136. export const getTenderPriceCoe = (projectGlj: IProjectGlj, tenderSetting?: ITenderSetting) => {
  137. let coe = 1;
  138. if (projectGlj.noAdjustPrice === false && tenderSetting) {
  139. coe = tenderSetting.gljPriceTenderCoe ? tenderSetting.gljPriceTenderCoe : 1;
  140. }
  141. return coe;
  142. };
  143. // 判断是否暂估
  144. export const isEvaluate = (projectGljID: string, configMaterials: IConfigMaterial) => {
  145. const materials = configMaterials[ConfigMaterialKey.EVALUATE];
  146. return !!find(materials, { isRelated: true, projectGljID });
  147. };
  148. // 判断是否计算价差
  149. export const calcPriceDiff = (projectGlj: IProjectGlj, configMaterials: IConfigMaterial, calcOption?: ICalcOption) => {
  150. if (calcOption) {
  151. const { calcEst, calcMain, calcAdd } = calcOption;
  152. if (isEvaluate(projectGlj.ID, configMaterials)) return calcEst; // 先按是否暂估判断
  153. // 再判断是否是主材和设备
  154. if (projectGlj.type === GljType.MAIN_MATERIAL || projectGlj.type === GljType.EQUIPMENT) return calcMain;
  155. // 再判断是否新增
  156. if (projectGlj.isAdd) return calcAdd;
  157. }
  158. return true;
  159. };
  160. // 取工料机的价格在确定subject数据已经获取全的情况下使用
  161. export const getPrice = (
  162. glj: IBaseGlj,
  163. projectGljMap: Record<string, IBaseGlj>,
  164. unitProperty: { tenderSetting?: ITenderSetting },
  165. constructionProperty: { decimal: IDecimal; calcOption?: ICalcOption },
  166. configMaterial: IConfigMaterial,
  167. tender?: boolean
  168. ) => {
  169. let marketPrice = 0;
  170. let basePrice = 0;
  171. let tenderPrice = 0; // 调后价
  172. let adjustPrice = 0; // 调整价
  173. const projectGlj = getProjectGlj(glj, projectGljMap);
  174. if (projectGlj) {
  175. marketPrice = getMarketPrice(projectGlj, 1, projectGljMap, constructionProperty.decimal);
  176. tenderPrice = marketPrice;
  177. if (tender === true) {
  178. const tenderCoe = getTenderPriceCoe(projectGlj, unitProperty.tenderSetting);
  179. tenderPrice = getMarketPrice(projectGlj, tenderCoe, projectGljMap, constructionProperty.decimal);
  180. }
  181. if (calcPriceDiff(projectGlj, configMaterial, constructionProperty.calcOption)) {
  182. // 计取价差
  183. basePrice = getBasePrice(projectGlj, constructionProperty.decimal);
  184. } else {
  185. // 不计价差时 基价也为市场价
  186. basePrice = marketPrice;
  187. }
  188. adjustPrice = basePrice;
  189. }
  190. return { marketPrice, basePrice, tenderPrice, adjustPrice, projectGlj };
  191. };