package com.jwipc.supplier.logic.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.enums.SqlLike;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.jwipc.aggregation.ModelAggregationService;
import com.jwipc.constant.FlagConst;
import com.jwipc.db.DbUtil;
import com.jwipc.exception.DaoException;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.security.LoginUtil;
import com.jwipc.supplier.constant.AuthenticationState;
import com.jwipc.supplier.constant.PurchaseCategoryType;
import com.jwipc.supplier.constant.SupplierPurchaseCategoryAttachmentType;
import com.jwipc.supplier.convert.SupplierConvert;
import com.jwipc.supplier.convert.SupplierMaterialDemoConvert;
import com.jwipc.supplier.convert.SupplierPurchaseCategoryConvert;
import com.jwipc.supplier.dto.*;
import com.jwipc.supplier.entity.*;
import com.jwipc.supplier.logic.SupplierPurchaseCategoryLogic;
import com.jwipc.supplier.logic.SupplierToOaLogic;
import com.jwipc.supplier.model.po.*;
import com.jwipc.supplier.model.query.SupplierPurchaseCategoryBaseQuery;
import com.jwipc.supplier.model.query.SupplierPurchaseCategorySelectQuery;
import com.jwipc.supplier.service.*;
import com.jwipc.sys.client.PurchaseGroupClient;
import com.jwipc.sys.client.dto.PurchaseGroupDTO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * <p> </p>
 *
 * @author BOGON
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@RequiredArgsConstructor
public class SupplierPurchaseCategoryLogicImpl implements SupplierPurchaseCategoryLogic {
    private final ISupplierPurchaseCategoryService supplierPurchaseCategoryService;
    private final SupplierPurchaseCategoryConvert supplierPurchaseCategoryConvert;
    private final ISupplierService supplierService;
    private final ISupplierPurchaseCategoryAttachmentService supplierPurchaseCategoryAttachmentService;
    private final ModelAggregationService modelAggregationService;
    private final ISupplierPurchaseCategoryDemoService supplierPurchaseCategoryDemoService;
    private final ISupplierMaterialDemoService supplierMaterialDemoService;
    private final SupplierMaterialDemoConvert supplierMaterialDemoConvert;
    private final ISupplierInvitaionService supplierInvitaionService;
    private final ISupplierBankService supplierBankService;
    private final ISupplierContactsService supplierContactsService;
    private final SupplierToOaLogic supplierToOaLogic;
    private final ISupplierSqeScoreService supplierSqeScoreService;
    private final PurchaseGroupClient purchaseGroupClient;
    private final SupplierConvert supplierConvert;

    @Override
    public List<SupplierPurchaseCategoryBaseDTO> listByInvitation(Long invitationId) {
        final List<SupplierPurchaseCategory> list = supplierPurchaseCategoryService.list(
                new LambdaQueryWrapper<SupplierPurchaseCategory>().eq(SupplierPurchaseCategory::getInvitationId,
                        invitationId));
        return supplierPurchaseCategoryConvert.entities2Dtos(list);
    }

    @Override
    public PageView listSupplier(SupplierPurchaseCategorySelectQuery query) {
        Page<SupplierPurchaseCategory> page = PageUtil.toPage(query);
        final LambdaQueryWrapper<SupplierPurchaseCategory> queryWrapper =
                new LambdaQueryWrapper<SupplierPurchaseCategory>()
                        .eq(Objects.nonNull(query.getSupplierId()),
                                SupplierPurchaseCategory::getSupplierId,
                                query.getSupplierId())
                        .and(StrUtil.isNotEmpty(query.getCategory()),
                                a -> a.like(SupplierPurchaseCategory::getPurchaseCategoryCode,
                                                query.getCategory()).or()
                                        .like(SupplierPurchaseCategory::getPurchaseCategoryName,
                                                query.getCategory()))
                        .in(CollUtil.isNotEmpty(DbUtil.toList(query.getState())), SupplierPurchaseCategory::getState,
                                DbUtil.toList(query.getState()));
        queryWrapper.exists(StrUtil.isNotEmpty(query.getSupplier()),
                "select ts.id from t_supplier ts where ts.id=t_supplier_purchase_category.supplier_id and (ts" +
                        ".supplier_name like {0} OR ts.supplier_erp_code LIKE {0} OR ts.supplier_code like {0})",
                SqlUtils.concatLike(query.getSupplier(), SqlLike.DEFAULT));
        final List<SupplierPurchaseCategory> list = supplierPurchaseCategoryService.list(page,
                queryWrapper);
        final List<SupplierPurchaseCategorySelectorDTO> categorySelectorDTOS =
                supplierPurchaseCategoryConvert.entities2ListDtos(
                        list);
        modelAggregationService.processRelationAggregation(categorySelectorDTOS);
        final List<Long> purchaseCategoryIds = new ArrayList<>(categorySelectorDTOS.stream()
                .map(SupplierPurchaseCategorySelectorDTO::getId).collect(Collectors.toSet()));
        if (CollUtil.isNotEmpty(purchaseCategoryIds)) {
            final List<SupplierPurchaseCategoryDemo> purchaseCategoryDemos = supplierPurchaseCategoryDemoService.list(
                    new LambdaQueryWrapper<SupplierPurchaseCategoryDemo>()
                            .in(SupplierPurchaseCategoryDemo::getSupplierPurchaseCategoryId, purchaseCategoryIds));
            // 根据 supplierPurchaseCategoryId 分组并统计数量
            Map<Long, Long> countCache = purchaseCategoryDemos.stream()
                    .collect(Collectors.groupingBy(SupplierPurchaseCategoryDemo::getSupplierPurchaseCategoryId,
                            Collectors.counting()));
            for (SupplierPurchaseCategorySelectorDTO it : categorySelectorDTOS) {
                final Long count = countCache.get(it.getId());
                if (Objects.nonNull(count)) {
                    it.setDemoSize(count);
                }
            }
        }
        return PageUtil.getPV(categorySelectorDTOS,
                Objects.isNull(page) ? categorySelectorDTOS.size() : page.getTotal());
    }

