package com.xisc.pm.app.service.impl;

import com.xisc.pm.api.dto.PmCompositeSlabActDTO;
import com.xisc.pm.api.dto.PmCompositeSlabActLineDTO;
import com.xisc.pm.api.dto.PmCompositeSlabActReqParamDTO;
import com.xisc.pm.app.service.PmCompositeSlabListService;
import com.xisc.pm.domain.entity.PmCompositeSlab;
import com.xisc.pm.domain.entity.PmCompositeSlabList;
import com.xisc.pm.domain.repository.PmCompositeSlabListRepository;
import com.xisc.pm.domain.repository.PmCompositeSlabRepository;
import com.xisc.pm.domain.vo.MatStatusModifyVO;
import com.xisc.pm.domain.vo.MmPlateVO;
import com.xisc.pm.domain.vo.WmInStockVO;
import com.xisc.pm.domain.vo.WmMatSigleVO;
import com.xisc.pm.domain.vo.WmSigleQtyVO;
import com.xisc.pm.infra.client.MmEventClient;
import com.xisc.pm.infra.client.WmApiClient;
import com.xisc.pm.infra.constant.Constants;
import com.xisc.pm.infra.mapper.PmCompositeSlabMapper;
import com.xisc.pm.infra.mapper.PmMmPlateMapper;
import io.choerodon.core.domain.Page;
import io.choerodon.core.domain.PageInfo;
import io.choerodon.core.exception.CommonException;
import io.choerodon.core.oauth.DetailsHelper;
import io.choerodon.mybatis.pagehelper.PageHelper;
import io.choerodon.mybatis.pagehelper.domain.PageRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.hzero.boot.platform.code.builder.CodeRuleBuilder;
import org.hzero.boot.platform.code.constant.CodeConstants;
import org.hzero.boot.platform.lov.adapter.LovAdapter;
import org.hzero.boot.platform.lov.dto.LovValueDTO;
import org.hzero.mybatis.domian.Condition;
import org.hzero.mybatis.util.Sqls;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 复合/叠轧坯明细信息表(PmCompositeSlabList)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-08-01 15:40:18
 */
@Slf4j
@Service
public class PmCompositeSlabListServiceImpl implements PmCompositeSlabListService {

    @Autowired
    private PmCompositeSlabListRepository pmCompositeSlabListRepository;
    @Autowired
    private PmCompositeSlabRepository pmCompositeSlabRepository;
    @Autowired
    private PmCompositeSlabMapper pmCompositeSlabMapper;
    @Autowired
    private LovAdapter lovAdapter;
    @Autowired
    private WmApiClient wmApiClient;
    @Autowired
    private MmEventClient mmEventClient;
    @Autowired
    private CodeRuleBuilder codeRuleBuilder;
    @Autowired
    private PmMmPlateMapper pmMmPlateMapper;

    private static final String METHOD_STATUS_INSERT = "insert";


