package com.engine.salary.wrapper;

import cn.hutool.core.util.ObjectUtil;
import com.api.browser.bean.SearchConditionGroup;
import com.api.browser.bean.SearchConditionItem;
import com.api.browser.bean.SearchConditionOption;
import com.api.browser.util.ConditionFactory;
import com.api.browser.util.ConditionType;
import com.cloudstore.eccom.constant.WeaBoolAttr;
import com.cloudstore.eccom.pc.table.WeaTable;
import com.cloudstore.eccom.pc.table.WeaTableCheckboxpopedom;
import com.cloudstore.eccom.pc.table.WeaTableColumn;
import com.cloudstore.eccom.result.WeaResultMsg;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.constant.SalaryItemConstant;
import com.engine.salary.entity.salaryBill.dto.*;
import com.engine.salary.entity.salaryBill.param.*;
import com.engine.salary.entity.salaryBill.po.SalarySendPO;
import com.engine.salary.entity.salaryBill.po.SalaryTemplatePO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
import com.engine.salary.entity.taxagent.dto.TaxAgentListDTO;
import com.engine.salary.enums.UserStatusEnum;
import com.engine.salary.enums.salarybill.SalarySendStatusEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.salarybill.SalarySendMapper;
import com.engine.salary.service.*;
import com.engine.salary.service.impl.*;
import com.engine.salary.sys.constant.SalarySysConstant;
import com.engine.salary.sys.entity.po.SalarySysConfPO;
import com.engine.salary.sys.enums.PayrollCheckTypeEnum;
import com.engine.salary.sys.service.SalarySysConfService;
import com.engine.salary.sys.service.impl.SalarySysConfServiceImpl;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.SalaryTokenUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.engine.salary.wrapper.proxy.SalarySendWrapperProxy;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import weaver.conn.mybatis.MyBatisFactory;
import weaver.hrm.User;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 工资单发放
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class SalarySendWrapper extends Service implements SalarySendWrapperProxy {
    private TaxAgentService getTaxAgentService(User user) {
        return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
    }

    private SalarySendService getSalarySendService(User user) {
        return ServiceUtil.getService(SalarySendServiceImpl.class, user);
    }

    private SalaryBillService getSalaryBillService(User user) {
        return ServiceUtil.getService(SalaryBillServiceImpl.class, user);
    }

    private SalaryTemplateService getSalaryTemplateService(User user) {
        return ServiceUtil.getService(SalaryTemplateServiceImpl.class, user);
    }

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

    private SalaryAcctRecordService getSalaryAcctRecordService(User user) {
        return ServiceUtil.getService(SalaryAcctRecordServiceImpl.class, user);
    }

    private ExtEmpService getExtEmpService(User user) {
        return ServiceUtil.getService(ExtEmpServiceImpl.class, user);
    }

    private SalarySysConfService getSalarySysConfService(User user) {
        return ServiceUtil.getService(SalarySysConfServiceImpl.class, user);
    }


    /**
     * 工资单发放列表
     *
     * @param queryParam
     * @return
     */
    public Map<String, Object> list(SalarySendQueryParam queryParam) {

        // 处理工资单发放历史数据
        getSalarySendService(user).handleHistory();

        long currentEmployeeId = user.getUID();

        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        Map<String, Object> datas = new HashMap<>(16);
        try {
            queryParam.setSalaryMonth(queryParam.getSalaryYearMonth().stream().map(e -> e + "-01 00:00:00").collect(Collectors.toList()));
            queryParam.setSalaryMonthDate(queryParam.getSalaryYearMonth().stream().map(e -> e + "-01 00:00:00").map(SalaryDateUtil::dateStrToLocalTime).collect(Collectors.toList()));
            //分权，获取当前人员管理的账套
            Boolean needAuth = getTaxAgentService(user).isNeedAuth(currentEmployeeId);
            List<SalarySendListDTO> list = new ArrayList<>();
            if (needAuth) {
                List<SalarySobPO> salarySobPOS = getSalarySobService(user).listByDisable(NumberUtils.INTEGER_ZERO);
                Set<Long> salarySobIds = SalaryEntityUtil.properties(salarySobPOS, SalarySobPO::getId);
                if (CollectionUtils.isNotEmpty(salarySobIds)) {
                    queryParam.setSalarySobIds(salarySobIds);
                    SalarySendMapper salarySendMapper = sqlSession.getMapper(SalarySendMapper.class);
                    list = salarySendMapper.list(queryParam);
                }
            } else {
                SalarySendMapper salarySendMapper = sqlSession.getMapper(SalarySendMapper.class);
                list = salarySendMapper.list(queryParam);
            }

            list.stream().forEach(dto -> {
                // 回算过，但是查看的是普通工资单（不能查看详情）;回算过，但是查看的是回算工资单（可以发）；记录没回算过（可以发）
                if(Objects.equals(dto.getSalaryAcctRecordType(), NumberUtils.INTEGER_ONE) &&  Objects.equals(dto.getSalaryAcctType(),NumberUtils.INTEGER_ZERO)){
                    dto.setCanSeeDetail(false);
                }else{
                    dto.setCanSeeDetail(true);
                }
            });

            PageInfo<SalarySendListDTO> pageInfo = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(),
                    list, SalarySendListDTO.class);
            List<SalarySendListDTO> pageList = pageInfo.getList();
            List<Long> salarySobIds = pageList.stream().map(SalarySendListDTO::getSalarySobId).distinct().collect(Collectors.toList());
            // 获取默认模板
            if (salarySobIds.size() > 0) {
                List<SalaryTemplatePO> salaryTemplates = getSalaryTemplateService(user).getDefaultTemplates(salarySobIds);
                pageList.forEach(e -> {
                    // 已发放
                    e.setSendSituation(e.getSendNum() + "/" + e.getSendTotal());
                    // 工资单模板
                    Optional<SalaryTemplatePO> optional = salaryTemplates.stream().filter(s -> s.getSalarySobId().equals(e.getSalarySobId())).findFirst();
                    if (optional.isPresent()) {
                        // todo 目前就一个回算，那么没有冻结且是回算，就展示补发名称
                        SalaryTemplatePO salaryTemplatePO = optional.get();
                        e.setTemplate(NumberUtils.INTEGER_ONE.equals(e.getSalaryAcctType()) ? salaryTemplatePO.getReplenishName() : salaryTemplatePO.getName());
                        e.setTemplateId(salaryTemplatePO.getId());
                        if ((salaryTemplatePO.getAckFeedbackStatus() != null && salaryTemplatePO.getAckFeedbackStatus() == 1) ||
                                (salaryTemplatePO.getFeedbackStatus() != null && salaryTemplatePO.getFeedbackStatus() == 1)  ) {
                            e.setAckFeedbackStatus(1);
                        } else {
                            e.setAckFeedbackStatus(0);
                        }
                    }
                });
            }
            List<WeaTableColumn> columns = buildWeaTableColumns();
            WeaTable table = new WeaTable();
            table.setColumns(columns);
            //设置check是否可用
            List<WeaTableCheckboxpopedom> checkboxpopedomList = new ArrayList<>();
            WeaTableCheckboxpopedom checkboxpopedom = new WeaTableCheckboxpopedom();
            checkboxpopedom.setPopedompara("column:system_type");
            checkboxpopedom.setShowmethod("com.engine.salary.transmethod.TaxRateTransMethod.getCheckBoxPopedom");
            checkboxpopedomList.add(checkboxpopedom);
            table.setCheckboxList(checkboxpopedomList);
            table.setCheckboxpopedom(null);

            WeaResultMsg result = new WeaResultMsg(false);
            result.putAll(table.makeDataResult());
            result.success();

            datas.put("pageInfo", pageInfo);
            datas.put("datas", pageList);
            datas.put("columns", columns);
            datas.put("dataKey", result.getResultMap());
            return datas;
        } catch (Exception e) {
            throw new SalaryRunTimeException(e.getMessage());
        } finally {
            sqlSession.close();
        }
    }

    /**
     * 创建表展示字段
     *
     * @return
     */
    private List<WeaTableColumn> buildWeaTableColumns() {
        List<WeaTableColumn> list = new ArrayList<>();
        WeaTableColumn idColumn = new WeaTableColumn("0px", "id", "id");
        idColumn.setDisplay(WeaBoolAttr.FALSE);
        list.add(new WeaTableColumn("10%", "薪资所属月", "salaryYearMonth"));
        list.add(new WeaTableColumn("35%", "薪资账套", "salarySob"));
        list.add(new WeaTableColumn("25%", "次数", "acctTimes"));
        list.add(new WeaTableColumn("25%", "工资单模板", "template"));
        list.add(new WeaTableColumn("15%", "已发放", "sendSituation"));
        list.add(new WeaTableColumn("15%", "最后发送时间", "lastSendTime"));
        return list;
    }

    /**
     * 工资单发放基本信息
     *
     * @param id
     * @return
     */
    public SalarySendBaseInfoDTO getBaseInfo(Long id) {
        return getSalarySendService(user).getBaseInfo(id);
    }

    /**
     * 工资单发放信息列表的高级搜索
     *
     * @return
     */
    public Map<String, Object> getInfoSearchCondition() {
        Map<String, Object> apidatas = new HashMap<String, Object>();
        ConditionFactory conditionFactory = new ConditionFactory(user);

        //条件组
        List<SearchConditionGroup> addGroups = new ArrayList<SearchConditionGroup>();
        List<SearchConditionItem> conditionItems = new ArrayList<SearchConditionItem>();

        //文本输入框
        SearchConditionItem username = conditionFactory.createCondition(ConditionType.INPUT, 25034, "username");
        username.setColSpan(2);//定义一行显示条件数，默认值为2,当值为1时标识该条件单独占一行
        username.setFieldcol(16);    //条件输入框所占宽度，默认值18
        username.setLabelcol(8);
        username.setViewAttr(2);  //	 编辑权限  1：只读，2：可编辑， 3：必填   默认2
        username.setLabel("姓名"); //设置文本值  这个将覆盖多语言标签的值
        username.setInputType("");
        conditionItems.add(username);

        // 个税扣缴义务人
        SearchConditionItem taxAgent = conditionFactory.createCondition(ConditionType.SELECT, 25034, "taxAgentId");
        taxAgent.setColSpan(2);//定义一行显示条件数，默认值为2,当值为1时标识该条件单独占一行
        taxAgent.setFieldcol(16);    //条件输入框所占宽度，默认值18
        taxAgent.setLabelcol(8);
        List<SearchConditionOption> searchConditionOptions = new ArrayList<>();
        Collection<TaxAgentListDTO> taxAgentLists = getTaxAgentService(user).findAll();
        taxAgentLists.forEach(e -> searchConditionOptions.add(new SearchConditionOption(e.getId().toString(), e.getName())));
        taxAgent.setOptions(searchConditionOptions);
        taxAgent.setInputType("");
        taxAgent.setViewAttr(2);  //	 编辑权限  1：只读，2：可编辑， 3：必填   默认2
        taxAgent.setLabel("个税扣缴义务人"); //设置文本值  这个将覆盖多语言标签的值
        conditionItems.add(taxAgent);

        // 分部
        SearchConditionItem subCompany = conditionFactory.createCondition(ConditionType.BROWSER, 502227, "subCompanyIdStr", "194");
        subCompany.setColSpan(2);
        subCompany.setFieldcol(16);
        subCompany.setLabelcol(8);
        subCompany.setViewAttr(2);
        subCompany.setIsQuickSearch(false);
        subCompany.setLabel("分部");
        subCompany.setInputType("");
        subCompany.getBrowserConditionParam().setIsSingle(false);
        conditionItems.add(subCompany);

        // 部门
        SearchConditionItem departmentName = conditionFactory.createCondition(ConditionType.BROWSER, 502227, "departmentIdStr", "4");
        departmentName.setColSpan(2);
        departmentName.setFieldcol(16);
        departmentName.setLabelcol(8);
        departmentName.setViewAttr(2);
        departmentName.setIsQuickSearch(false);
        departmentName.setLabel("部门");
        departmentName.setInputType("");
        departmentName.getBrowserConditionParam().setIsSingle(false);
        conditionItems.add(departmentName);

        // 岗位
        SearchConditionItem position = conditionFactory.createCondition(ConditionType.BROWSER, 502227, "positionIds", "24");
        position.setColSpan(2);
        position.setFieldcol(16);
        position.setLabelcol(8);
        position.setViewAttr(2);
        position.setIsQuickSearch(false);
        position.setLabel("岗位");
        position.setInputType("");
        conditionItems.add(position);

        //状态
        SearchConditionItem status = conditionFactory.createCondition(ConditionType.SELECT, 25034, "userstatus");
        status.setColSpan(2);//定义一行显示条件数，默认值为2,当值为1时标识该条件单独占一行
        status.setFieldcol(16);    //条件输入框所占宽度，默认值18
        status.setLabelcol(8);
        List<SearchConditionOption> userStatusOptions = new ArrayList<>();
        UserStatusEnum.getList().forEach(e -> userStatusOptions.add(new SearchConditionOption(e.get("id"), e.get("content"))));
        status.setOptions(userStatusOptions);
        status.setInputType("");
        status.setViewAttr(2);  //	 编辑权限  1：只读，2：可编辑， 3：必填  默认2
        status.setLabel("状态"); //设置文本值  这个将覆盖多语言标签的值
        conditionItems.add(status);

        //发送状态
        SearchConditionItem sendStatus = conditionFactory.createCondition(ConditionType.SELECT, 25034, "sendStatusVal");
        sendStatus.setColSpan(2);//定义一行显示条件数，默认值为2,当值为1时标识该条件单独占一行
        sendStatus.setFieldcol(16);    //条件输入框所占宽度，默认值18
        sendStatus.setLabelcol(8);
        List<SearchConditionOption> sendStatusOptions = new ArrayList<>();
        Arrays.asList(SalarySendStatusEnum.values())
                .forEach(e -> sendStatusOptions.add(new SearchConditionOption(e.getValue().toString(), e.getDefaultLabel())));
        sendStatus.setOptions(sendStatusOptions);
        sendStatus.setInputType("");
        sendStatus.setViewAttr(2);  // 编辑权限  1：只读，2：可编辑， 3：必填  默认2
        sendStatus.setLabel("发送状态"); //设置文本值  这个将覆盖多语言标签的值
        conditionItems.add(sendStatus);

        addGroups.add(new SearchConditionGroup("常用条件", true, conditionItems));

        apidatas.put("condition", addGroups);
        return apidatas;
    }

    /**
     * 工资单发放信息列表
     *
     * @param queryParam
     * @return
     */
    public PageInfo<SalarySendInfoListDTO> infoList(SalarySendInfoQueryParam queryParam) {

        SalarySendInfoQueryParam.checkParam(queryParam);
        // 发送状态
        if (queryParam.getSendStatus() != null) {
            queryParam.setSendStatusVal(queryParam.getSendStatus().getValue());
        }

        PageInfo<SalarySendInfoListDTO> pageInfo = getSalarySendService(user).salarySendInfoListPage(queryParam);

        return pageInfo;
    }

    /**
     * 工资单信息列表
     *
     * @return
     */
    private List<WeaTableColumn> buildInfoListWeaTableColumns() {
        List<WeaTableColumn> list = new ArrayList<>();
        WeaTableColumn idColumn = new WeaTableColumn("0px", "id", "id");
        idColumn.setDisplay(WeaBoolAttr.TRUE);
        list.add(new WeaTableColumn("20%", "姓名", "username"));
        list.add(new WeaTableColumn("20%", "个税扣缴义务人", "taxAgent"));
        list.add(new WeaTableColumn("20%", "部门", "department"));
        list.add(new WeaTableColumn("20%", "手机号", "mobile"));
        list.add(new WeaTableColumn("20%", "工号", "jobNum"));
        list.add(new WeaTableColumn("20%", "发送状态", "sendStatus"));
        list.add(new WeaTableColumn("20%", "操作", "operation"));
        return list;
    }


    /**
     * 导出-工资单发放信息列表
     *
     * @param queryParam
     * @return
     */
    public XSSFWorkbook exportInfoList(SalarySendInfoQueryParam queryParam) {
        return getSalarySendService(user).exportInfoList(queryParam);
    }

    /**
     * 工资单发放
     *
     * @param queryParam
     * @return
     */
    public Map<String, Object> grant(SalarySendGrantParam queryParam) {
        return getSalaryBillService(user).grant(queryParam);
    }

    /**
     * 工资单撤回
     *
     * @param queryParam
     * @return
     */
    public Map<String, Object> withdraw(SalarySendWithdrawParam queryParam) {
        return getSalarySendService(user).withdraw(queryParam);
    }

    /**
     * 工资单发放详情列表的高级搜索
     *
     * @return
     */
    public Map<String, Object> getDetailSearchCondition() {
        Map<String, Object> apidatas = new HashMap<String, Object>();
        ConditionFactory conditionFactory = new ConditionFactory(user);

        //条件组
        List<SearchConditionGroup> addGroups = new ArrayList<SearchConditionGroup>();
        List<SearchConditionItem> conditionItems = new ArrayList<SearchConditionItem>();

        //文本输入框
        SearchConditionItem username = conditionFactory.createCondition(ConditionType.INPUT, 25034, "username");
        username.setColSpan(2);//定义一行显示条件数，默认值为2,当值为1时标识该条件单独占一行
        username.setFieldcol(16);    //条件输入框所占宽度，默认值18
        username.setLabelcol(8);
        username.setViewAttr(2);  //	 编辑权限  1：只读，2：可编辑， 3：必填   默认2
        username.setLabel("姓名"); //设置文本值  这个将覆盖多语言标签的值
        username.setInputType("");
        conditionItems.add(username);

        // 个税扣缴义务人
        SearchConditionItem taxAgent = conditionFactory.createCondition(ConditionType.SELECT, 25034, "taxAgent");
        taxAgent.setColSpan(2);//定义一行显示条件数，默认值为2,当值为1时标识该条件单独占一行
        taxAgent.setFieldcol(16);    //条件输入框所占宽度，默认值18
        taxAgent.setLabelcol(8);
        List<SearchConditionOption> searchConditionOptions = new ArrayList<>();
        Collection<TaxAgentListDTO> taxAgentLists = getTaxAgentService(user).findAll();
        taxAgentLists.forEach(e -> searchConditionOptions.add(new SearchConditionOption(e.getId().toString(), e.getName())));
        taxAgent.setOptions(searchConditionOptions);
        taxAgent.setInputType("");
        taxAgent.setViewAttr(2);  //	 编辑权限  1：只读，2：可编辑， 3：必填   默认2
        taxAgent.setLabel("个税扣缴义务人"); //设置文本值  这个将覆盖多语言标签的值
        conditionItems.add(taxAgent);

        // 分部
        SearchConditionItem subCompany = conditionFactory.createCondition(ConditionType.BROWSER, 502227, "subCompanyIdStr", "194");
        subCompany.setColSpan(2);
        subCompany.setFieldcol(16);
        subCompany.setLabelcol(8);
        subCompany.setViewAttr(2);
        subCompany.setInputType("");
        subCompany.setIsQuickSearch(false);
        subCompany.setLabel("分部");
        subCompany.getBrowserConditionParam().setIsSingle(false);
        conditionItems.add(subCompany);


        // 部门
        SearchConditionItem departmentName = conditionFactory.createCondition(ConditionType.BROWSER, 502227, "departmentIdStr", "4");
        departmentName.setColSpan(2);
        departmentName.setFieldcol(16);
        departmentName.setLabelcol(8);
        departmentName.setViewAttr(2);
        departmentName.setInputType("");
        departmentName.setIsQuickSearch(false);
        departmentName.setLabel("部门");
        departmentName.getBrowserConditionParam().setIsSingle(false);
        conditionItems.add(departmentName);

        // 岗位
        SearchConditionItem position = conditionFactory.createCondition(ConditionType.BROWSER, 502227, "position", "24");
        position.setColSpan(2);
        position.setFieldcol(16);
        position.setInputType("");
        position.setLabelcol(8);
        position.setViewAttr(2);
        position.setIsQuickSearch(false);
        position.setLabel("岗位");
        conditionItems.add(position);

        //状态
        SearchConditionItem status = conditionFactory.createCondition(ConditionType.SELECT, 25034, "userstatus");
        status.setColSpan(2);//定义一行显示条件数，默认值为2,当值为1时标识该条件单独占一行
        status.setFieldcol(16);    //条件输入框所占宽度，默认值18
        status.setLabelcol(8);
        List<SearchConditionOption> userStatusOptions = new ArrayList<>();
        UserStatusEnum.getList().forEach(e -> userStatusOptions.add(new SearchConditionOption(e.get("id"), e.get("content"))));
        status.setOptions(userStatusOptions);
        status.setInputType("");
        status.setViewAttr(2);  //	 编辑权限  1：只读，2：可编辑， 3：必填  默认2
        status.setLabel("状态"); //设置文本值  这个将覆盖多语言标签的值
        conditionItems.add(status);

//        //入职日期
//        SearchConditionItem hiredate = conditionFactory.createCondition(ConditionType.RANGEPICKER, 25034, "hiredate");
//        hiredate.setColSpan(2);//定义一行显示条件数，默认值为2,当值为1时标识该条件单独占一行
//        hiredate.setFieldcol(16);    //条件输入框所占宽度，默认值18
//        hiredate.setLabelcol(8);
//        hiredate.setViewAttr(2);  // 编辑权限  1：只读，2：可编辑， 3：必填  默认2
//        Map<String, Object> otherParams1 = new HashMap<String, Object>();
//        otherParams1.put("format", "yyyy-MM-dd");
//        hiredate.setOtherParams(otherParams1);
//        hiredate.setInputType("day");
//        hiredate.setMode("day");
//        hiredate.setLabel("入职日期"); //设置文本值  这个将覆盖多语言标签的值
//        conditionItems.add(hiredate);

        //合并计税
        SearchConditionItem mergeCountTax = conditionFactory.createCondition(ConditionType.CHECKBOX, 25034, "mergeCountTax");
        mergeCountTax.setColSpan(2);//定义一行显示条件数，默认值为2,当值为1时标识该条件单独占一行
        mergeCountTax.setFieldcol(16);    //条件输入框所占宽度，默认值18
        mergeCountTax.setLabelcol(8);
        mergeCountTax.setInputType("switch");
        mergeCountTax.setViewAttr(2);  // 编辑权限  1：只读，2：可编辑， 3：必填  默认2
        mergeCountTax.setLabel("合并计税"); //设置文本值  这个将覆盖多语言标签的值
        conditionItems.add(mergeCountTax);

        addGroups.add(new SearchConditionGroup("常用条件", true, conditionItems));

        apidatas.put("condition", addGroups);
        return apidatas;
    }

    /**
     * 工资单发放详情列表
     *
     * @param queryParam
     * @return
     */
    public Map<String, Object> detailList(SalarySendDetailQueryParam queryParam) {
        Map<String, Object> datas = new HashMap<>();
        SalarySendDetailQueryParam.checkParam(queryParam);
        SalarySendPO salarySend = getSalarySendService(user).getById(queryParam.getSalarySendId());

        if (salarySend == null) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100510, "工资发放不存在"));
        }

        SalaryAcctRecordPO salaryAcctRecord = getSalaryAcctRecordService(user).getById(salarySend.getSalaryAccountingId());
        boolean isReplenish = salaryAcctRecord != null && Objects.equals(salaryAcctRecord.getBackCalcStatus(), (NumberUtils.INTEGER_ONE));


        // 1.根据模板获取薪资项目设置
        SalarySobPO salarySob = getSalarySobService(user).getById(salarySend.getSalarySobId());
        List<SalaryTemplatePO> salaryTemplates = getSalaryTemplateService(user)
                .getDefaultTemplates(Arrays.asList(salarySend.getSalarySobId(), salarySob == null ? 0L : salarySob.getId()));

        List<SalaryTemplateSalaryItemListDTO> salaryItems = getSalarySendService(user)
                .getSalaryItemsSetting(CollectionUtils.isNotEmpty(salaryTemplates) ? salaryTemplates.get(0) : null, isReplenish);

        // 2.获取基本数据
        PageInfo<SalarySendDetailListDTO> pageInfo = getSalarySendService(user).salarySendInfoDetailListPage(queryParam);

        List<SalarySendDetailListDTO> records = pageInfo.getList();
        // 3.组装详情数据
        List<Map<String, Object>> listMaps = getSalarySendService(user).buildDetailList(salaryItems, records, salarySend.getSalaryAccountingId());

        List<WeaTableColumn> columns = buildDetailListWeaTableColumns();

        for (SalaryTemplateSalaryItemListDTO salaryItem : salaryItems) {
            columns.add(new WeaTableColumn("100px", salaryItem.getName(), salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX));
        }


        WeaTable table = new WeaTable();
        table.setColumns(columns);
        //设置check是否可用
        List<WeaTableCheckboxpopedom> checkboxpopedomList = new ArrayList<>();
        WeaTableCheckboxpopedom checkboxpopedom = new WeaTableCheckboxpopedom();
        checkboxpopedom.setPopedompara("column:system_type");
        checkboxpopedom.setShowmethod("com.engine.salary.transmethod.TaxRateTransMethod.getCheckBoxPopedom");
        checkboxpopedomList.add(checkboxpopedom);
        table.setCheckboxList(checkboxpopedomList);
        table.setCheckboxpopedom(null);

        WeaResultMsg result = new WeaResultMsg(false);
        result.putAll(table.makeDataResult());
        result.success();

        datas.put("pageInfo", pageInfo);
        datas.put("datas", listMaps);
        datas.put("columns", columns);
        datas.put("dataKey", result.getResultMap());

        return datas;
    }

    private List<WeaTableColumn> buildDetailListWeaTableColumns() {
        List<WeaTableColumn> list = new ArrayList<>();
        WeaTableColumn idColumn = new WeaTableColumn("0px", "id", "id");
        idColumn.setDisplay(WeaBoolAttr.TRUE);
        list.add(new WeaTableColumn("100px", "姓名", "username"));
        list.add(new WeaTableColumn("100px", "个税扣缴义务人", "taxAgent"));
        list.add(new WeaTableColumn("100px", "部门", "department"));
        list.add(new WeaTableColumn("100px", "手机号", "mobile"));
        list.add(new WeaTableColumn("100px", "工号", "jobNum"));
        return list;
    }

    /**
     * 导出-工资单发放详情列表
     *
     * @param queryParam
     * @return
     */
    public XSSFWorkbook exportDetailList(SalarySendDetailQueryParam queryParam) {
        // 获取发放详情
        SalarySendDetailQueryParam.checkParam(queryParam);

        SalarySendPO salarySend = getSalarySendService(user).getById(queryParam.getSalarySendId());
        if (salarySend == null) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100512, "工资单发放不存在"));
        }

        return getSalarySendService(user).exportDetailList(salarySend, queryParam);
    }

    /**
     * 我的工资单列表
     *
     * @param queryParam
     * @return
     */
    public Map<String, Object> mySalaryBillList(SalaryBillQueryParam queryParam) {
        Map<String, Object> datas = new HashMap<>();
        queryParam.setEmployeeId((long) user.getUID());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        queryParam.setSalaryMonth(
                queryParam.getSalaryYearMonth().stream().map(e -> {
                    try {
                        return simpleDateFormat.parse(e + "-01");
                    } catch (ParseException parseException) {
                        throw new SalaryRunTimeException("日期转换错误");
                    }
                }).collect(Collectors.toList()));
        PageInfo<SalaryMySalaryBillListDTO> pageInfo = getSalarySendService(user).mySalaryBillListPage(queryParam);
        List<SalaryMySalaryBillListDTO> records = pageInfo.getList();

        records.forEach(e -> {
            e.setTaxAgent(StringUtils.isEmpty(e.getTaxAgent()) ? "" : e.getTaxAgent());
            e.setAcctTimes(e.getAcctTimes());
        });
        List<WeaTableColumn> columns = buildMySalaryBillListColumns();
        WeaTable table = new WeaTable();
        table.setColumns(columns);
        //设置check是否可用
        List<WeaTableCheckboxpopedom> checkboxpopedomList = new ArrayList<>();
        WeaTableCheckboxpopedom checkboxpopedom = new WeaTableCheckboxpopedom();
        checkboxpopedom.setPopedompara("column:system_type");
        checkboxpopedom.setShowmethod("com.engine.salary.transmethod.TaxRateTransMethod.getCheckBoxPopedom");
        checkboxpopedomList.add(checkboxpopedom);
        table.setCheckboxList(checkboxpopedomList);
        table.setCheckboxpopedom(null);

        WeaResultMsg result = new WeaResultMsg(false);
        result.putAll(table.makeDataResult());
        result.success();

        datas.put("pageInfo", pageInfo);
        datas.put("datas", records);
        datas.put("columns", columns);
        datas.put("dataKey", result.getResultMap());

        return datas;
    }

    private List<WeaTableColumn> buildMySalaryBillListColumns() {
        SalarySysConfPO taxAgentShowStatusPO = getSalarySysConfService(user).getOneByCode(SalarySysConstant.TAX_AGENT_SHOW_STATUS);
        List<WeaTableColumn> list = new ArrayList<>();
        WeaTableColumn idColumn = new WeaTableColumn("0px", "id", "id");
        idColumn.setDisplay(WeaBoolAttr.TRUE);
        list.add(new WeaTableColumn("20%", "薪资所属月", "salaryYearMonth"));
        if (taxAgentShowStatusPO == null || taxAgentShowStatusPO.getConfValue().equals("1")) {
            list.add(new WeaTableColumn("40%", "个税扣缴义务人", "taxAgent"));
        }
        list.add(new WeaTableColumn("40%", "发放时间", "sendTime"));
        return list;
    }


    /**
     * 我的工资单
     *
     * @param salaryInfoId
     * @return
     */
    public Map<String, Object> mySalaryBill(Long salaryInfoId) {
        if (user == null) {
            throw new SalaryRunTimeException("获取人员信息失败！");
        }
        return getSalarySendService(user).mySalaryBill(salaryInfoId, (long) user.getUID());
    }

    /**
     * 工资单发放信息合计行
     *
     * @param queryParam
     * @return
     */
    public Map<String, Object> sumSendResult(SalarySendInfoQueryParam queryParam) {
        Map<String, Object> datas = new HashMap<>();
        //合计
        Map<String, Object> sumRow = getSalarySendService(user).sumRow(queryParam);
        datas.put("sumRow", sumRow);
        return datas;

    }

    /**
     * 发送短信验证码
     * @param param 短信验证码发送参数
     */
    public void sendMobileCode(SMSCodeSendParam param) {
        getSalarySendService(user).sendMobileCode(param);
    }

    /**
     * 校验短信验证码
     * @param param
     * @return
     */
    public Boolean checkMobileCode(SMSCodeCheckParam param) {
        return getSalarySendService(user).checkMobileCode(param);
    }

    public PayrollCheckTypeEnum payrollCheckType() {
        SalarySysConfPO conf = getSalarySysConfService(user).getOneByCode(SalarySysConstant.SALARY_PAYROLL_CHECK_TYPE);

        if(conf == null){
            return PayrollCheckTypeEnum.PWD;
        }

        return PayrollCheckTypeEnum.parseByValue(conf.getConfValue());
    }

    public void confirmSalaryBill(Long salaryInfoId) {
        if(ObjectUtil.isNull(salaryInfoId)){
            throw new SalaryRunTimeException("工资单id不能为空！");
        }
        getSalaryBillService(user).confirmSalaryBill(salaryInfoId);
    }

    public void feedBackSalaryBill(Long salaryInfoId) {
        if(ObjectUtil.isNull(salaryInfoId)){
            throw new SalaryRunTimeException("工资单id不能为空！");
        }
        getSalaryBillService(user).feedBackSalaryBill(salaryInfoId);
    }

    public String exportPdf(SalaryExportPdfParam param) {
        return getSalaryBillService(user).exportPdf(param);
    }

    public Map<String, String> getToken(Long uid) {
        return SalaryTokenUtil.GetToken( uid);
    }

    public String genPdfBeforeExport(SalaryExportPdfParam salaryExportPdfParam) {
        return getSalaryBillService(user).genPdfBeforeExport(salaryExportPdfParam);
    }
}
