Browse Source

获取bom报价接口

fgd 1 năm trước cách đây
mục cha
commit
56ab99fbdb

+ 18 - 4
sd-business/src/main/java/com/sd/business/controller/bom/BomSpecController.java

@@ -2,10 +2,7 @@ package com.sd.business.controller.bom;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.domain.BaseSelectDto;
-import com.sd.business.entity.bom.dto.BomSpecDto;
-import com.sd.business.entity.bom.dto.BomSpecSelectDto;
-import com.sd.business.entity.bom.dto.BomSpecUpdateBoardDto;
-import com.sd.business.entity.bom.dto.BomSpecUpdateBoardSortDto;
+import com.sd.business.entity.bom.dto.*;
 import com.sd.business.entity.bom.vo.BomSpecBoardSelectVo;
 import com.sd.business.entity.bom.vo.BomSpecVo;
 import com.sd.business.service.bom.BomSpecService;
@@ -16,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 
@@ -110,4 +108,20 @@ public class BomSpecController {
         bomSpecService.editPrice(bomSpecDto);
     }
 
+    /**
+     * bom规格获取价格
+     */
+    @PostMapping("/getPriceByParam")
+    public BigDecimal getPriceByParam(@Validated @RequestBody BomSpecPriceComputeDto dto) {
+        return bomSpecService.getPriceByParam(dto);
+    }
+
+    /**
+     * bom规格获取价格
+     */
+    @PostMapping("/getPriceById")
+    public BigDecimal getPriceById(@RequestBody BaseSelectDto dto) {
+        return bomSpecService.getPriceById(dto.getId());
+    }
+
 }

+ 67 - 0
sd-business/src/main/java/com/sd/business/entity/bom/dto/BomSpecPriceComputeDto.java

@@ -0,0 +1,67 @@
+package com.sd.business.entity.bom.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+/**
+ * bom规格价格计算入参实体
+ *
+ * @author
+ * @since 2024-01-08
+ */
+@Getter
+@Setter
+public class BomSpecPriceComputeDto {
+
+    /**
+     * bom分类id
+     */
+    @NotNull(message = "类目id不能为空")
+    private Long bomClassifyId;
+
+    /**
+     * 色层 字典:bom_chromatophore
+     */
+    @NotNull(message = "色层不能为空")
+    private String chromatophore;
+
+    /**
+     * 售价体系 字典:bom_sellingPriceSystem
+     */
+    @NotNull(message = "售价体系不能为空")
+    private String sellingPriceSystem;
+
+    /**
+     * 压纹工艺 字典:bom_embossingProcess
+     */
+    @NotNull(message = "压纹工艺不能为空")
+    private String embossingProcess;
+
+    /**
+     * 颜色
+     */
+    @NotNull(message = "颜色不能为空")
+    private String colour;
+
+    /**
+     * 长 cm
+     */
+    @NotNull(message = "长不能为空")
+    private BigDecimal length;
+
+    /**
+     * 宽 cm
+     */
+    @NotNull(message = "宽不能为空")
+    private BigDecimal width;
+
+    /**
+     * 高 cm
+     */
+    @NotNull(message = "高不能为空")
+    private BigDecimal height;
+
+}

+ 17 - 4
sd-business/src/main/java/com/sd/business/service/bom/BomSpecService.java

@@ -2,14 +2,12 @@ package com.sd.business.service.bom;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.service.BaseService;
-import com.sd.business.entity.bom.dto.BomSpecDto;
-import com.sd.business.entity.bom.dto.BomSpecSelectDto;
-import com.sd.business.entity.bom.dto.BomSpecUpdateBoardDto;
-import com.sd.business.entity.bom.dto.BomSpecUpdateBoardSortDto;
+import com.sd.business.entity.bom.dto.*;
 import com.sd.business.entity.bom.po.BomSpec;
 import com.sd.business.entity.bom.vo.BomSpecBoardSelectVo;
 import com.sd.business.entity.bom.vo.BomSpecVo;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 