    @Override
    public Page<PmCompositeSlabActDTO> selectList(PageRequest pageRequest, PmCompositeSlabActReqParamDTO dto, Long tenantId) {
        // 根据条件查询复合/叠轧坯基本信息表获取数据,查询加工厂代码等于当前操作用户所属部门代码
         // 获取用户所属部门的代码
       List<String> unitCodeList =  pmCompositeSlabMapper.getCurrentUserUintCode(tenantId, DetailsHelper.getUserDetails().getUserId());
       if (CollectionUtils.isEmpty(unitCodeList)) {
           return new Page<>();
       }

        Condition.Builder build = Condition.builder(PmCompositeSlab.class)
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_STATUS_CODE, dto.getStatusCode(), true))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_SLAB_TYPE, dto.getSlabType(), true))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_DEST_STOCK_CODE, dto.getStockCode(), true))
                .andWhere(Sqls.custom().andLike(PmCompositeSlab.FIELD_SLAB_NO, dto.getSlabNo(), true))
                .andWhere(Sqls.custom().andGreaterThanOrEqualTo(PmCompositeSlab.FIELD_CREATION_DATE, dto.getCreateDateFrom(), true))
                .andWhere(Sqls.custom().andLessThanOrEqualTo(PmCompositeSlab.FIELD_CREATION_DATE, dto.getCreateDateTo(), true))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_CREATED_BY, dto.getCreatedById(), true))
                .andWhere(Sqls.custom().andIn(PmCompositeSlab.FIELD_FACTORY_CODE, unitCodeList));

        if (StringUtils.isNotEmpty(dto.getBaseMatNo())) {
            List<PmCompositeSlabList> pmCompositeSlabLists = pmCompositeSlabListRepository.
                    selectByBaseMatNoList(Arrays.asList(dto.getBaseMatNo()), tenantId);
            List<Long> idList = pmCompositeSlabLists.stream().map(PmCompositeSlabList::getSlabId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(idList)) {
                return new Page<>();
            }
            build.andWhere(Sqls.custom().andIn(PmCompositeSlabList.FIELD_SLAB_ID, idList));
        }
        Condition condition = build.build();

        // 分页查询
        Page<PmCompositeSlab> page = PageHelper.doPageAndSort(pageRequest, () -> pmCompositeSlabRepository.selectByCondition(condition));
        // 判断是否为空
        if (CollectionUtils.isEmpty(page.getContent())) {
            return new Page<>();
        }
        // 获取主键id集合
        List<Long> slabIdList = page.getContent().stream().map(PmCompositeSlab::getSlabId).collect(Collectors.toList());
        // 查询明细表数据
        List<PmCompositeSlabList> pmCompositeSlabLists = pmCompositeSlabListRepository.selectByCondition(Condition.builder(PmCompositeSlabList.class)
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlabList.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmCompositeSlabList.FIELD_SLAB_ID, slabIdList))
                .build());
        // 根据slabId分组
        Map<Long, List<PmCompositeSlabList>> pmCompositeSlabListMap = new HashMap<>(pmCompositeSlabLists.size());
        if (CollectionUtils.isNotEmpty(pmCompositeSlabLists)) {
            pmCompositeSlabListMap = pmCompositeSlabLists.stream().collect(Collectors.groupingBy(PmCompositeSlabList::getSlabId));
        }

        // 遍历组装数据
        List<PmCompositeSlabActDTO> resultList = new ArrayList<>();
        for (PmCompositeSlab pmCompositeSlab : page.getContent()) {
            PmCompositeSlabActDTO actualDTO = new PmCompositeSlabActDTO();
            actualDTO.setSlabId(pmCompositeSlab.getSlabId());
            actualDTO.setSlabNo(pmCompositeSlab.getSlabNo());
            actualDTO.setStatusCode(pmCompositeSlab.getStatusCode());
            actualDTO.setStockCode(pmCompositeSlab.getDestStockCode());
            actualDTO.setSlabType(pmCompositeSlab.getSlabType());
            actualDTO.setHeatNo(pmCompositeSlab.getHeatNo());
            actualDTO.setPono(pmCompositeSlab.getPono());
            actualDTO.setActThick(pmCompositeSlab.getActThick());
            actualDTO.setActWidth(pmCompositeSlab.getActWidth());
            actualDTO.setActLength(pmCompositeSlab.getActLength());
            actualDTO.setActWt(pmCompositeSlab.getActWt());
            actualDTO.setRollType(pmCompositeSlab.getRollType());
            actualDTO.setRollAimThick(pmCompositeSlab.getRollAimThick());
            actualDTO.setRollAimWidth(pmCompositeSlab.getRollAimWidth());
            actualDTO.setSampleLotNo(pmCompositeSlab.getSampleLotNo());
            actualDTO.setMscLineNo(pmCompositeSlab.getMscLineNo());
            actualDTO.setFactoryCode(pmCompositeSlab.getFactoryCode());
            // 组装行信息，行转列
            if (!pmCompositeSlabListMap.isEmpty() && pmCompositeSlabListMap.containsKey(pmCompositeSlab.getSlabId())) {
                List<PmCompositeSlabActLineDTO> actDTOList = new ArrayList<>();
                List<PmCompositeSlabList> compositeSlabList = pmCompositeSlabListMap.get(pmCompositeSlab.getSlabId());
                for (PmCompositeSlabList slabList : compositeSlabList) {
                    PmCompositeSlabActLineDTO actDTO = new PmCompositeSlabActLineDTO();
                    actDTO.setLayerNo(slabList.getLayerNo());
                    actDTO.setBaseOrderNo(slabList.getBaseOrderNo());
                    actDTO.setBaseMatNo(slabList.getBaseMatNo());
                    actDTO.setMatActThk(slabList.getBaseMatThick());
                    actDTO.setMatActWid(slabList.getBaseMatWidth());
                    actDTO.setMatActLen(slabList.getBaseMatLength());
                    actDTO.setMatActWgt(slabList.getBaseMatWt());
                    actDTO.setSsNo(slabList.getCompMatNo());
                    actDTO.setSsPono(slabList.getCompMatPono());
                    actDTOList.add(actDTO);
                }
                actualDTO.setActDTOList(actDTOList);
            }
            resultList.add(actualDTO);
        }

        // 分页返回
        return new Page<>(resultList, new PageInfo(pageRequest.getPage(), pageRequest.getSize()), page.getTotalElements());
    }

    @Override
    public List<PmCompositeSlabActLineDTO> queryLineList(Long id, Long tenantId) {
        // 根据的表ID列表查询行数据
        List<PmCompositeSlab> pmCompositeSlabs = pmCompositeSlabRepository.selectByCondition(Condition.builder(PmCompositeSlab.class)
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_SLAB_ID, id))
                .build());
        if (CollectionUtils.isEmpty(pmCompositeSlabs)) {
            return Collections.emptyList();
        }
        // 获取第一条
        PmCompositeSlab pmCompositeSlab = pmCompositeSlabs.get(0);

        // 查询明细表数据
        List<PmCompositeSlabList> pmCompositeSlabLists = pmCompositeSlabListRepository.selectByCondition(Condition.builder(PmCompositeSlabList.class)
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlabList.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlabList.FIELD_SLAB_ID, pmCompositeSlab.getSlabId())).build());
        // 为空则返回
        if (CollectionUtils.isEmpty(pmCompositeSlabLists)) {
            return Collections.emptyList();
        }


        List<PmCompositeSlabActLineDTO> resultList = new ArrayList<>();
        for (PmCompositeSlabList line : pmCompositeSlabLists) {
            PmCompositeSlabActLineDTO lineDTO = new PmCompositeSlabActLineDTO();
            lineDTO.setId(line.getListId());
            lineDTO.setLayerNo(line.getLayerNo());
            lineDTO.setBaseOrderNo(line.getBaseOrderNo());
            lineDTO.setBaseMatId(line.getBaseMatId());
            lineDTO.setBaseMatNo(line.getBaseMatNo());
            lineDTO.setMatActThk(line.getBaseMatThick());
            lineDTO.setMatActWid(line.getBaseMatWidth());
            lineDTO.setMatActLen(line.getBaseMatLength());
            lineDTO.setMatActWgt(line.getBaseMatWt());
            lineDTO.setSsType(line.getCompMatType());
            lineDTO.setSsId(line.getCompMatId());
            lineDTO.setSsNo(line.getCompMatNo());
            lineDTO.setSsPono(line.getCompMatPono());
            lineDTO.setSsNum(line.getCompMatNum());
            // 从基本表PM_COMPOSITE_SLAB中获取
            lineDTO.setSlabNo(pmCompositeSlab.getSlabNo());
            lineDTO.setHeatNo(pmCompositeSlab.getHeatNo());
            lineDTO.setPono(pmCompositeSlab.getPono());
            lineDTO.setActThick(pmCompositeSlab.getActThick());
            lineDTO.setActWidth(pmCompositeSlab.getActWidth());
            lineDTO.setActLength(pmCompositeSlab.getActLength());
            lineDTO.setRollType(pmCompositeSlab.getRollType());
            lineDTO.setRollAimThick(pmCompositeSlab.getRollAimThick());
            lineDTO.setRollAimWidth(pmCompositeSlab.getRollAimWidth());
            resultList.add(lineDTO);
        }
        // 按照层号排序
        return resultList.stream().sorted(Comparator.comparing(PmCompositeSlabActLineDTO::getLayerNo)).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveData(Long tenantId, PmCompositeSlabActDTO dto) {
        if (Objects.isNull(dto)) {
            return;
        }
        // 1. 校验各层之间基材号是否相同
        List<String> baseMatNoList = dto.getActDTOList().stream().map(PmCompositeSlabActLineDTO::getBaseMatNo).distinct().collect(Collectors.toList());
        if (baseMatNoList.size() < dto.getActDTOList().size()) {
            throw new CommonException("pm.composite_slab_list_001");
        }

        List<PmCompositeSlab> pmCompositeSlabs = pmCompositeSlabRepository.selectByCondition(Condition.builder(PmCompositeSlab.class)
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_SLAB_ID, dto.getSlabId()))
                .build());
        if (CollectionUtils.isEmpty(pmCompositeSlabs)) {
            throw new CommonException("pm.composite_slab_013", dto.getSlabId(), "【叠轧坯基本信息表PM_COMPOSITE_SLAB】");
        }

        boolean isStatus = false;
        LocalDate now = LocalDate.now();
        // 给PM_COMPOSITE_SLAB赋值
        PmCompositeSlab pmCompositeSlab = pmCompositeSlabs.get(0);
        pmCompositeSlab.setHeatNo(dto.getHeatNo());
        pmCompositeSlab.setPono(dto.getPono());
        pmCompositeSlab.setActThick(dto.getActThick());
        pmCompositeSlab.setActWidth(dto.getActWidth());
        pmCompositeSlab.setActLength(dto.getActLength());
        pmCompositeSlab.setRollType(dto.getRollType());
        pmCompositeSlab.setRollAimThick(dto.getRollAimThick());
        pmCompositeSlab.setRollAimWidth(dto.getRollAimWidth());
        // 试验号赋值
        String sampleLotNo = pmCompositeSlab.getSampleLotNo();
        if (StringUtils.isEmpty(dto.getSampleLotNo()) && StringUtils.isEmpty(pmCompositeSlab.getSampleLotNo())) {
            Map<String, String> paramsMap = new HashMap<String, String>(1);
            paramsMap.put("year", String.format("%02d%02d%02d", now.getYear() % 100, now.getMonthValue(), now.getDayOfMonth()));
            sampleLotNo = codeRuleBuilder.generateCode(tenantId, Constants.CodeRule.SAMPLE_LOT_NO,
                    CodeConstants.CodeRuleLevelCode.GLOBAL, Constants.CodeRule.GLOBAL_LEVEL_VALUE, paramsMap);
        } else if (StringUtils.isNotEmpty(dto.getSampleLotNo())) {
            sampleLotNo = dto.getSampleLotNo();
        }
        pmCompositeSlab.setSampleLotNo(sampleLotNo);
        pmCompositeSlab.setTenantId(tenantId);
        
        // 第一次提交时候才修改状态
        if (METHOD_STATUS_INSERT.equals(dto.getMethodStatus()) && !Constants.StatusCode.STATUS_CODE_52.equals(pmCompositeSlab.getStatusCode())) {
            if(Constants.StatusCode.STATUS_CODE_54.equals(pmCompositeSlab.getStatusCode())) {
                throw new CommonException("pm.composite_slab_024"); 
            }
            pmCompositeSlab.setStatusCode(Constants.StatusCode.STATUS_CODE_52);
            isStatus = true;
        }

        // 查询明细表
        List<PmCompositeSlabList> pmCompositeSlabLists = pmCompositeSlabListRepository.selectByCondition(Condition.builder(PmCompositeSlabList.class)
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlabList.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlabList.FIELD_SLAB_ID, pmCompositeSlab.getSlabId())).build());
        // 校验是否为空
        if (CollectionUtils.isEmpty(pmCompositeSlabLists)) {
            throw new CommonException("pm.composite_slab_013", dto.getSlabId(), "【复合/叠轧坯明细信息表PM_COMPOSITE_SLAB_LIST】");
        }

        List<WmSigleQtyVO> WmSigleQtyVOList = new ArrayList<>();
        //
        for (PmCompositeSlabList line : pmCompositeSlabLists) {
            // 将旧的复材库存加回来
            if (line.getCompMatId() != null) {
                WmSigleQtyVO wmSigleQtyVO = new WmSigleQtyVO();
                wmSigleQtyVO.setMatSigleId(line.getCompMatId());
                wmSigleQtyVO.setMatNo(line.getCompMatNo());
                wmSigleQtyVO.setOrderNo(line.getBaseOrderNo());
                wmSigleQtyVO.setMatQty(line.getCompMatNum());
                WmSigleQtyVOList.add(wmSigleQtyVO);
            }
        }

        // 获取复材厚度
        List<Long> matSigleIdList = dto.getActDTOList().stream().filter(item-> item.getSsId() != null).map(PmCompositeSlabActLineDTO::getSsId).distinct()
                .collect(Collectors.toList());
        List<String> matNoList = dto.getActDTOList().stream().filter(item-> StringUtils.isNotEmpty(item.getSsNo())).map(PmCompositeSlabActLineDTO::getSsNo).distinct()
                .collect(Collectors.toList());
        Map<Long, String> matSigleIdNoMap = dto.getActDTOList().stream().filter(item -> StringUtils.isNotEmpty(item.getSsNo()))
                .collect(Collectors.toMap(PmCompositeSlabActLineDTO::getSsId, PmCompositeSlabActLineDTO::getSsNo, (k,v)->k));
        Map<Long, BigDecimal>  wmMatSigleMap = new HashMap<>(matSigleIdList.size());
        if (CollectionUtils.isNotEmpty(matSigleIdList)) {
            // 查询复材库存，校验库存数量
            List<WmMatSigleVO> wmMatSigleList = pmCompositeSlabMapper.selectMatSigleByMatNo(matSigleIdList, tenantId);
            if (CollectionUtils.isEmpty(wmMatSigleList)) {
               throw new CommonException("pm.composite_slab_016", Strings.join(matNoList, ','));
            }

            wmMatSigleMap = wmMatSigleList.stream().filter(item -> item.getMatThick() != null)
                    .collect(Collectors.toMap(WmMatSigleVO::getMatSigleId, WmMatSigleVO::getMatThick, (k, v) -> k));
            // 2. 如果选择了复材，校验复材库存是否小于0，如果是，提示：“新增失败！复材库存不足！”
            Map<Long, Double> matNoQtyMap = dto.getActDTOList().stream().filter(item -> StringUtils.isNotEmpty(item.getSsNo())).
                    collect(Collectors.groupingBy(PmCompositeSlabActLineDTO::getSsId, Collectors.summingDouble(PmCompositeSlabActLineDTO::getSsNum)));
            Map<Long, BigDecimal> matSigleMap = wmMatSigleList.stream().filter(item -> item.getMatQty() != null)
                    .collect(Collectors.toMap(WmMatSigleVO::getMatSigleId, WmMatSigleVO::getMatQty, (k, v) -> k));
            for (Long matSigleId : matSigleIdList) {
                if (!matSigleMap.containsKey(matSigleId)) {
                    throw new CommonException("pm.composite_slab_014", matSigleIdNoMap.get(matSigleId));
                }
                if (matSigleMap.get(matSigleId).compareTo(BigDecimal.valueOf(matNoQtyMap.get(matSigleId))) < 0) {
                    throw new CommonException("pm.composite_slab_015", matSigleIdNoMap.get(matSigleId), matSigleMap.get(matSigleId));
                }
            }
        }

        // 获取碳板密度
        List<LovValueDTO> densityList = lovAdapter.queryLovValue("PM.C_DENSITY", tenantId);
        BigDecimal compMatDensity = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(densityList)) {
            compMatDensity = BigDecimal.valueOf(Double.parseDouble(densityList.get(0).getMeaning()));
        }

        BigDecimal actWtTotal = BigDecimal.ZERO;
        List<MatStatusModifyVO> matStatusModifyVOList = new ArrayList<>(pmCompositeSlabLists.size());
        List<WmInStockVO> wmInStockVOList = new ArrayList<>(pmCompositeSlabLists.size());
        // 更新各层数据
        Map<Long, PmCompositeSlabActLineDTO> noSlabActMap = dto.getActDTOList().stream()
                .collect(Collectors.toMap(PmCompositeSlabActLineDTO::getLayerNo, Function.identity(), (v1, v2) -> v1));
        for (PmCompositeSlabList line : pmCompositeSlabLists) {

            if (noSlabActMap.containsKey(line.getLayerNo())) {
                PmCompositeSlabActLineDTO lineDto = noSlabActMap.get(line.getLayerNo());
                line.setBaseMatId(lineDto.getBaseMatId());
                line.setBaseMatNo(lineDto.getBaseMatNo());
                line.setBaseMatThick(lineDto.getMatActThk());
                line.setBaseMatWidth(lineDto.getMatActWid());
                line.setBaseMatLength(lineDto.getMatActLen());
                line.setBaseMatWt(lineDto.getMatActWgt());
                line.setCompMatType(lineDto.getSsType());
                line.setCompMatId(lineDto.getSsId());
                line.setCompMatNo(lineDto.getSsNo());
                line.setCompMatPono(lineDto.getSsPono());
                line.setCompMatNum(lineDto.getSsNum());
                line.setTenantId(tenantId);

                // 组装调用轧钢修改基材状态数据
                MatStatusModifyVO matStatusModifyVO = new MatStatusModifyVO();
                matStatusModifyVO.setMatNo(line.getBaseMatNo());
                matStatusModifyVO.setPpFlag(Constants.PpFlag.HP);
                matStatusModifyVOList.add(matStatusModifyVO);

                // 组装调用仓储删除垛位信息
                WmInStockVO wmInStockVO = new WmInStockVO();
                wmInStockVO.setMatId(line.getBaseMatId());
                wmInStockVO.setMatKind(Constants.PpFlag.HP);
                wmInStockVOList.add(wmInStockVO);

                // 复材号为空，则不计算实际重量
//                if (StringUtils.isEmpty(lineDto.getSsNo())) {
//                    continue;
//                }
                // 复材重量 = 复材厚度*复材宽度*复材长度* 复材密度*复材块数
//                if (!wmMatSigleMap.containsKey(lineDto.getSsId())) {
//                    throw new CommonException("pm.composite_slab_0016", lineDto.getSsNo());
//                }

                // 碳板重量 = （实际厚度-复材厚度*复材块数）*实际宽度*实际长度*碳板密度*碳板块数
//               BigDecimal compositeThick = wmMatSigleMap.get(lineDto.getSsId());
//               BigDecimal compositeWt = compositeThick.multiply(dto.getActWidth() == null ? BigDecimal.ZERO : dto.getActWidth())
//                       .multiply(dto.getActLength() == null ? BigDecimal.ZERO : dto.getActLength())
//                       .multiply(compMatDensity).multiply(lineDto.getSsNum() == null ? BigDecimal.ZERO : new BigDecimal(lineDto.getSsNum()));

               // 碳板重量 = （实际厚度-复材厚度*复材块数）*实际宽度*实际长度*碳板密度*碳板块数
//                BigDecimal boardWeight = (dto.getActThick() == null ? BigDecimal.ZERO : dto.getActThick())
//                        .subtract(compositeThick.multiply(lineDto.getSsNum() == null ? BigDecimal.ZERO : new BigDecimal(lineDto.getSsNum())))
//                         .multiply(dto.getActWidth() == null ? BigDecimal.ZERO : dto.getActWidth())
//                         .multiply(dto.getActLength() == null ? BigDecimal.ZERO : dto.getActLength()).multiply(compMatDensity)
//                         .multiply(new BigDecimal(dto.getActDTOList().size()));

                // 实际重量 = 复材重量 + 碳板重量
//                BigDecimal actWt = compositeWt.add(boardWeight);
//                actWtTotal = actWtTotal.add(actWt);

            }
        }

        // 实际重量=材料实际厚度*材料实际宽度*材料长度*(PM.C DENSITY)*0.000000001
        if (dto.getActThick() != null && dto.getActWidth() != null && dto.getActLength() != null) {
            BigDecimal actWt = dto.getActThick().multiply(dto.getActWidth()).multiply(dto.getActLength()).multiply(compMatDensity);
            pmCompositeSlab.setActWt(actWt.divide(BigDecimal.valueOf(1000000000)));
        }
        // 更新PM_COMPOSITE_SLAB	复合/叠轧坯基本信息表
        pmCompositeSlabRepository.updateByPrimaryKey(pmCompositeSlab);

        // 更新复合/叠轧坯明细信息表
        pmCompositeSlabListRepository.batchUpdateByPrimaryKey(pmCompositeSlabLists);

        // 第一次提交
        if (isStatus) {
//             用轧钢实绩模块API，将基材材料状态修改为37，
//            mmEventClient.batchMatStatusModify(tenantId, Constants.EventCode.PM_MODIF_BASE_MAT_STATUS_LOCK, matStatusModifyVOList);
        }

        // 新的复材库存减掉
        List<PmCompositeSlabActLineDTO> compositeFilterList = dto.getActDTOList().stream().filter(item-> item.getSsId() != null).collect(Collectors.toList());
        for (PmCompositeSlabActLineDTO item : compositeFilterList) {
            WmSigleQtyVO wmSigleQtyVO = new WmSigleQtyVO();
            wmSigleQtyVO.setMatSigleId(item.getSsId());
            wmSigleQtyVO.setMatNo(item.getSsNo());
            wmSigleQtyVO.setOrderNo(item.getBaseOrderNo());
            wmSigleQtyVO.setMatQty(item.getSsNum()*(-1));
            WmSigleQtyVOList.add(wmSigleQtyVO);
        }

        // 调用仓储修改库存
        if (CollectionUtils.isNotEmpty(WmSigleQtyVOList)) {
            wmApiClient.syncSigleQty(tenantId, WmSigleQtyVOList);
        }

        // 提交时调用仓储接口，删除垛位信息
        if (METHOD_STATUS_INSERT.equals(dto.getMethodStatus())) {
            wmApiClient.matRemove(tenantId, wmInStockVOList);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteListBySlabId(Long tenantId, List<Long> slabIdList) {
        // 校验入参
        if (CollectionUtils.isEmpty(slabIdList)) {
            return;
        }
        // 根据id查询复合/叠轧坯基本信息表
        List<PmCompositeSlab> pmCompositeSlabs = pmCompositeSlabRepository.selectByCondition(Condition.builder(PmCompositeSlab.class)
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_SLAB_ID, slabIdList))
                .build());
        if (CollectionUtils.isEmpty(pmCompositeSlabs)) {
            return;
        }
        for (PmCompositeSlab pmCompositeSlab : pmCompositeSlabs) {
            // 校验复合/叠轧坯必须为52(材料产出)状态
            if (!pmCompositeSlab.getStatusCode().equals(Constants.StatusCode.STATUS_CODE_52)) {
                throw new CommonException("pm.composite_slab_005", pmCompositeSlab.getSlabNo());
            }
        }

        // 1. 修改复合/叠轧坯状态为50（计划状态）
        pmCompositeSlabs.forEach(pmCompositeSlab -> {
            pmCompositeSlab.setStatusCode(Constants.StatusCode.STATUS_CODE_50);
            pmCompositeSlab.setHeatNo(null);
            pmCompositeSlab.setPono(null);
            pmCompositeSlab.setActThick(null);
            pmCompositeSlab.setActWidth(null);
            pmCompositeSlab.setActLength(null);
            pmCompositeSlab.setActWt(null);
            pmCompositeSlab.setRollType(null);
            pmCompositeSlab.setRollAimThick(null);
            pmCompositeSlab.setRollAimWidth(null);
            pmCompositeSlab.setSampleLotNo(null);
        });
        // 更新复合/叠轧坯明细信息表
        pmCompositeSlabRepository.batchUpdateByPrimaryKey(pmCompositeSlabs);

        List<Long> idList = pmCompositeSlabs.stream().map(PmCompositeSlab::getSlabId).collect(Collectors.toList());
        List<PmCompositeSlabList> pmCompositeSlabLists = pmCompositeSlabListRepository.selectByCondition(Condition.builder(PmCompositeSlabList.class)
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlabList.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmCompositeSlabList.FIELD_SLAB_ID, idList)).build());
        if (CollectionUtils.isEmpty(pmCompositeSlabLists)) {
            return;
        }

        List<String> baseMatNoList = pmCompositeSlabLists.stream().map(PmCompositeSlabList::getBaseMatNo).collect(Collectors.toList());
        List<MmPlateVO> matStatusVOList = pmMmPlateMapper.getMmPlateByMatNo(baseMatNoList, tenantId);

        List<WmInStockVO> wmInStockVOList = pmCompositeSlabMapper.selectMatPileByMatNo(baseMatNoList, tenantId);

        List<MatStatusModifyVO> matStatusModifyVOList = new ArrayList<>(pmCompositeSlabLists.size());
        List<WmSigleQtyVO> WmSigleQtyVOList = new ArrayList<>();
        pmCompositeSlabLists.forEach(pmCompositeSlabList -> {
            // 组装调用轧钢修改基材状态数据
            MatStatusModifyVO matStatusModifyVO = new MatStatusModifyVO();
            matStatusModifyVO.setMatNo(pmCompositeSlabList.getBaseMatNo());
            matStatusModifyVO.setPpFlag(Constants.PpFlag.HP);
            matStatusModifyVOList.add(matStatusModifyVO);

            // 组装调用仓储修改复合坯参数
            if (StringUtils.isNotEmpty(pmCompositeSlabList.getCompMatNo())) {
                WmSigleQtyVO wmSigleQtyVO = new WmSigleQtyVO();
                wmSigleQtyVO.setMatSigleId(pmCompositeSlabList.getCompMatId());
                wmSigleQtyVO.setMatNo(pmCompositeSlabList.getCompMatNo());
                wmSigleQtyVO.setOrderNo(pmCompositeSlabList.getBaseOrderNo());
                wmSigleQtyVO.setMatQty(pmCompositeSlabList.getCompMatNum());
                WmSigleQtyVOList.add(wmSigleQtyVO);
            }

            // 置该复合坯对应的复合/叠轧坯明细信息表（PM_COMPOSITE_SLAB_LIST）表的基材信息空
            pmCompositeSlabList.setBaseMatId(null);
            pmCompositeSlabList.setBaseMatNo(null);
            pmCompositeSlabList.setBaseMatThick(null);
            pmCompositeSlabList.setBaseMatWidth(null);
            pmCompositeSlabList.setBaseMatLength(null);
            pmCompositeSlabList.setBaseMatWt(null);
            pmCompositeSlabList.setCompMatType(null);
            pmCompositeSlabList.setCompMatId(null);
            pmCompositeSlabList.setCompMatNo(null);
            pmCompositeSlabList.setCompMatPono(null);
            pmCompositeSlabList.setCompMatNum(null);
        });
        // 更新复合/叠轧坯明细信息表
        pmCompositeSlabListRepository.batchUpdateByPrimaryKey(pmCompositeSlabLists);

        // 查询mm_plate获取状态，如果都为37，调用轧钢材料状态变更修改为33
        Optional<MmPlateVO> matStatusOptional = matStatusVOList.stream().filter(item -> !"37".equals(item.getMatStatus())).findFirst();
        if (!matStatusOptional.isPresent()) {
           mmEventClient.batchMatStatusModify(tenantId, Constants.EventCode.PM_MODIF_BASE_MAT_STATUS_RELEASE, matStatusModifyVOList);
        }

        // 如果该复合坯下有复材信息，则调用仓储模块API将对应复材材料库存+复材块数.
        if (CollectionUtils.isNotEmpty(WmSigleQtyVOList)) {
            wmApiClient.syncSigleQty(tenantId, WmSigleQtyVOList);
        }

        // 调用仓储模块材料入库接口
        if (CollectionUtils.isNotEmpty(wmInStockVOList)) {
            wmApiClient.inStock(tenantId, wmInStockVOList);
        }
    }
}