    @NotNull
    private Map<Long, List<Long>> getFileMap(List<Long> purchaseCategoryIds,
                                             SupplierPurchaseCategoryAttachmentType type)
    {
        /**
         * 需要查询附件信息
         */
        if (CollUtil.isEmpty(purchaseCategoryIds)) {
            return Collections.emptyMap();
        }
        final List<SupplierPurchaseCategoryAttachment> attachments = supplierPurchaseCategoryAttachmentService.list(
                new LambdaQueryWrapper<SupplierPurchaseCategoryAttachment>().in(
                                SupplierPurchaseCategoryAttachment::getSupplierPurchaseCategoryId, purchaseCategoryIds)
                        .eq(SupplierPurchaseCategoryAttachment::getType,
                                type.getType()));
        final Map<Long, List<Long>> map = attachments.stream().collect(
                Collectors.groupingBy(SupplierPurchaseCategoryAttachment::getSupplierPurchaseCategoryId,
                        Collectors.mapping(SupplierPurchaseCategoryAttachment::getFileId, Collectors.toList())));
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAuthFile(Long id, String fileIds) {
        //需要保存样品认证附件
        final List<String> fileIdList = StrUtil.split(fileIds, StrUtil.COMMA);
        //先取数据库中的附件
        final LambdaQueryWrapper<SupplierPurchaseCategoryAttachment> eq =
                new LambdaQueryWrapper<SupplierPurchaseCategoryAttachment>().eq(
                                SupplierPurchaseCategoryAttachment::getSupplierPurchaseCategoryId, id)
                        .eq(SupplierPurchaseCategoryAttachment::getType,
                                SupplierPurchaseCategoryAttachmentType.AUTH_FILE.getType());
        supplierPurchaseCategoryAttachmentService.remove(eq);
        List<SupplierPurchaseCategoryAttachment> insertLists = Lists.newArrayList();
        for (String s : fileIdList) {
            SupplierPurchaseCategoryAttachment attachment = new SupplierPurchaseCategoryAttachment();
            attachment.setCreateTime(LocalDateTime.now());
            attachment.setCreateUser(LoginUtil.getUserId());
            attachment.setSupplierPurchaseCategoryId(id);
            attachment.setFileId(Long.valueOf(s));
            attachment.setType(SupplierPurchaseCategoryAttachmentType.AUTH_FILE.getType());
            insertLists.add(attachment);
        }
        if (CollUtil.isNotEmpty(insertLists)) {
            supplierPurchaseCategoryAttachmentService.saveBatch(insertLists);
        }
    }

    @Override
    public PageView getPotentialList(SupplierPurchaseCategoryBaseQuery query) {
        final Page<SupplierPurchaseCategoryListPO> page = PageUtil.toPage(query);
        query.setState(AuthenticationState.POTENTIAL.getState());
        List<SupplierPurchaseCategoryListPO> categoryListPOS = supplierPurchaseCategoryService.findPage(page, query);
        List<SupplierPotentialListDTO> supplierPotentialListDTOS = supplierPurchaseCategoryConvert.pos2PotentialDtos(
                categoryListPOS);
        return PageUtil.getPV(supplierPotentialListDTOS, page.getTotal());
    }

    @Override
    public List<SupplierPotentialListDTO> getPotentialAllList(SupplierPurchaseCategoryBaseQuery query) {
        query.setState(AuthenticationState.POTENTIAL.getState());
        List<SupplierPurchaseCategoryListPO> categoryListPOS = supplierPurchaseCategoryService.findPage(null, query);
        List<SupplierPotentialListDTO> supplierPotentialListDTOS = supplierPurchaseCategoryConvert.pos2PotentialDtos(
                categoryListPOS);
        return supplierPotentialListDTOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void convertSmallbatch(String id) {


        //需要转小批量样品认证通过才能转
        final List<SupplierPurchaseCategoryListPO> purchaseCategories = supplierPurchaseCategoryService.findPOForIds(
                Arrays.asList(id.split(StrUtil.COMMA)));
        //判断是否是同一个供应商
        // 获取第一个元素的supplierId作为参照
        Long referenceSupplierId = purchaseCategories.get(0).getSupplierId();

        // 遍历列表，与参照值进行比较
        for (SupplierPurchaseCategoryListPO category : purchaseCategories) {
            if (!Objects.equals(category.getSupplierId(), referenceSupplierId)) {
                throw new DaoException("请选择相同供应商进行转小批量!");
            }
        }
        // 校验是否有相同OA 单号的勾选
        List<SupplierPurchaseCategoryListPO> collect = purchaseCategories.stream().filter(pop -> StringUtils.isNotEmpty(pop.getOaId())).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(collect)){
            String oaId = collect.get(0).getOaId();
            if(StringUtils.isNotEmpty(oaId)){
                final List<SupplierPurchaseCategory> purchaseCategory = supplierPurchaseCategoryService.list(
                        new LambdaQueryWrapper<>(SupplierPurchaseCategory.class).eq(SupplierPurchaseCategory::getOaId,
                                oaId));
                if (purchaseCategory.size()!=collect.size()) {
                    throw new DaoException("该供应商下还有相同OA流程单号的数据未选择!");
                }
            }
        }


        //如果是特批供应商直接推送oa
        final Supplier dbSupplier = supplierService.getById(referenceSupplierId);
        Integer supplierAttribution = dbSupplier.getSupplierAttribution();
        if (dbSupplier.getAssessType().equals("3")) {
            //表示特批直接推送OA
            supplierToOaLogic.supplierAccessToOa(dbSupplier,
                    supplierPurchaseCategoryService.listByIds(Arrays.asList(id.split(StrUtil.COMMA))),supplierAttribution);
            return;
        }
        //Z006客供品类的也不需要校验 邓京术 2025-07-16
        //Z011代收款供应商\Z012-手板供应商不需要校验
        //判断是否存在sqe评分MRO的品类不校验
        if (!purchaseCategories.get(0).getPurchaseCategoryCode().equals("Z011")&&!purchaseCategories.get(0).getPurchaseCategoryCode().equals("Z012")&&
                !purchaseCategories.get(0).getPurchaseCategoryCode().equals("Z005") && (null == dbSupplier.getSupplierCategoryType() || !dbSupplier.getSupplierCategoryType().equals("1"))) {
            final long count1 = supplierSqeScoreService.count(
                    new LambdaQueryWrapper<>(SupplierSqeScore.class).eq(SupplierSqeScore::getSupplierId,
                            referenceSupplierId));
            if (count1 <= 0) {
                throw new DaoException("请先进行SQE评分再转小批量!");
            }
        }
        if (CollUtil.isNotEmpty(purchaseCategories)) {
            //需要判断是否生产性
            //需要判断，不是特批供应商并且是生产性供应商就需要上传现场认证附件
            final Supplier supplier = supplierService.getById(purchaseCategories.get(0).getSupplierId());
            final long count = purchaseCategories.stream()
                    .filter(a -> a.getPurchaseType().equals(PurchaseCategoryType.PRODUCTION_TYPE.getCode())).count();
            Set<String> tipMsg = Sets.newHashSet();
            if (!supplier.getAssessType().equals(3) && count > 0L) {
                purchaseCategories.stream()
                        .filter(a -> a.getPurchaseType().equals(PurchaseCategoryType.PRODUCTION_TYPE.getCode()))
                        .forEach(a -> {
                            if (Objects.isNull(a.getReportFlag()) ||
                                    (!a.getReportFlag().equals(FlagConst.Y.getCode()))) {
                                tipMsg.add(a.getPurchaseCategoryCode());
                            }
                        });
            }
            //Z006客供品类的也不需要校验 邓京术 2025-07-16
            if ( !purchaseCategories.get(0).getPurchaseCategoryCode().equals("Z011") && !purchaseCategories.get(0).getPurchaseCategoryCode().equals("Z012") &&
                    (CollUtil.isNotEmpty(tipMsg) && (null == supplier.getSupplierCategoryType() || !"1".equals(supplier.getSupplierCategoryType())))) {
                throw new DaoException("请上传现场认证附件：" + CollUtil.join(tipMsg, StrUtil.COMMA));
            }
            Integer sa=null;
            sa= supplier.getSupplierAttribution();
            //Z011和Z012品类外 添加了其他品类后按照正常供应商流程走， 删除标识
            if ( purchaseCategories.size()>1  ) {
                final Set<String> collected = purchaseCategories.stream().map(a -> a.getPurchaseCategoryCode()).collect(Collectors.toSet());
                if ( (collected.contains("Z011") || collected.contains("Z012"))   ) {
                    sa=null;
                }
            }
            //资源整合部标识去除
            supplier.setSupplierAttribution(null);
            // 推送oa
            supplierToOaLogic.supplierAccessToOa(supplier,
                    supplierPurchaseCategoryService.listByIds(Arrays.asList(id.split(StrUtil.COMMA))),sa);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importSupplierApproval(String ids) {
        //查询供应商资质表数据
        final List<SupplierPurchaseCategoryListPO> purchaseCategories = supplierPurchaseCategoryService.findPOForIds(
                Arrays.asList(ids.split(StrUtil.COMMA)));
        // 1.遍历列表，与参照值进行比较找出不同的供应商循环调用推送OA接口生成不同的OA创建供应商流程

        Map<Long, List<Long>> supplierIdToIdListMap = purchaseCategories.stream()
                .collect(Collectors.groupingBy(
                        SupplierPurchaseCategoryListPO::getSupplierId, // 分组的key为supplierId
                        Collectors.mapping(
                                SupplierPurchaseCategoryListPO::getId, // 提取每个对象的id
                                Collectors.toList() // 将id收集到List中
                        )
                ));
        if (!supplierIdToIdListMap.isEmpty()) {
            supplierIdToIdListMap.forEach((supplierId, idList) -> {
                System.out.println("Supplier ID: " + supplierId);
                idList.forEach(id -> System.out.println(" - ID: " + id));
                final Supplier dbSupplier = supplierService.getById(supplierId);
                supplierToOaLogic.supplierAccessToOa(dbSupplier,
                        supplierPurchaseCategoryService.listByIds(idList),dbSupplier.getSupplierAttribution());
            });
        }
        return;

    }

    @Override
    public PageView getSmallbatchList(SupplierPurchaseCategoryBaseQuery query) {
        final Page<SupplierPurchaseCategoryListPO> page = PageUtil.toPage(query);
        query.setState(AuthenticationState.SMALL_BATCH.getState());
        List<SupplierPurchaseCategoryListPO> categoryListPOS = supplierPurchaseCategoryService.findPage(page, query);
        List<SupplierSmallbatchListDTO> supplierSmallbatchListDTOS = supplierPurchaseCategoryConvert.pos2SmallbatchDtos(
                categoryListPOS);
        return PageUtil.getPV(supplierSmallbatchListDTOS, page.getTotal());
    }

    @Override
    public void saveOnSiteAuthenticationFile(Long id, String fileIds) {
        //需要保存现场认证附件
        final List<String> fileIdList = StrUtil.split(fileIds, StrUtil.COMMA);
        //先取数据库中的附件
        final LambdaQueryWrapper<SupplierPurchaseCategoryAttachment> eq =
                new LambdaQueryWrapper<SupplierPurchaseCategoryAttachment>().eq(
                                SupplierPurchaseCategoryAttachment::getSupplierPurchaseCategoryId, id)
                        .eq(SupplierPurchaseCategoryAttachment::getType,
                                SupplierPurchaseCategoryAttachmentType.ON_SITE_AUTHENTICATION.getType());
        supplierPurchaseCategoryAttachmentService.remove(eq);
        List<SupplierPurchaseCategoryAttachment> insertLists = Lists.newArrayList();
        if (StrUtil.isEmpty(fileIds)) {
            return;
        }
        for (String s : fileIdList) {
            SupplierPurchaseCategoryAttachment attachment = new SupplierPurchaseCategoryAttachment();
            attachment.setCreateTime(LocalDateTime.now());
            attachment.setCreateUser(LoginUtil.getUserId());
            attachment.setSupplierPurchaseCategoryId(id);
            attachment.setFileId(Long.valueOf(s));
            attachment.setType(SupplierPurchaseCategoryAttachmentType.ON_SITE_AUTHENTICATION.getType());
            insertLists.add(attachment);
        }
        if (CollUtil.isNotEmpty(insertLists)) {
            supplierPurchaseCategoryAttachmentService.saveBatch(insertLists);
        }
    }

    /**
     * 供应商转合格
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void convertQualified(Long id, String demoIds) {
        final SupplierPurchaseCategory supplierPurchaseCategory = supplierPurchaseCategoryService.getById(id);
        supplierPurchaseCategory.setState(AuthenticationState.QUALIFIED.getState());
        supplierPurchaseCategory.setQualifiedTime(LocalDateTime.now());
        supplierPurchaseCategoryService.updateById(supplierPurchaseCategory);
        sumbmitDemoRel(id, demoIds);
    }

    @Override
    public PageView getQualifiedList(SupplierPurchaseCategoryBaseQuery query) {
        final Page<SupplierPurchaseCategoryListPO> page = PageUtil.toPage(query);
        query.setState(AuthenticationState.QUALIFIED.getState());
        List<SupplierPurchaseCategoryListPO> categoryListPOS = supplierPurchaseCategoryService.findPage(page, query);
        List<SupplierQualifiedListDTO> supplierPotentialListDTOS = supplierPurchaseCategoryConvert.pos2QualifiedDtos(
                categoryListPOS);
        //根据采购组代码取采购级名称（人员姓名）， 根据人工号对应的采购组代码取申请人姓名
        List<PurchaseGroupDTO> purchaseGroupDTOList = purchaseGroupClient.getAll();
        supplierPotentialListDTOS.stream().forEach(item -> {
            for (PurchaseGroupDTO purchaseGroupDTO: purchaseGroupDTOList) {
                if (null != item.getPurchaseGroupCode() && item.getPurchaseGroupCode().equals(purchaseGroupDTO.getPurchaseGroupCode())) {
                    item.setPurchaseGroupCode(new StringBuilder("(").append(purchaseGroupDTO.getPurchaseGroupCode()).append(")").append(purchaseGroupDTO.getPurchaseGroupName()).toString());
                }
                if (null != item.getPurchaseGroupCode() && item.getRecommenderCode().equals(purchaseGroupDTO.getPurchaseGroupCode())) {
                    item.setRecommender(purchaseGroupDTO.getPurchaseGroupName());
                }
            }
        });
        return PageUtil.getPV(supplierPotentialListDTOS, page.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sumbmitDemoRel(Long id, String demoIds) {
        final List<String> demoIdList = StrUtil.split(demoIds, StrUtil.COMMA);
        List<SupplierPurchaseCategoryDemo> insertLists = new ArrayList<>();
        for (String s : demoIdList) {
            //需要判断是否已存在如果已经存在就不需要再插入
            final SupplierPurchaseCategoryDemo one = supplierPurchaseCategoryDemoService.getOne(
                    new LambdaQueryWrapper<SupplierPurchaseCategoryDemo>()
                            .eq(SupplierPurchaseCategoryDemo::getSupplierPurchaseCategoryId, id)
                            .eq(SupplierPurchaseCategoryDemo::getSupplierDemoId, s), false);
            if (Objects.nonNull(one)) {
                continue;
            }
            SupplierPurchaseCategoryDemo supplierPurchaseCategoryDemo = new SupplierPurchaseCategoryDemo();
            supplierPurchaseCategoryDemo.setSupplierDemoId(Long.valueOf(s));
            supplierPurchaseCategoryDemo.setSupplierPurchaseCategoryId(id);
            supplierPurchaseCategoryDemo.setCreateUser(LoginUtil.getUserId());
            supplierPurchaseCategoryDemo.setCreateTime(LocalDateTime.now());
            insertLists.add(supplierPurchaseCategoryDemo);
        }
        if (CollUtil.isNotEmpty(insertLists)) {
            supplierPurchaseCategoryDemoService.saveBatch(insertLists);
        }
    }

    @Override
    public PageView getDemo(Long id) {
        final List<SupplierPurchaseCategoryDemo> demos = supplierPurchaseCategoryDemoService.list(
                new LambdaQueryWrapper<SupplierPurchaseCategoryDemo>()
                        .eq(SupplierPurchaseCategoryDemo::getSupplierPurchaseCategoryId, id));
        final Set<Long> ids = demos.stream().map(a -> a.getSupplierDemoId()).collect(Collectors.toSet());
        if (CollUtil.isNotEmpty(ids)) {
            final List<SupplierMaterialDemo> supplierMaterialDemos = supplierMaterialDemoService.listByIds(ids);
            final List<SupplierMaterialDemoBaseDTO> baseDTOS = supplierMaterialDemoConvert.entities2Dtos(
                    supplierMaterialDemos);
            return PageUtil.getPV(baseDTOS, baseDTOS.size());
        }

        return PageUtil.getPV(Collections.emptyList(), 0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateFirst(Long id) {
        final SupplierPurchaseCategory purchaseCategory = supplierPurchaseCategoryService.getById(id);
        final Long supplierId = purchaseCategory.getSupplierId();
        supplierPurchaseCategoryService.update(new LambdaUpdateWrapper<SupplierPurchaseCategory>()
                .set(SupplierPurchaseCategory::getFirstFlag, FlagConst.N.getCode())
                .eq(SupplierPurchaseCategory::getSupplierId, supplierId)
                .ne(SupplierPurchaseCategory::getId, id));
        purchaseCategory.setFirstFlag(FlagConst.Y.getCode());
        supplierPurchaseCategoryService.updateById(purchaseCategory);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateFirstForAll(Long supplierId) {
        final List<SupplierPurchaseCategory> purchaseCategory = supplierPurchaseCategoryService.list(
                new LambdaQueryWrapper<>(SupplierPurchaseCategory.class).eq(SupplierPurchaseCategory::getSupplierId,
                        supplierId));
        if (CollUtil.isNotEmpty(purchaseCategory)) {
            if (purchaseCategory.size() == 1) {
                supplierPurchaseCategoryService.update(new LambdaUpdateWrapper<SupplierPurchaseCategory>()
                        .set(SupplierPurchaseCategory::getFirstFlag, FlagConst.Y.getCode())
                        .eq(SupplierPurchaseCategory::getSupplierId, supplierId));
            } else {
                final long count = purchaseCategory.stream().filter(a -> Objects.nonNull(a.getFirstFlag()) &&
                        a.getFirstFlag().equals(FlagConst.Y.getCode())).count();
                if (count <= 0) {
                    supplierPurchaseCategoryService.update(new LambdaUpdateWrapper<SupplierPurchaseCategory>()
                            .set(SupplierPurchaseCategory::getFirstFlag, FlagConst.Y.getCode())
                            .eq(SupplierPurchaseCategory::getId, purchaseCategory.get(0).getId()));
                }
            }
        }
    }

    @Override
    public void saveOrUpdate(SupplierPurchaseCategoryBaseDTO supplierPurchaseCategoryBaseDTO) {
        final Long supplierId = supplierPurchaseCategoryBaseDTO.getSupplierId();
        SupplierPurchaseCategory supplierPurchaseCategory = supplierPurchaseCategoryConvert.dto2Entity(
                supplierPurchaseCategoryBaseDTO);
        supplierPurchaseCategory.setState(AuthenticationState.POTENTIAL.getState());
        supplierPurchaseCategory.setId(null);


        //获取到邀请的id
        final SupplierInvitaion invitaionServiceOne = supplierInvitaionService.getOne(
                new LambdaQueryWrapper<SupplierInvitaion>()
                        .eq(SupplierInvitaion::getSupplierId, supplierId));
        if (Objects.nonNull(invitaionServiceOne)) {
            supplierPurchaseCategory.setInvitationId(invitaionServiceOne.getId());
            supplierPurchaseCategory.setCreateTime(LocalDateTime.now());
            supplierPurchaseCategory.setCreateId(LoginUtil.getUserId());
        }
        //需要根据品类编码+采购组织判断啊采购品类的唯一性
        final List<SupplierPurchaseCategory> dbPurchaseCategory = supplierPurchaseCategoryService.list(
                new LambdaQueryWrapper<SupplierPurchaseCategory>().eq(SupplierPurchaseCategory::getSupplierId,
                        supplierId));
        //判断该供应商是否为客供品类供应商 Z006 如果是则SQE处理状态改为SQE已处理， 邓京术 2025-07-16
        dbPurchaseCategory.stream().forEach(item -> {
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(item.getPurchaseCategoryCode()) && item.getPurchaseCategoryCode().equals("Z006")) {
                supplierPurchaseCategory.setReportFlag(1);
            }
        });

        //客供类供应商扩充其他非“客供品类”时，判定供应商的“工商注册地址”是否有值，如果没有值，不允许扩充品类，需要先维护好“工商注册地址”；
        dbPurchaseCategory.stream().forEach(item -> {
            if (!supplierPurchaseCategoryBaseDTO.getPurchaseCategoryCode().equals("Z006")&&
                    org.apache.commons.lang3.StringUtils.isNotEmpty(item.getPurchaseCategoryCode()) && item.getPurchaseCategoryCode().equals("Z006")) {
                Supplier byId = supplierService.getById(supplierId);
                if(StringUtils.isEmpty(byId.getColBeiyOne())){
                    throw new DaoException("不允许扩充品类，需要先维护好“工商注册地址”!");
                }
            }
        });

        dbPurchaseCategory.add(supplierPurchaseCategory);
        //需要根据品类、税率、币种、付款条件、公司、组织、付款方式判断啊采购品类的唯一性
        final Map<String, String> stringStringMap = dbPurchaseCategory.stream().collect(
                Collectors.toMap(
                        category -> {
                            final String format = StrUtil.format("{}-{}-{}-{}-{}-{}-{}",
                                    category.getPurchaseCategoryCode(),
                                    category.getTaxCode(),
                                    category.getCurrencyCode(),
                                    category.getPaymentTerms(),
                                    category.getCompanyCode(),
                                    category.getPurchaseOrgCode(),
                                    category.getPaymentMethod()
                            );
                            return format;
                        },
                        SupplierPurchaseCategory::getPurchaseCategoryName,
                        (existing, replacement) -> existing));
        //校验
        Map<String, Long> codeCountMap = dbPurchaseCategory.stream()
                .collect(Collectors.groupingBy(
                        category -> {
                            final String format = StrUtil.format("{}-{}-{}-{}-{}-{}-{}",
                                    category.getPurchaseCategoryCode(),
                                    category.getTaxCode(),
                                    category.getCurrencyCode(),
                                    category.getPaymentTerms(),
                                    category.getCompanyCode(),
                                    category.getPurchaseOrgCode(),
                                    category.getPaymentMethod()
                            );
                            return format;
                        },
                        Collectors.counting()
                ));

        boolean hasDuplicates = codeCountMap.values().stream().anyMatch(a -> a > 1);
        if (hasDuplicates) {
            Set<String> tipMsg = Sets.newHashSet();
            codeCountMap.entrySet().stream()
                    .filter(entry -> entry.getValue() > 1)
                    .forEach(entry -> tipMsg.add(stringStringMap.get(entry.getKey())));
            throw new DaoException(String.join(",", tipMsg) + "出现重复");
        }

        supplierPurchaseCategoryService.save(supplierPurchaseCategory);
    }

    @Override
    public PageView getMainDataList(SupplierPurchaseCategoryBaseQuery query) {
        final Page<SupplierPurchaseCategoryListPO> page = PageUtil.toPage(query);
        List<SupplierPurchaseCategoryListPO> categoryListPOS = supplierPurchaseCategoryService.findMainPage(page,
                query);
        List<SupplierMainDataListDTO> mainDataListDTO = supplierPurchaseCategoryConvert.pos2MainData(categoryListPOS);
        return PageUtil.getPV(mainDataListDTO, page.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateFreeze(Set<String> purchaseOrgCodes, Long supplierId, Integer state) {
        supplierPurchaseCategoryService.update(new LambdaUpdateWrapper<SupplierPurchaseCategory>()
                .set(SupplierPurchaseCategory::getIsFreeze, state)
                .eq(SupplierPurchaseCategory::getSupplierId, supplierId)
                .in(SupplierPurchaseCategory::getPurchaseOrgCode, purchaseOrgCodes));
    }

    @Override
    public List<SupplierMainDataListDTO> findForMainDataExport(SupplierPurchaseCategoryBaseQuery query) {
        final List<SupplierPurchaseCategoryListPO> mainPage = supplierPurchaseCategoryService.findMainPage(null, query);
        return supplierPurchaseCategoryConvert.pos2MainData(mainPage);
    }

    @Override
    public List<SupplierBankDMDTO> findForBankdmReportExport(SupplierPurchaseCategoryBaseQuery query) {
        List<SupplierBankDMPO> data = supplierBankService.findForBankdmReportExport(query);
        return supplierPurchaseCategoryConvert.pos2MainData1(data);
    }

    @Override
    public List<SupplierProductTypeDMDTO> findForProducttypedmReportExport(SupplierPurchaseCategoryBaseQuery query) {
        List<SupplierProductTypeDMPO> data = supplierPurchaseCategoryService.findForProducttypedmReportExport(query);
        return supplierPurchaseCategoryConvert.pos2MainData2(data);
    }

    @Override
    public List<SupplierContactsDMDTO> findForContactdmReportExport(SupplierPurchaseCategoryBaseQuery query) {
        List<SupplierContactsDMPO> supplierContactsDMPOS = supplierContactsService.findForContactdmReportExport(query);
        return supplierPurchaseCategoryConvert.pos2MainData3(supplierContactsDMPOS);
    }

    @Override
    public List<SupplierSmallbatchListDTO> getSmallbatchAllList(SupplierPurchaseCategoryBaseQuery query) {
        query.setState(AuthenticationState.SMALL_BATCH.getState());
        List<SupplierPurchaseCategoryListPO> categoryListPOS = supplierPurchaseCategoryService.findPage(null, query);
        List<SupplierSmallbatchListDTO> supplierSmallbatchListDTOS = supplierPurchaseCategoryConvert.pos2SmallbatchDtos(
                categoryListPOS);
        return supplierSmallbatchListDTOS;
    }

    @Override
    public List<SupplierQualifiedListDTO> getQualifiedAllList(SupplierPurchaseCategoryBaseQuery query) {
        query.setState(AuthenticationState.QUALIFIED.getState());
        List<SupplierPurchaseCategoryListPO> categoryListPOS = supplierPurchaseCategoryService.findPage(null, query);
        List<SupplierQualifiedListDTO> supplierPotentialListDTOS = supplierPurchaseCategoryConvert.pos2QualifiedDtos(
                categoryListPOS);
        //根据采购组代码取采购级名称（人员姓名）， 根据人工号对应的采购组代码取申请人姓名
        List<PurchaseGroupDTO> purchaseGroupDTOList = purchaseGroupClient.getAll();
        supplierPotentialListDTOS.stream().forEach(item -> {
            for (PurchaseGroupDTO purchaseGroupDTO: purchaseGroupDTOList) {
                boolean falge1 = false;
                boolean falge2 = false;
                //设置对账采购组名称
                if (null == item.getPurchaseGroupCode()) {
                    falge1 = true;
                } else if (item.getPurchaseGroupCode().equals(purchaseGroupDTO.getPurchaseGroupCode())) {
                    falge1 = true;
                    item.setPurchaseGroupCode(new StringBuilder("(").append(purchaseGroupDTO.getPurchaseGroupCode()).append(")").append(purchaseGroupDTO.getPurchaseGroupName()).toString());
                }
                //设置申请人名称
                if (null == item.getRecommenderCode()) {
                    falge2 = true;
                } else if ( item.getRecommenderCode().equals(purchaseGroupDTO.getPurchaseGroupCode())) {
                    falge2 = true;
                    item.setRecommender(purchaseGroupDTO.getPurchaseGroupName());
                }
                if (falge1 && falge2) {
                    break;
                }
            }
        });

        return supplierPotentialListDTOS;
    }

    @Override
    public String findCurryCode(String supplierCode) {
        SupplierPurchaseCategory supplierPurchaseCategory = supplierPurchaseCategoryService.findCurryCode(supplierCode);
        return supplierPurchaseCategory == null ? "" : supplierPurchaseCategory.getCurrencyCode();
    }

    @Override
    public void updateReportFlag(String ids) {
        final List<String> idArr = StrUtil.split(ids, ",");
        if (CollUtil.isNotEmpty(idArr)) {
            supplierPurchaseCategoryService.update(new LambdaUpdateWrapper<>(SupplierPurchaseCategory.class)
                    .set(SupplierPurchaseCategory::getReportFlag, FlagConst.N.getCode())
                    .in(SupplierPurchaseCategory::getId, idArr));
        }
    }

    @Override
    public void updateSqeReject(String ids, String remark) {
        final List<String> idArr = StrUtil.split(ids, ",");
        if (CollUtil.isNotEmpty(idArr)) {
            supplierPurchaseCategoryService.update(new LambdaUpdateWrapper<>(SupplierPurchaseCategory.class)
                    .set(SupplierPurchaseCategory::getReportFlag, FlagConst.R.getCode())
                    .set(SupplierPurchaseCategory::getRemark,remark)
                    .in(SupplierPurchaseCategory::getId, idArr));
        }
    }

    @Override
    public List<SupplierPurchaseCategoryBaseDTO> getCompanyCategoryAndSupplierIds(String companyCode,
                                                                                  String purchaseOrgCode,
                                                                                  String supplierIds)
    {
        final List<String> supplierIdArray = StrUtil.split(supplierIds, StrUtil.COMMA);
        if (CollUtil.isEmpty(supplierIdArray)) {
            return Collections.emptyList();
        }
        final List<SupplierPurchaseCategory> list = supplierPurchaseCategoryService.list(
                new LambdaQueryWrapper<>(SupplierPurchaseCategory.class)
                        .eq(SupplierPurchaseCategory::getCompanyCode, companyCode)
                        .eq(SupplierPurchaseCategory::getPurchaseCategoryCode, purchaseOrgCode)
                        .in(SupplierPurchaseCategory::getSupplierId, supplierIdArray)
                        .groupBy(SupplierPurchaseCategory::getSupplierId));
        return supplierPurchaseCategoryConvert.entities2Dtos(list);
    }

    @Override
    public SupplierPurchaseCategoryBaseDTO getCompanyAndSupplierCode(String companyCode, String supplierCode) {
        Supplier supplier = supplierService.getOne(Wrappers.lambdaQuery(Supplier.class).eq(Supplier::getSupplierCode, supplierCode).last("limit 1"));
        if (ObjectUtil.isEmpty(supplier)) {
            return null;
        }
        final SupplierPurchaseCategory supplierPurchaseCategory = supplierPurchaseCategoryService.getOne(
                new LambdaQueryWrapper<>(SupplierPurchaseCategory.class)
                        .eq(SupplierPurchaseCategory::getCompanyCode, companyCode)
                        .eq(SupplierPurchaseCategory::getSupplierId, supplier.getId()).last("limit 1"));
        return supplierPurchaseCategoryConvert.entities2Dto(supplierPurchaseCategory);
    }

    @Override
    public List<SupplierReportDTO> findForSupplierReportExport(SupplierPurchaseCategoryBaseQuery query) {
        return supplierConvert.convert1(this.supplierService.findForSupplierReportExport(query));
    }


}