@@ -72,4 +70,19 @@ public interface BomSpecService extends BaseService<BomSpec> {
      * @param bomSpecDto
      */
     void editPrice(BomSpecDto bomSpecDto);
+
+    /**
+     * bom规格获取价格
+     *
+     * @param dto
+     * @return
+     */
+    BigDecimal getPriceByParam(BomSpecPriceComputeDto dto);
+
+    /**
+     * bom规格获取价格
+     * @param id
+     * @return
+     */
+    BigDecimal getPriceById(Long id);
 }

+ 1 - 1
sd-business/src/main/java/com/sd/business/service/bom/impl/BomSpecPriceConfigServiceImpl.java

@@ -167,7 +167,7 @@ public class BomSpecPriceConfigServiceImpl extends ServiceImpl<BomSpecPriceConfi
                 .map(BomSpecPriceConfig::getPrice)
                 .reduce(BigDecimal.ZERO, BigDecimal::add);
         // 如果是热复合时,增加复合费用
-        if (Objects.equals(categoryDetail.getName(), "热复合")) {
+        if (Objects.equals(categoryDetail.getName(), "双层热复合")) {
             List<BomSpecPriceConfig> compoundingCostConfigList = configCodeMap.getOrDefault(BomSpecPriceConfigCodeEnum.COMPOUNDING_COST_CONFIG.getKey(), Collections.emptyList());
             BomSpecPriceConfig priceConfig = compoundingCostConfigList.stream()
                     .filter(item -> this.operatorCompareTo(item.getName(), dto.getWidth()))

+ 233 - 4
sd-business/src/main/java/com/sd/business/service/bom/impl/BomSpecServiceImpl.java

@@ -2,29 +2,37 @@ package com.sd.business.service.bom.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.ReUtil;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.tenant.entity.dict.po.DictCommonData;
+import com.fjhx.tenant.service.dict.DictCommonDataService;
 import com.ruoyi.common.constant.StatusConstant;
 import com.ruoyi.common.core.domain.BaseIdPo;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.wrapper.IWrapper;
-import com.sd.business.entity.bom.dto.BomSpecDto;
-import com.sd.business.entity.bom.dto.BomSpecSelectDto;
-import com.sd.business.entity.bom.dto.BomSpecUpdateBoardDto;
-import com.sd.business.entity.bom.dto.BomSpecUpdateBoardSortDto;
+import com.sd.business.entity.bom.constant.BomClassifyConstant;
+import com.sd.business.entity.bom.dto.*;
+import com.sd.business.entity.bom.enums.BomSpecPriceConfigCodeEnum;
+import com.sd.business.entity.bom.po.Bom;
 import com.sd.business.entity.bom.po.BomSpec;
+import com.sd.business.entity.bom.po.BomSpecPriceConfig;
 import com.sd.business.entity.bom.vo.BomSpecBoardSelectVo;
 import com.sd.business.entity.bom.vo.BomSpecVo;
 import com.sd.business.entity.department.constant.DepartmentConstant;
 import com.sd.business.entity.inventory.po.Inventory;
 import com.sd.business.entity.warehouse.constant.WarehouseConstant;
 import com.sd.business.mapper.bom.BomSpecMapper;
+import com.sd.business.service.bom.BomService;
+import com.sd.business.service.bom.BomSpecPriceConfigService;
 import com.sd.business.service.bom.BomSpecService;
 import com.sd.business.service.inventory.InventoryService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -42,6 +50,15 @@ public class BomSpecServiceImpl extends ServiceImpl<BomSpecMapper, BomSpec> impl
     @Autowired
     private InventoryService inventoryService;
 
+    @Autowired
+    private BomService bomService;
+
+    @Autowired
+    private DictCommonDataService dictCommonDataService;
+
+    @Autowired
+    private BomSpecPriceConfigService bomSpecPriceConfigService;
+
     @Override
     public Page<BomSpecVo> getPage(BomSpecSelectDto dto) {
         IWrapper<BomSpec> wrapper = getWrapper();
@@ -140,4 +157,216 @@ public class BomSpecServiceImpl extends ServiceImpl<BomSpecMapper, BomSpec> impl
         bomSpec.setExternalSellingPrice(bomSpecDto.getExternalSellingPrice());
         this.updateById(bomSpec);
     }
+
+    @Override
+    public BigDecimal getPriceByParam(BomSpecPriceComputeDto dto) {
+        Long bomClassifyId = dto.getBomClassifyId();
+        if (!Objects.equals(bomClassifyId, BomClassifyConstant.YOGA_MAT) &&
+                !Objects.equals(bomClassifyId, BomClassifyConstant.SKIP_MAT)) {
+            return BigDecimal.ZERO;
+        }
+        // 是否是瑜伽垫
+        boolean yogaMatFlag = Objects.equals(bomClassifyId, BomClassifyConstant.YOGA_MAT);
+        // 厚度单位为cm,需要mm
+        dto.setHeight(dto.getHeight().multiply(BigDecimal.TEN));
+        // 获取bom字典值
+        List<DictCommonData> dictCommonDataList = dictCommonDataService.list();
+        Map<String, Map<String, String>> dictMap = dictCommonDataList.stream()
+                .collect(Collectors.groupingBy(
+                        DictCommonData::getDictCode,
+                        Collectors.toMap(
+                                DictCommonData::getDictKey,
+                                DictCommonData::getDictValue)
+                ));
+        String sellingPriceSystem = dictMap.getOrDefault("bom_sellingPriceSystem", Collections.emptyMap()).get(dto.getSellingPriceSystem());
+        String chromatophore = dictMap.getOrDefault("bom_chromatophore", Collections.emptyMap()).get(dto.getChromatophore());
+        String embossingProcess = dictMap.getOrDefault("bom_embossingProcess", Collections.emptyMap()).get(dto.getEmbossingProcess());
+        if (StrUtil.isBlank(sellingPriceSystem) || StrUtil.isBlank(chromatophore) || StrUtil.isBlank(embossingProcess)) {
+            return BigDecimal.ZERO;
+        }
+
+        // 计算公式=(基材价格+品类+特性+颜色价格)*[(长+裁切配置)*(宽+裁切配置)/10000]*(厚度+压纹配置)*(1+损耗)+加工费+运费
+        List<BomSpecPriceConfig> list = bomSpecPriceConfigService.list();
+        Map<String, List<BomSpecPriceConfig>> configCodeMap = list.stream().collect(Collectors.groupingBy(BomSpecPriceConfig::getCode));
+
+        // 计算bom每平方价格
+        BigDecimal price = BigDecimal.ZERO;
+        // 等级
+        List<BomSpecPriceConfig> bomSpecMaterialConfigList = configCodeMap
+                .getOrDefault(BomSpecPriceConfigCodeEnum.BASE_MATERIAL_PRICE.getKey(), Collections.emptyList());
+        BomSpecPriceConfig levelDetail = bomSpecMaterialConfigList.stream()
+                .filter(item -> item.getName().contains(sellingPriceSystem))
+                .findAny().orElse(null);
+        if (levelDetail == null) {
+            return BigDecimal.ZERO;
+        }
+        price = price.add(levelDetail.getPrice());
+
+        // 品类
+        List<BomSpecPriceConfig> bomSpecCategoryConfigList = configCodeMap
+                .getOrDefault(BomSpecPriceConfigCodeEnum.CATEGORY_PRICE.getKey(), Collections.emptyList());
+        BomSpecPriceConfig categoryDetail = bomSpecCategoryConfigList.stream()
+                .filter(item -> item.getName().contains(chromatophore))
+                .findAny().orElse(null);
+        if (categoryDetail == null) {
+            return BigDecimal.ZERO;
+        }
+        price = price.add(categoryDetail.getPrice());
+
+        // 颜色
+        List<String> colourList = Arrays.asList(dto.getColour().split("\\+"));
+        List<BomSpecPriceConfig> bomSpecColourConfigList = configCodeMap
+                .getOrDefault(BomSpecPriceConfigCodeEnum.COLOUR_PRICE.getKey(), Collections.emptyList());
+
+        for (String colour : colourList) {
+            BigDecimal colourPrice = bomSpecColourConfigList.stream()
+                    .filter(item -> item.getName().contains(colour))
+                    .findAny()
+                    .map(BomSpecPriceConfig::getPrice)
+                    .orElse(BigDecimal.ZERO);
+            if (colourList.size() > 1) {
+                colourPrice = colourPrice.divide(BigDecimal.valueOf(2), 4, RoundingMode.HALF_UP);
+            }
+            price = price.add(colourPrice);
+        }
+
+        // 获取裁切配置
+        List<BomSpecPriceConfig> bomSpecCropConfigList = configCodeMap
+                .getOrDefault(BomSpecPriceConfigCodeEnum.CROP_CONFIG.getKey(), Collections.emptyList());
+        BomSpecPriceConfig cropConfig = bomSpecCropConfigList.stream()
+                .filter(item -> item.getName().contains(categoryDetail.getName()))
+                .findAny().orElse(null);
+        if (cropConfig != null) {
+            dto.setLength(dto.getLength().add(cropConfig.getLength()));
+            dto.setWidth(dto.getWidth().add(cropConfig.getWidth()));
+        }
+
+        // 获取压纹配置
+        List<BomSpecPriceConfig> bomSpecEmbossingConfigList = configCodeMap.
+                getOrDefault(BomSpecPriceConfigCodeEnum.EMBOSSING_CONFIG.getKey(), Collections.emptyList());
+        BomSpecPriceConfig embossingConfig = bomSpecEmbossingConfigList.stream()
+                .filter(item -> item.getName().contains(embossingProcess))
+                .findAny().orElse(null);
+        if (embossingConfig != null) {
+            dto.setHeight(dto.getHeight().add(embossingConfig.getHeight()));
+        }
+
+        // 获取损耗配置
+        BigDecimal depletion = BigDecimal.ZERO;
+        String depletionCode;
+        if (yogaMatFlag) {
+            depletionCode = BomSpecPriceConfigCodeEnum.YOGA_MAT_DEPLETION_CONFIG.getKey();
+        } else {
+            depletionCode = BomSpecPriceConfigCodeEnum.SKIP_MAT_DEPLETION_CONFIG.getKey();
+        }
+        List<BomSpecPriceConfig> bomSpecDepletionConfigList = configCodeMap.getOrDefault(depletionCode, Collections.emptyList());
+        BomSpecPriceConfig depletionConfig = bomSpecDepletionConfigList.stream()
+                .filter(item -> item.getName().contains(categoryDetail.getName()))
+                .findAny().orElse(null);
+        if (depletionConfig != null) {
+            depletion = depletionConfig.getDepletion();
+        }
+        // 获取附加配置
+        List<BomSpecPriceConfig> additionalConfigList = bomSpecDepletionConfigList.stream()
+                .filter(item -> Objects.equals(item.getType(), StatusConstant.YES)).collect(Collectors.toList());
+
+        // 瑜伽垫对比宽度,跳绳垫对比级别
+        BomSpecPriceConfig additionalConfig;
+        if (yogaMatFlag) {
+            additionalConfig = additionalConfigList.stream()
+                    .filter(item -> this.operatorCompareTo(item.getName(), dto.getWidth()))
+                    .findAny().orElse(null);
+        } else {
+            additionalConfig = additionalConfigList.stream()
+                    .filter(item -> item.getName().contains(levelDetail.getName()))
+                    .findAny().orElse(null);
+        }
+
+        // 附加配置匹配成功,增加损耗
+        if (additionalConfig != null) {
+            depletion = depletion.add(additionalConfig.getDepletion());
+        }
+
+        // 获取加工费配置
+        List<BomSpecPriceConfig> bomSpecProcessingFeeConfigList = configCodeMap
+                .getOrDefault(BomSpecPriceConfigCodeEnum.PROCESSING_FEE_CONFIG.getKey(), Collections.emptyList());
+        BigDecimal processingFee = bomSpecProcessingFeeConfigList.stream()
+                .map(BomSpecPriceConfig::getPrice)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        // 如果是热复合时,增加复合费用
+        if (Objects.equals(categoryDetail.getName(), "双层热复合")) {
+            List<BomSpecPriceConfig> compoundingCostConfigList = configCodeMap
+                    .getOrDefault(BomSpecPriceConfigCodeEnum.COMPOUNDING_COST_CONFIG.getKey(), Collections.emptyList());
+            BomSpecPriceConfig priceConfig = compoundingCostConfigList.stream()
+                    .filter(item -> this.operatorCompareTo(item.getName(), dto.getWidth()))
+                    .findAny().orElse(null);
+            if (priceConfig != null) {
+                processingFee = processingFee.add(priceConfig.getPrice());
+            }
+        }
+
+        // 获取运费配置
+        List<BomSpecPriceConfig> bomSpecFreightConfigList = configCodeMap
+                .getOrDefault(BomSpecPriceConfigCodeEnum.FREIGHT_CONFIG.getKey(), Collections.emptyList());
+        BigDecimal freightFee = BigDecimal.ZERO;
+        BomSpecPriceConfig freightConfig = bomSpecFreightConfigList.stream()
+                .filter(item -> this.operatorCompareTo(item.getName(), dto.getWidth())).findAny().orElse(null);
+        if (freightConfig != null) {
+            freightFee = freightConfig.getPrice();
+        }
+
+        return price.multiply(dto.getLength().multiply(dto.getWidth()).divide(BigDecimal.valueOf(10000), 10, RoundingMode.HALF_UP))
+                .multiply(dto.getHeight())
+                .multiply(BigDecimal.ONE.add(depletion.multiply(BigDecimal.valueOf(0.01))))
+                .add(processingFee)
+                .add(freightFee)
+                .setScale(2, RoundingMode.HALF_UP);
+    }
+
+    @Override
+    public BigDecimal getPriceById(Long id) {
+        BomSpec bomSpec = this.getById(id);
+        if (bomSpec == null) {
+            throw new ServiceException("未知bom规格id!");
+        }
+        Bom bom = bomService.getById(bomSpec.getBomId());
+        // 添加计算条件
+        BomSpecPriceComputeDto dto = new BomSpecPriceComputeDto();
+        dto.setBomClassifyId(bom.getBomClassifyId());
+        dto.setChromatophore(bom.getChromatophore());
+        dto.setSellingPriceSystem(bom.getSellingPriceSystem());
+        dto.setEmbossingProcess(bom.getEmbossingProcess());
+        dto.setColour(bomSpec.getColour());
+        dto.setLength(bomSpec.getLength());
+        dto.setWidth(bomSpec.getWidth());
+        dto.setHeight(bomSpec.getHeight());
+
+        BigDecimal price = this.getPriceByParam(dto);
+        // 计算不出价格时,取当前成本价
+        if (Objects.equals(price, BigDecimal.ZERO)) {
+            price = bomSpec.getCostPrice();
+        }
+        return price;
+    }
+
+    /**
+     * 对比
+     * @param rule 规则
+     * @param value
+     * @return
+     */
+    private boolean operatorCompareTo(String rule, BigDecimal value) {
+        Integer number = ReUtil.getFirstNumber(rule);
+        if (rule.startsWith(">=") || rule.startsWith("≥")) {
+            return value.compareTo(BigDecimal.valueOf(number)) >= 0;
+        } else if (rule.startsWith(">")) {
+            return value.compareTo(BigDecimal.valueOf(number)) > 0;
+        } else if (rule.startsWith("<=") || rule.startsWith("≤")) {
+            return value.compareTo(BigDecimal.valueOf(number)) <= 0;
+        } else if (rule.startsWith("<")) {
+            return value.compareTo(BigDecimal.valueOf(number)) < 0;
+        } else {
+            return value.compareTo(BigDecimal.valueOf(number)) == 0;
+        }
+    }
 }