package com.engine.salary.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.biz.SalarySobBiz;
import com.engine.salary.biz.SalaryTemplateBiz;
import com.engine.salary.config.SalaryElogConfig;
import com.engine.hrmelog.entity.dto.LoggerContext;
import com.engine.salary.entity.salaryBill.bo.SalaryTemplateBO;
import com.engine.salary.entity.salaryBill.dto.SalaryTemplateListDTO;
import com.engine.salary.entity.salaryBill.dto.SalaryTemplateSalaryItemListDTO;
import com.engine.salary.entity.salaryBill.dto.SalaryTemplateSalaryItemSetListDTO;
import com.engine.salary.entity.salaryBill.param.SalaryTemplateCopyParam;
import com.engine.salary.entity.salaryBill.param.SalaryTemplateDefaultUseParam;
import com.engine.salary.entity.salaryBill.param.SalaryTemplateQueryParam;
import com.engine.salary.entity.salaryBill.param.SalaryTemplateSaveParam;
import com.engine.salary.entity.salaryBill.po.SalaryBillItemNamePO;
import com.engine.salary.entity.salaryBill.po.SalaryTemplatePO;
import com.engine.salary.entity.salarysob.dto.SalarySobItemAggregateDTO;
import com.engine.salary.entity.salarysob.dto.SalarySobItemDTO;
import com.engine.salary.entity.salarysob.dto.SalarySobItemGroupDTO;
import com.engine.salary.entity.salarysob.po.SalarySobEmpFieldPO;
import com.engine.salary.entity.salarysob.po.SalarySobItemHidePO;
import com.engine.salary.entity.salarysob.po.SalarySobItemPO;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
import com.engine.salary.enums.OperateTypeEnum;
import com.engine.salary.enums.salarybill.SalaryTemplateWhetherEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.salarysob.SalarySobEmpFieldMapper;
import com.engine.salary.report.entity.po.SalaryStatisticsReportPO;
import com.engine.salary.service.*;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.IdGenerator;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.mzlion.core.utils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import weaver.hrm.User;

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

/**
 * @Description: 工资单模板
 * @Author: wangxiangzhong
 * @Date: 2021-12-08 14:44
 */
public class SalaryTemplateServiceImpl extends Service implements SalaryTemplateService {

    private SalaryTemplateBiz mapper = new SalaryTemplateBiz();

    private SalarySobBiz salarySobMapper = new SalarySobBiz();

    private SalarySobItemService getSalarySobItemService(User user) {
        return ServiceUtil.getService(SalarySobItemServiceImpl.class, user);
    }

    private SalarySobService getSalarySobService(User user) {
        return ServiceUtil.getService(SalarySobServiceImpl.class, user);
    }

    private TaxAgentService getTaxAgentService(User user) {
        return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
    }

    private SalarySobItemHideService getSalarySobItemHideService(User user) {
        return ServiceUtil.getService(SalarySobItemHideServiceImpl.class, user);
    }

    private SalaryBillItemNameService getSalaryBillItemNameService(User user) {
        return ServiceUtil.getService(SalaryBillItemNameServiceImpl.class, user);
    }

    private SalarySobEmpFieldService getSalarySobEmpFieldService(User user) {
        return (SalarySobEmpFieldService) ServiceUtil.getService(SalarySobEmpFieldServiceImpl.class, user);
    }

    private SalarySobEmpFieldMapper getSalarySobEmpFieldMapper() {
        return MapperProxyFactory.getProxy(SalarySobEmpFieldMapper.class);
    }

    @Override
    public SalaryTemplatePO getById(Long id) {
        return mapper.getById(id);
    }

//    @Override
//    public Map<String, Object> listPage(SalaryTemplateQueryParam queryParam) {
//        mapper.list(queryParam);
//        return page;
//    }

    @Override
    public String defaultUse(SalaryTemplateDefaultUseParam defaultUseParamy) {
        // 校验参数
        SalaryTemplateDefaultUseParam.checkParam(defaultUseParamy);

        SalaryTemplatePO salaryTemplate = getById(defaultUseParamy.getId());

        if (salaryTemplate == null) {
            throw new SalaryRunTimeException("工资单模板不存在");
        }

        // 选中默认使用
        SalaryTemplatePO po = new SalaryTemplatePO();
        po.setDeleteType(0);
        po.setSalarySobId(salaryTemplate.getSalarySobId());
        po.setUseType(SalaryTemplateWhetherEnum.FALSE.getValue());
        mapper.updateBySalarySobId(po);

        SalaryTemplatePO salaryTemplateNew = new SalaryTemplatePO();
        BeanUtils.copyProperties(salaryTemplate, salaryTemplateNew);
        salaryTemplateNew.setUseType(SalaryTemplateWhetherEnum.TRUE.getValue());
        mapper.updateById(salaryTemplateNew);

        // 记录日志
        LoggerContext<SalaryStatisticsReportPO> loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId(String.valueOf(salaryTemplateNew.getId()));
        loggerContext.setTargetName(salaryTemplateNew.getName());
        loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "设为默认使用"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel( 0, "设为默认使用"));
        SalaryElogConfig.salaryTemplateLoggerTemplate.write(loggerContext);
        return "";
    }

    @Override
    public String save(SalaryTemplateSaveParam saveParam) {
        // 校验参数
        SalaryTemplateSaveParam.checkParam(saveParam);

        SalaryTemplatePO po = new SalaryTemplatePO();
        po.setDeleteType(0);
        po.setName(saveParam.getName());
        List<SalaryTemplatePO> salaryTemplates = mapper.listSome(po);

        if (CollectionUtils.isNotEmpty(salaryTemplates)) {
            throw new SalaryRunTimeException("工资单模板名称不允许重复");
        }

        SalarySobPO salarySobPO = new SalarySobPO();
        po.setDeleteType(0);
        po.setId(saveParam.getSalarySobId());
        List<SalarySobPO> salarySobs = salarySobMapper.listSome(salarySobPO);

        if (CollectionUtils.isEmpty(salarySobs)) {
            throw new SalaryRunTimeException("薪资账套不存在");
        }
        // todo 薪资项目设置检查校验
        // 保存
        SalaryTemplatePO salaryTemplate = SalaryTemplateBO.convertToPO(saveParam, (long) user.getUID());
//        salaryTemplate.setSendEmailId(saveParam.getSendEmail());
        salaryTemplate.setEmailStatus(saveParam.getEmailStatus() ? 1 : 0);
        salaryTemplate.setMsgStatus(saveParam.getMsgStatus() ? 1 : 0);
        salaryTemplate.setSmsStatus(saveParam.getSmsStatus() != null && saveParam.getSmsStatus() ? 1 : 0);
        salaryTemplate.setSmsSetting(saveParam.getSmsSetting() == null ? "" : JSON.toJSONString(saveParam.getSmsSetting()));
        salaryTemplate.setTextContentPosition(saveParam.getTextContentPosition());
        salaryTemplate.setSalaryItemNullStatus(saveParam.getSalaryItemNullStatus() ? 1 : 0);
        salaryTemplate.setSalaryItemZeroStatus(saveParam.getSalaryItemZeroStatus() ? 1 : 0);
        salaryTemplate.setAutoSendCycleType(saveParam.getAutoSendCycleType());
        mapper.insert(salaryTemplate);

        // 存储工资单项目自定义名称信息
        saveParam.getSalaryBillItemNameSetting().stream().forEach(set -> set.setSalaryTemplateId(salaryTemplate.getId()));
        getSalaryBillItemNameService(user).saveItemShowName(saveParam.getSalaryBillItemNameSetting());
        // 记录日志
        LoggerContext<SalaryStatisticsReportPO> loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId(String.valueOf(salaryTemplate.getId()));
        loggerContext.setTargetName(salaryTemplate.getName());
        loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "新增工资单模板"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel( 0, "新增工资单模板"));
        loggerContext.setNewValues(salaryTemplate);
        SalaryElogConfig.salaryTemplateLoggerTemplate.write(loggerContext);

        return "";
    }

    @Override
    public String update(SalaryTemplateSaveParam saveParam) {
        // 校验参数
        SalaryTemplateSaveParam.checkParam(saveParam);
        // 校验是否可以编辑
        if (saveParam.getId() == null) {
            throw new SalaryRunTimeException("参数错误");
        }
        SalaryTemplatePO salaryTemplate = getById(saveParam.getId());
        if (salaryTemplate == null) {
            throw new SalaryRunTimeException("工资单模板不存在");
        }

        // 工资单模板编辑时不允许调整账套
        if (!salaryTemplate.getSalarySobId().equals(saveParam.getSalarySobId())) {
            throw new SalaryRunTimeException("工资单模板编辑时不允许调整账套");
        }

        SalaryTemplatePO po = new SalaryTemplatePO();
        po.setDeleteType(0);
        po.setName(saveParam.getName());
        List<SalaryTemplatePO> salaryTemplates = mapper.listSome(po);

        boolean nameExist = salaryTemplates.stream().anyMatch(e -> !Objects.equals(e.getId(), saveParam.getId()));
        if (nameExist) {
            throw new SalaryRunTimeException("工资单模板名称不允许重复");
        }
        SalarySobPO salarySobPO = new SalarySobPO();
        po.setDeleteType(0);
        po.setId(saveParam.getSalarySobId());
        List<SalarySobPO> salarySobs = salarySobMapper.listSome(salarySobPO);

        if (CollectionUtils.isEmpty(salarySobs)) {
            throw new SalaryRunTimeException("薪资账套不存在");
        }
        // 更新工资单
        SalaryTemplatePO salaryTemplateNew = new SalaryTemplatePO();
        BeanUtils.copyProperties(salaryTemplate, salaryTemplateNew);
        BeanUtils.copyProperties(saveParam, salaryTemplateNew);
        salaryTemplateNew.setUpdateTime(new Date());
        salaryTemplateNew.setSendEmailId(0L);
        salaryTemplateNew.setEmailStatus(saveParam.getEmailStatus() ? 1 : 0);
        salaryTemplateNew.setMsgStatus(saveParam.getMsgStatus() ? 1 : 0);
        salaryTemplateNew.setSmsStatus(saveParam.getSmsStatus() != null && saveParam.getSmsStatus() ? 1 : 0);
        salaryTemplateNew.setSmsSetting(saveParam.getSmsSetting() == null ? "" : JSON.toJSONString(saveParam.getSmsSetting()));
        salaryTemplateNew.setTextContentPosition(saveParam.getTextContentPosition());
        salaryTemplateNew.setSalaryItemNullStatus(saveParam.getSalaryItemNullStatus() ? 1 : 0);
        salaryTemplateNew.setSalaryItemZeroStatus(saveParam.getSalaryItemZeroStatus() ? 1 : 0);
        salaryTemplateNew.setAutoSendStatus(saveParam.getAutoSendStatus() ? 1 : 0);
        salaryTemplateNew.setAutoSendCycleType(saveParam.getAutoSendCycleType());
        salaryTemplateNew.setAckFeedbackStatus(saveParam.getAckFeedbackStatus() ? 1 : 0);
        salaryTemplateNew.setFeedbackStatus(saveParam.getFeedbackStatus() ? 1 : 0);
        salaryTemplateNew.setAutoAckDays(saveParam.getAutoAckDays());
        salaryTemplateNew.setFeedbackUrl(saveParam.getFeedbackUrl());
        salaryTemplateNew.setMobileFeedbackUrl(saveParam.getMobileFeedbackUrl());
        // todo 薪资项目设置检查校验
        salaryTemplateNew.setSalaryItemSetting(saveParam.getSalaryItemSetting() != null ? JSONUtil.toJsonStr(saveParam.getSalaryItemSetting()) : "");
        salaryTemplateNew.setReplenishSalaryItemSetting(saveParam.getReplenishSalaryItemSetting() != null ? JSONUtil.toJsonStr(saveParam.getReplenishSalaryItemSetting()) : "");
        mapper.updateById(salaryTemplateNew);

        // 保存自定义工资单项目名称信息
        getSalaryBillItemNameService(user).saveItemShowName(saveParam.getSalaryBillItemNameSetting());
        // 模板中没有的薪资项目需要同步删除显示名称表
        List<SalaryBillItemNamePO> billItemNameList = getSalaryBillItemNameService(user).ListByTemplateAndType(SalaryBillItemNamePO.builder().salaryTemplateId(saveParam.getId()).build());
        Map<Integer, List<SalaryBillItemNamePO>> billItemNameMap = SalaryEntityUtil.group2Map(billItemNameList, SalaryBillItemNamePO::getSalaryBillType);
        List<SalaryTemplateSalaryItemListDTO> saveItemList = saveParam.getSalaryItemSetting().stream().map(SalaryTemplateSalaryItemSetListDTO::getItems).flatMap(Collection::stream).collect(Collectors.toList());
        Set<String> saveItemIdList = SalaryEntityUtil.properties(saveItemList, SalaryTemplateSalaryItemListDTO::getSalaryItemId);
        // 正常工资单模板中删除的薪资项目
        List<Long> needDeleteIds = billItemNameMap.getOrDefault(NumberUtils.INTEGER_ZERO, Collections.emptyList()).stream().filter(salaryBillItemNamepo -> !saveItemIdList.contains(salaryBillItemNamepo.getSalaryItemId().toString()))
                .map(SalaryBillItemNamePO::getId).collect(Collectors.toList());
        // 补发工资单模板中删除的薪资项目
        List<SalaryTemplateSalaryItemListDTO> replenishItemList = saveParam.getReplenishSalaryItemSetting().stream().map(SalaryTemplateSalaryItemSetListDTO::getItems).flatMap(Collection::stream).collect(Collectors.toList());
        Set<String> saveReplenishItemIdList = SalaryEntityUtil.properties(replenishItemList, SalaryTemplateSalaryItemListDTO::getSalaryItemId);
        needDeleteIds.addAll(billItemNameMap.getOrDefault(NumberUtils.INTEGER_ONE, Collections.emptyList()).stream().filter(salaryBillItemNamepo -> !saveReplenishItemIdList.contains(salaryBillItemNamepo.getSalaryItemId().toString()))
                .map(SalaryBillItemNamePO::getId).collect(Collectors.toList()));
        getSalaryBillItemNameService(user).deleteByIds(needDeleteIds);

        // 记录日志
        LoggerContext<SalaryTemplatePO> loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId(String.valueOf(salaryTemplateNew.getId()));
        loggerContext.setTargetName(salaryTemplateNew.getName());
        loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "编辑工资单模板"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel( 0, "编辑工资单模板"));
        loggerContext.setOldValues(salaryTemplate);
        loggerContext.setNewValues(salaryTemplateNew);
        SalaryElogConfig.salaryTemplateLoggerTemplate.write(loggerContext);

        return "";
    }

    @Override
    public String copy(SalaryTemplateCopyParam copyParam) {
        // 校验参数
        SalaryTemplateCopyParam.checkParam(copyParam);

        SalaryTemplatePO salaryTemplate = getById(copyParam.getId());
        if (salaryTemplate == null) {
            throw new SalaryRunTimeException("被复制的工资单不存在");
        }

        List<SalaryTemplateListDTO> salaryTemplates = mapper.list(SalaryTemplateQueryParam.builder().name(copyParam.getName()).build());

        if (CollectionUtils.isNotEmpty(salaryTemplates)) {
            throw new SalaryRunTimeException("工资单模板名称不允许重复");
        }

        SalaryTemplatePO salaryTemplateNew = new SalaryTemplatePO();
        BeanUtils.copyProperties(salaryTemplate, salaryTemplateNew);
        salaryTemplateNew.setId(null);
        salaryTemplateNew.setName(copyParam.getName());
        salaryTemplateNew.setReplenishName(copyParam.getName() + "-" + SalaryI18nUtil.getI18nLabel(0, "补发工资单"));
        salaryTemplateNew.setUseType(SalaryTemplateWhetherEnum.FALSE.getValue());

        //20240122逻辑变更，拷贝工资单模板时，可变更薪资账套
        if (copyParam.getSalarySobId() != null && !copyParam.getSalarySobId().equals(salaryTemplate.getSalarySobId())) {
            // 查询薪资账套的员工信息字段
            List<SalarySobEmpFieldPO> salarySobEmpFieldPOS = getSalarySobEmpFieldService(user).listBySalarySobId(copyParam.getSalarySobId());
            List<String> empFieldCodeList = salarySobEmpFieldPOS.stream().map(SalarySobEmpFieldPO::getFieldCode).collect(Collectors.toList());
            Map<String, Long> empFieldCodeWithIdMap = SalaryEntityUtil.convert2Map(salarySobEmpFieldPOS, SalarySobEmpFieldPO::getFieldCode, SalarySobEmpFieldPO::getId);
            // 查询薪资账套的薪资项目副本
            List<SalarySobItemPO> salarySobItemPOS = getSalarySobItemService(user).listBySalarySobIdWithHideItem(copyParam.getSalarySobId());
            List<Long> salaryItemIdList = salarySobItemPOS.stream().map(SalarySobItemPO::getSalaryItemId).collect(Collectors.toList());
            //拷贝数据中的薪资项目
            List<SalaryTemplateSalaryItemSetListDTO> salaryItemSettingList = StrUtil.isNotBlank(salaryTemplate.getSalaryItemSetting())
                    ? JSONArray.parseArray(salaryTemplate.getSalaryItemSetting(), SalaryTemplateSalaryItemSetListDTO.class) : new ArrayList<>();
            for (SalaryTemplateSalaryItemSetListDTO salaryItemSetting : salaryItemSettingList) {
                if ("111111111111111111".equals(salaryItemSetting.getGroupId()) && salaryItemSetting.getItems() != null) {
                    List<SalaryTemplateSalaryItemListDTO> newItems = new ArrayList<>();
                    for (SalaryTemplateSalaryItemListDTO templateItem : salaryItemSetting.getItems()) {
                        SalarySobEmpFieldPO empFieldPO = getSalarySobEmpFieldMapper().getById(Long.valueOf(templateItem.getSalaryItemId()));
                        if (empFieldCodeList.contains(empFieldPO.getFieldCode()) && empFieldCodeWithIdMap.get(empFieldPO.getFieldCode()) != null) {
                            templateItem.setId(empFieldCodeWithIdMap.get(empFieldPO.getFieldCode()).toString());
                            templateItem.setSalaryItemId(empFieldCodeWithIdMap.get(empFieldPO.getFieldCode()).toString());
                            newItems.add(templateItem);
                        }
                    }
                    salaryItemSetting.setItems(newItems);
                } else if (salaryItemSetting.getItems() != null){
                    List<SalaryTemplateSalaryItemListDTO> newItems = new ArrayList<>();
                    for (SalaryTemplateSalaryItemListDTO templateItem : salaryItemSetting.getItems()) {
                        if (salaryItemIdList.contains(Long.valueOf(templateItem.getSalaryItemId()))) {
                            newItems.add(templateItem);
                        }
                    }
                    salaryItemSetting.setItems(newItems);
                }
            }
            List<SalaryTemplateSalaryItemSetListDTO> replenishSalaryItemSettingList = StrUtil.isNotBlank(salaryTemplate.getReplenishSalaryItemSetting())
                    ? JSONArray.parseArray(salaryTemplate.getReplenishSalaryItemSetting(), SalaryTemplateSalaryItemSetListDTO.class): new ArrayList<>();
            for (SalaryTemplateSalaryItemSetListDTO salaryItemSetting : replenishSalaryItemSettingList) {
                if ("111111111111111111".equals(salaryItemSetting.getGroupId()) && salaryItemSetting.getItems() != null) {
                    List<SalaryTemplateSalaryItemListDTO> newItems = new ArrayList<>();
                    for (SalaryTemplateSalaryItemListDTO templateItem : salaryItemSetting.getItems()) {
                        SalarySobEmpFieldPO empFieldPO = getSalarySobEmpFieldMapper().getById(Long.valueOf(templateItem.getSalaryItemId()));
                        if (empFieldCodeList.contains(empFieldPO.getFieldCode()) && empFieldCodeWithIdMap.get(empFieldPO.getFieldCode()) != null) {
                            templateItem.setId(empFieldCodeWithIdMap.get(empFieldPO.getFieldCode()).toString());
                            templateItem.setSalaryItemId(empFieldCodeWithIdMap.get(empFieldPO.getFieldCode()).toString());
                            newItems.add(templateItem);
                        }
                    }
                    salaryItemSetting.setItems(newItems);
                } else if (!"333333333333333333".equals(salaryItemSetting.getGroupId()) && salaryItemSetting.getItems() != null){
                    List<SalaryTemplateSalaryItemListDTO> newItems = new ArrayList<>();
                    for (SalaryTemplateSalaryItemListDTO templateItem : salaryItemSetting.getItems()) {
                        if (salaryItemIdList.contains(Long.valueOf(templateItem.getSalaryItemId()))) {
                            newItems.add(templateItem);
                        }
                    }
                    salaryItemSetting.setItems(newItems);
                }
            }
            salaryTemplateNew.setSalaryItemSetting(salaryItemSettingList.size() > 0 ? JSONUtil.toJsonStr(salaryItemSettingList) : "");
            salaryTemplateNew.setReplenishSalaryItemSetting(replenishSalaryItemSettingList.size() > 0 ? JSONUtil.toJsonStr(replenishSalaryItemSettingList) : "");
            salaryTemplateNew.setSalarySobId(copyParam.getSalarySobId());
        }

        mapper.insert(salaryTemplateNew);

        // 复制工资单自定义名称信息
        List<SalaryBillItemNamePO> billItemNamePOList = getSalaryBillItemNameService(user).ListByTemplateAndType(SalaryBillItemNamePO.builder().salaryTemplateId(copyParam.getId()).build());
        if (CollectionUtils.isNotEmpty(billItemNamePOList)) {
            Date now = new Date();
            List<SalaryBillItemNamePO> needInsertList = billItemNamePOList.stream().map(po -> {
                SalaryBillItemNamePO newSalaryBillItemNamePO = new SalaryBillItemNamePO();
                BeanUtils.copyProperties(po, newSalaryBillItemNamePO);
                newSalaryBillItemNamePO.setId(IdGenerator.generate());
                newSalaryBillItemNamePO.setUpdateTime(now);
                newSalaryBillItemNamePO.setSalaryTemplateId(salaryTemplateNew.getId());
                return newSalaryBillItemNamePO;
            }).collect(Collectors.toList());
            getSalaryBillItemNameService(user).batchInsert(needInsertList);
        }
        // 记录日志
        LoggerContext<SalaryStatisticsReportPO> loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId(String.valueOf(salaryTemplateNew.getId()));
        loggerContext.setTargetName(salaryTemplateNew.getName());
        loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "复制工资单模板"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel( 0, "复制工资单模板"));
        loggerContext.setNewValues(salaryTemplateNew);
        SalaryElogConfig.salaryTemplateLoggerTemplate.write(loggerContext);

        return "";
    }

    @Override
    public String delete(Collection<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new SalaryRunTimeException("参数错误");
        }
        List<SalaryTemplateListDTO> salaryTemplates = mapper.list(SalaryTemplateQueryParam.builder().ids(ids).build());
        if (CollectionUtils.isEmpty(salaryTemplates)) {
            throw new SalaryRunTimeException("要删除的工资单在不存在或已删除");
        }
        // TODO 正在使用的记录不允许删除
        mapper.deleteByIds(ids);
        // 删除工资单重命名表
        getSalaryBillItemNameService(user).deleteByTemplateIds(ids);
        // 记录日志
        salaryTemplates.stream().forEach(template -> {
            LoggerContext<SalaryStatisticsReportPO> loggerContext = new LoggerContext<>();
            loggerContext.setUser(user);
            loggerContext.setTargetId(String.valueOf(template.getId()));
            loggerContext.setTargetName(template.getName() + ":" + template.getId());
            loggerContext.setOperateType(OperateTypeEnum.DELETE.getValue());
            loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "删除工资单模板"));
            loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel( 0, "删除工资单模板"));
            SalaryElogConfig.salaryTemplateLoggerTemplate.write(loggerContext);
        });
        return "";
    }

    @Override
    public List<Map<String, Object>> selectSalarySobList() {
        List<SalarySobPO> salarySobs = getSalarySobService(user).listByDisable(NumberUtils.INTEGER_ZERO);

        return salarySobs.stream().map(m -> {
            Map<String, Object> map = new HashMap<>(2);
            map.put("id", String.valueOf(m.getId()));
            map.put("content", m.getName());
            return map;
        }).collect(Collectors.toList());
    }

    @Override
    public List<SalaryTemplateSalaryItemSetListDTO> getSalaryItemSet(Long salarySobId, boolean isReplenish) {
        SalarySobItemAggregateDTO salarySobItemAggregate = getSalarySobItemService(user).getAggregateBySalarySobId(salarySobId);
        // 处理薪资账套中隐藏的分类和项目
        // 获取关闭显示的分类
        List<Long> hideGroupIDs = getSalarySobItemHideService(user).listHideGroupBysalarySobId(SalarySobItemHidePO.builder().salarySobId(salarySobId).isGroup(1).build());
        // 过滤关闭显示的薪资项目分类
        List<SalarySobItemGroupDTO> itemGroupDTOS = salarySobItemAggregate.getItemGroups().stream().filter(group -> !(hideGroupIDs.contains(group.getId()))).collect(Collectors.toList());
        // 获取关闭显示的薪资项目
        List<Long> hideItemIDs = getSalarySobItemHideService(user).listHideGroupBysalarySobId(SalarySobItemHidePO.builder().salarySobId(salarySobId).isGroup(0).build());
        for (SalarySobItemGroupDTO DTO : itemGroupDTOS) {
            List<SalarySobItemDTO> items = DTO.getItems();
            DTO.setItems(items.stream().filter(item -> !(hideItemIDs.contains(item.getSalaryItemId()))).collect(Collectors.toList()));
        }
        itemGroupDTOS = itemGroupDTOS.stream().filter(DTO -> CollectionUtils.isNotEmpty(DTO.getItems())).collect(Collectors.toList());
        salarySobItemAggregate.setItemGroups(itemGroupDTOS);
        if (hideGroupIDs.contains(0L)) {
            // 隐藏了未分类
            salarySobItemAggregate.setItems(Collections.emptyList());
        } else {
            salarySobItemAggregate.setItems(salarySobItemAggregate.getItems().stream().filter(item -> !(hideItemIDs.contains(item.getSalaryItemId()))).collect(Collectors.toList()));
        }
        return SalaryTemplateBO.convertSalarySobItemAggregateToSalaryItemSet(salarySobItemAggregate, new Long(user.getUID()), isReplenish);
    }

    @Override
    public List<SalaryTemplateSalaryItemSetListDTO> getSalaryItemSetContainHide(Long salarySobId, Long salaryTemplateId, boolean isReplenish) {
        SalarySobItemAggregateDTO salarySobItemAggregate = getSalarySobItemService(user).getAggregateBySalarySobId(salarySobId);
        // 获取工资单薪资项目展示名信息
        List<SalaryBillItemNamePO> billItemNameList = Collections.emptyList();
        if (salaryTemplateId != null) {
            billItemNameList = getSalaryBillItemNameService(user).ListByTemplateAndType(
                    SalaryBillItemNamePO.builder().salaryTemplateId(salaryTemplateId)
                            .salaryBillType(isReplenish ? 1 : 0)
                            .build());
        }

        Map<Long, String> itemShowNameMap = SalaryEntityUtil.convert2Map(billItemNameList, SalaryBillItemNamePO::getSalaryItemId, SalaryBillItemNamePO::getSalaryItemShowName);

        List<SalaryTemplateSalaryItemSetListDTO> salaryTemplateSalaryItemSetListDTOS = SalaryTemplateBO.convertSalarySobItemAggregateToSalaryItemSet(salarySobItemAggregate, new Long(user.getUID()), isReplenish);
        salaryTemplateSalaryItemSetListDTOS.stream()
                .filter(data -> !StringUtils.equals(data.getGroupId(), "111111111111111111"))
                .forEach(data -> {
                    data.getItems().forEach(item -> {
                        Long salaryItemId = Long.valueOf(item.getSalaryItemId());
                        if (itemShowNameMap.containsKey(salaryItemId)) {
                            item.setSalaryItemShowName(itemShowNameMap.get(salaryItemId));
                            item.setName(itemShowNameMap.get(salaryItemId) + "（" + item.getOriginName() + "）");
                        } else {
                            item.setSalaryItemShowName(item.getOriginName());
                            item.setName(item.getOriginName());
                        }
                    });
                });
        return salaryTemplateSalaryItemSetListDTOS;
    }

    @Override
    public List<SalaryTemplatePO> getDefaultTemplates(List<Long> salarySobIds) {
        return mapper.listDefaultTemplates(salarySobIds);
    }

    @Override
    public List<SalaryTemplatePO> getBySalarySobIds(Collection<Long> ids) {
        return mapper.listSome(SalaryTemplatePO.builder().salarySobIds(ids).build());
    }

    @Override
    public PageInfo<SalaryTemplateListDTO> listPage(SalaryTemplateQueryParam queryParam) {
        List<SalaryTemplateListDTO> salaryTemplateDTOList = Collections.emptyList();
        // 分权
        long currentEmployeeId = user.getUID();
        Boolean needAuth = getTaxAgentService(user).isNeedAuth(currentEmployeeId);
        if (needAuth) {
            List<SalarySobPO> salarySobPOS = getSalarySobService(user).listByDisable(NumberUtils.INTEGER_ZERO);
            Set<Long> salarySobIds = SalaryEntityUtil.properties(salarySobPOS, SalarySobPO::getId);
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(salarySobIds)) {
                // 查询
                salaryTemplateDTOList = mapper.listDTO(SalaryTemplatePO.builder()
                        .salarySobId(queryParam.getSalarySobId())
                        .name(queryParam.getName())
                        .salarySobIds(salarySobIds).build());
            } else {
                return SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), salaryTemplateDTOList, SalaryTemplateListDTO.class);
            }
        } else {
            // 查询
            salaryTemplateDTOList = mapper.listDTO(SalaryTemplatePO.builder().salarySobId(queryParam.getSalarySobId()).name(queryParam.getName()).build());
        }

        // 分页参数
        PageInfo<SalaryTemplateListDTO> page = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), salaryTemplateDTOList, SalaryTemplateListDTO.class);
        return page;
    }

    @Override
    public List<SalaryTemplatePO> getAutoSendTemplate() {
        return mapper.listSome(SalaryTemplatePO.builder().autoSendStatus(NumberUtils.INTEGER_ONE).useType(NumberUtils.INTEGER_ONE).deleteType(NumberUtils.INTEGER_ZERO).build());
    }

    @Override
    public List<SalaryTemplatePO> listNeedAckDefaultTemplate() {
        return mapper.listSome(SalaryTemplatePO.builder().useType(NumberUtils.INTEGER_ONE).ackFeedbackStatus(NumberUtils.INTEGER_ONE).build());
    }
}
