package cn.ezhizao.project.business.salary.controller;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import cn.ezhizao.common.utils.PdfUtil;
import cn.ezhizao.common.utils.SecurityUtils;
import cn.ezhizao.common.utils.StringUtils;
import cn.ezhizao.framework.aspectj.lang.annotation.Anonymous;
import cn.ezhizao.framework.aspectj.lang.annotation.Excel;
import cn.ezhizao.framework.lock.DistributionLock;
import cn.ezhizao.framework.lock.LockKey;
import cn.ezhizao.project.business.company.domain.BizCompany;
import cn.ezhizao.project.business.company.service.IBizCompanyService;
import cn.ezhizao.project.business.finance.IndividualIncomeTaxIsZero.domain.BizFinancialIndividualIncomeTaxDetailIsZero;
import cn.ezhizao.project.business.finance.IndividualIncomeTaxIsZero.domain.BizFinancialIndividualIncomeTaxIsZero;
import cn.ezhizao.project.business.finance.IndividualIncomeTaxIsZero.service.IBizFinancialIndividualIncomeTaxIsZeroService;
import cn.ezhizao.project.business.finance.IndividualIncomeTaxIsZero.service.IBizFinancialIndividualIncomeTaxDetailIsZeroService;
import cn.ezhizao.project.business.housingFund.domain.BizHousingFundConfirm;
import cn.ezhizao.project.business.housingFund.domain.BizHousingFundConfirmDetail;
import cn.ezhizao.project.business.housingFund.domain.BizHousingFundConfirmDetailEmployee;
import cn.ezhizao.project.business.housingFund.service.IBizHousingFundConfirmDetailEmployeeService;
import cn.ezhizao.project.business.housingFund.service.IBizHousingFundConfirmDetailService;
import cn.ezhizao.project.business.housingFund.service.IBizHousingFundConfirmService;
import cn.ezhizao.project.business.keepAccounts.domain.BizFinancialKeepAccount;
import cn.ezhizao.project.business.keepAccounts.domain.BizFinancialKeepAccountDetail;
import cn.ezhizao.project.business.keepAccounts.service.IBizFinancialKeepAccountDetailService;
import cn.ezhizao.project.business.keepAccounts.service.IBizFinancialKeepAccountService;
import cn.ezhizao.project.business.receiveTicket.domain.BizFinancialReceiveTicketDetail;
import cn.ezhizao.project.business.receiveTicket.service.IBizFinancialReceiveTicketDetailService;
import cn.ezhizao.project.business.receiveTicket.service.IBizFinancialReceiveTicketService;
import cn.ezhizao.project.business.salary.domain.BizFinancialSalaryDetail;
import cn.ezhizao.project.business.salary.domain.BizFinancialSalaryDetailEmployee;
import cn.ezhizao.project.business.salary.domain.vo.BizFinancialSalaryDetailEmployeeNotCompany;
import cn.ezhizao.project.business.salary.domain.vo.FilterRequest;
import cn.ezhizao.project.business.salary.service.IBizFinancialSalaryDetailEmployeeService;
import cn.ezhizao.project.business.salary.service.IBizFinancialSalaryDetailService;
import cn.ezhizao.project.business.socialSecurity.domain.BizSocialSecurityConfirm;
import cn.ezhizao.project.business.socialSecurity.domain.BizSocialSecurityConfirmDetail;
import cn.ezhizao.project.business.socialSecurity.domain.BizSocialSecurityConfirmDetailEmployee;
import cn.ezhizao.project.business.socialSecurity.service.IBizSocialSecurityConfirmDetailEmployeeService;
import cn.ezhizao.project.business.socialSecurity.service.IBizSocialSecurityConfirmDetailService;
import cn.ezhizao.project.business.socialSecurity.service.IBizSocialSecurityConfirmService;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrderRecord;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderRecordService;
import cn.ezhizao.project.system.domain.SysUser;
import cn.ezhizao.project.system.mapper.SysUserMapper;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itextpdf.kernel.geom.PageSize;

import freemarker.template.Template;
import freemarker.template.TemplateException;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import cn.ezhizao.framework.aspectj.lang.annotation.Log;
import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;
import cn.ezhizao.project.business.salary.domain.BizFinancialSalary;
import cn.ezhizao.project.business.salary.service.IBizFinancialSalaryService;
import cn.ezhizao.framework.web.controller.BaseController;
import cn.ezhizao.framework.web.domain.AjaxResult;
import cn.ezhizao.common.utils.poi.ExcelUtil;
import cn.ezhizao.framework.web.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

/**
 * 工资Controller
 *
 * @author ruoyi
 * @date 2023-11-16
 */
@RestController
@RequestMapping("/business/salary")
public class BizFinancialSalaryController extends BaseController {
    @Resource
    private IBizFinancialSalaryService bizFinancialSalaryService;
    @Resource
    private IBizFinancialSalaryDetailService bizFinancialSalaryDetailService;
    @Resource
    private IBizFinancialIndividualIncomeTaxIsZeroService financialIndividualIncomeTaxService;
    @Resource
    private IBizFinancialIndividualIncomeTaxDetailIsZeroService financialIndividualIncomeTaxDetailService;
    @Resource
    private IBizFinancialReceiveTicketService financialReceiveTicketService;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private IBizFinancialReceiveTicketDetailService financialReceiveTicketDetailService;
    @Resource
    private IBizWorkOrderRecordService bizWorkOrderRecordService;
    @Resource
    private IBizCompanyService companyService;

    @Value("${ruoyi.pdfTemplate.url}")
    private String templatePath;
    /**
     * 生成pdf
     */
    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;


    @Resource
    private IBizFinancialSalaryDetailEmployeeService bizFinancialSalaryDetailEmployeeService;
    @Resource
    private IBizFinancialKeepAccountService financialKeepAccountService;
    @Resource
    private IBizFinancialKeepAccountDetailService financialKeepAccountDetailService;

    @Resource
    private IBizSocialSecurityConfirmDetailService socialSecurityConfirmDetailService;
    @Resource
    private IBizSocialSecurityConfirmDetailEmployeeService socialSecurityConfirmDetailEmployeeService;

    @Resource
    private IBizHousingFundConfirmDetailEmployeeService housingFundConfirmDetailEmployeeService;

    @Resource
    private IBizSocialSecurityConfirmService socialSecurityConfirmService;

    @Resource
    private IBizHousingFundConfirmService housingFundConfirmService;

    @Resource
    private IBizHousingFundConfirmDetailService housingFundConfirmDetailService;

    /**
     * 查询工资列表
     */
    @PreAuthorize("@ss.hasPermi('business:salary:list')")
    @GetMapping("/list")
    public TableDataInfo list(BizFinancialSalary bizFinancialSalary) throws NoSuchFieldException, IllegalAccessException {
        String chooseYear = bizFinancialSalary.getYear();
        int nwoYear = LocalDate.now().getYear();
        setTenantId(bizFinancialSalary);
        startPage();
        startOrderBy();
        bizFinancialSalary.setYear(String.valueOf(nwoYear));
        bizFinancialSalary.setIsZero(0);

        List<BizFinancialSalary> list = bizFinancialSalaryService.getList(bizFinancialSalary);
        if (!list.isEmpty()) {
            if (!chooseYear.equals(nwoYear)) {
                List<BizFinancialSalaryDetail> details = bizFinancialSalaryDetailService.query().in("financial_salary_id", list.stream().map(BizFinancialSalary::getId).collect(Collectors.toList())).eq("year", chooseYear).list();
                list.forEach(l -> {
                    l.setDetails(details.stream().filter(v -> v.getFinancialSalaryId().equals(l.getId())).collect(Collectors.toList()));
                });
            } else {
                List<BizFinancialSalaryDetail> details = bizFinancialSalaryDetailService.query().in("financial_salary_id", list.stream().map(BizFinancialSalary::getId).collect(Collectors.toList())).eq("year", bizFinancialSalary.getYear()).list();
                list.forEach(l -> {
                    l.setDetails(details.stream().filter(v -> v.getFinancialSalaryId().equals(l.getId())).collect(Collectors.toList()));
                });
            }

        }
        return getDataTable(list);
    }

    /**
     * 导出工资列表
     */
    @PreAuthorize("@ss.hasPermi('business:salary:export')")
    @Log(title = "工资", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(BizFinancialSalary bizFinancialSalary, HttpServletResponse response) throws NoSuchFieldException, IllegalAccessException {
        //设置当前账套
        setTenantId(bizFinancialSalary);
        startOrderBy();
        //非零申报
        bizFinancialSalary.setIsZero(0);
        //查询数据
//        List<BizFinancialSalary> list = bizFinancialSalaryService.getList(bizFinancialSalary);
        List<BizFinancialSalary> list = bizFinancialSalaryService.getList2(bizFinancialSalary);
        //优化
        Map<String, BizFinancialSalaryDetail> detailMap = bizFinancialSalaryDetailService
                .list(new LambdaQueryWrapper<BizFinancialSalaryDetail>().eq(BizFinancialSalaryDetail::getDeleted, 0))
                .stream().collect(Collectors.toMap(d -> d.getFinancialSalaryId() + d.getYear() + d.getMonth(),
                        Function.identity(), (d1, d2) -> d1));
        List<SysUser> sysUsers = sysUserMapper.selectUserList(new SysUser());
        Map<Long, SysUser> userMap = sysUsers.stream().collect(Collectors.toMap(user -> user.getUserId(), Function.identity()));

        //设置状态和当前期间
        for (BizFinancialSalary salary : list) {
            //设置当前期间
            salary.setCurrentPeriod(bizFinancialSalary.getYear() + "-" + bizFinancialSalary.getMonth());
            BizFinancialSalaryDetail salaryDetail = new BizFinancialSalaryDetail();
            salaryDetail.setFinancialSalaryId(salary.getId());
            salaryDetail.setYear(bizFinancialSalary.getYear());
            salaryDetail.setMonth(bizFinancialSalary.getMonth());
//            //查询当前期间明细
//            List<BizFinancialSalaryDetail> bizFinancialSalaryDetails = bizFinancialSalaryDetailService.getList(salaryDetail);
            String query = salary.getId() + bizFinancialSalary.getYear() + bizFinancialSalary.getMonth();

//            if (bizFinancialSalaryDetails.size() == 0 ) {
//                salaryDetail.setStatus(0);
//                salary.setServiceName("");
            if (detailMap.get(query) == null) {
                salaryDetail.setStatus(0);
                salary.setServiceName("");
            } else {
//                salaryDetail = bizFinancialSalaryDetails.get(0);
                salaryDetail = detailMap.get(query);
//                SysUser sysUser = sysUserMapper.selectUserById(salaryDetail.getVerifierId());
                SysUser sysUser = userMap.getOrDefault(salaryDetail.getVerifierId(), null);
                salary.setServiceName(sysUser == null ? "" : sysUser.getNickName());
            }
            //设置状态
            switch (salaryDetail.getStatus()) {
                case 0:
                    salary.setCurrentStatus("未开始");
                    break;
                case 1:
                    salary.setCurrentStatus("待确认");
                    break;
                case 2:
                    salary.setCurrentStatus("待审核");
                    break;
                case 3:
                    salary.setCurrentStatus("已完成");
                    break;
                case 4:
                    salary.setCurrentStatus("驳回待处理");
                    break;
                default:
                    break;
            }

        }
        ExcelUtil<BizFinancialSalary> util = new ExcelUtil<BizFinancialSalary>(BizFinancialSalary.class);
        util.exportExcel(response, list, "工资数据");
    }

    /**
     * 导出工资模板
     */
    @Log(title = "导出工资模板", businessType = BusinessType.EXPORT)
    @PostMapping("/exportSalaryTemplate")
    public void exportSalaryTemplate(HttpServletResponse response) throws NoSuchFieldException, IllegalAccessException {
        ExcelUtil<BizFinancialSalaryDetailEmployee> util = new ExcelUtil<BizFinancialSalaryDetailEmployee>(BizFinancialSalaryDetailEmployee.class);
        util.importTemplateExcel(response, "工资模板");
    }

    @Log(title = "导出工资模板2", businessType = BusinessType.EXPORT)
    @PostMapping("/exportSalaryTemplateNotCompany")
    public void exportSalaryTemplateNotCompany(HttpServletResponse response) throws NoSuchFieldException, IllegalAccessException {
        ExcelUtil<BizFinancialSalaryDetailEmployeeNotCompany> util = new ExcelUtil<BizFinancialSalaryDetailEmployeeNotCompany>(BizFinancialSalaryDetailEmployeeNotCompany.class);
        util.importTemplateExcel(response, "工资模板");
    }

    @Log(title = "工资导入", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('business:salary:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, @RequestParam String year, @RequestParam String month, @RequestParam(required = false) String companyId) throws Exception {
        List<BizFinancialSalaryDetailEmployee> detailList = new ArrayList<>();
        List<BizFinancialSalaryDetailEmployeeNotCompany> detailListNotCompany = new ArrayList<>();
        List<String> excelHeaders = null;
        List<String> names = null;
        if (StringUtils.isNotEmpty(companyId)) {
            BizCompany company = companyService.getById(companyId);
            ExcelUtil<BizFinancialSalaryDetailEmployeeNotCompany> util = new ExcelUtil<>(BizFinancialSalaryDetailEmployeeNotCompany.class);
            detailListNotCompany = util.importExcel(file.getInputStream());
            for (BizFinancialSalaryDetailEmployeeNotCompany item : detailListNotCompany) {
                item.setCompanyName(company.getName());
                BizFinancialSalaryDetailEmployee bizFinancialSalaryDetailEmployee = new BizFinancialSalaryDetailEmployee();
                BeanUtils.copyProperties(item, bizFinancialSalaryDetailEmployee);
                detailList.add(bizFinancialSalaryDetailEmployee);
            }
            // 获取 入Excel 表头字段
            excelHeaders = util.readExcelHeaders(file.getInputStream());
            //获取实体类字段
            names = getExcelAnnotatedFields(BizFinancialSalaryDetailEmployeeNotCompany.class);
        } else {
            ExcelUtil<BizFinancialSalaryDetailEmployee> util = new ExcelUtil<>(BizFinancialSalaryDetailEmployee.class);
            detailList = util.importExcel(file.getInputStream());
            // 获取 入Excel 表头字段
            excelHeaders = util.readExcelHeaders(file.getInputStream());
            //获取实体类字段
            names = getExcelAnnotatedFields(BizFinancialSalaryDetailEmployee.class);
            //如果不存在模板中的字段，返回错误
        }
        if (!excelHeaders.containsAll(names)) {
            return error("导入数据与模板不匹配！");
        }
        String message = bizFinancialSalaryService.importSalary(detailList, year, month, getTenantId() == null ? 0 : getTenantId(), 0);
        return success(message);
    }

    public List<String> getExcelAnnotatedFields(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        List<String> result = new ArrayList<>();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Excel.class)) {
                Excel excelAnnotation = field.getAnnotation(Excel.class);
                String fieldName = excelAnnotation.name();
                result.add(fieldName);
            }
        }
        return result;
    }

    /**
     * 获取工资详细信息
     */
    @PreAuthorize("@ss.hasPermi('business:salary:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(bizFinancialSalaryService.getById(id));
    }

    /**
     * 新增工资
     */
    @PreAuthorize("@ss.hasPermi('business:salary:add')")
    @Log(title = "工资", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody BizFinancialSalary bizFinancialSalary) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizFinancialSalary);
        return toAjax(bizFinancialSalaryService.save(bizFinancialSalary));
    }

    /**
     * 修改工资
     */
    @PreAuthorize("@ss.hasPermi('business:salary:edit')")
    @Log(title = "工资", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BizFinancialSalary bizFinancialSalary) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizFinancialSalary);
        return toAjax(bizFinancialSalaryService.updateById(bizFinancialSalary));
    }

    /**
     * 删除工资
     */
    @PreAuthorize("@ss.hasPermi('business:salary:remove')")
    @Log(title = "工资", businessType = BusinessType.DELETE)
    @DeleteMapping("/physical/{ids}")
    public AjaxResult remove(@PathVariable List<Long> ids) {
        if (ids.isEmpty()) {
            return null;
        }
        return toAjax(bizFinancialSalaryService.physicalDeleteIds(ids));
    }

    @Log(title = "工资", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult removeByIdS(@PathVariable List<Long> ids) {

        return toAjax(bizFinancialSalaryService.removeBatchByIds(ids));
    }

    @PreAuthorize("@ss.hasAnyPermi('business:salary:query,business:salary:view')")
    @PostMapping("/getDetail")
    public AjaxResult getDetail(@RequestBody BizFinancialSalaryDetail bizFinancialSalaryDetail) {
        List<BizFinancialSalaryDetail> bizFinancialSalaryDetails = bizFinancialSalaryDetailService.getList(bizFinancialSalaryDetail);
        if (bizFinancialSalaryDetails.isEmpty()) {
            // 获取上个月的工资人员信息
            // 先获取之前的一个月是否已填报，然后获取填报后的工资人员信息
            BizFinancialSalaryDetail detail = bizFinancialSalaryDetailService.query().eq("financial_salary_id", bizFinancialSalaryDetail.getFinancialSalaryId()).lt("concat(year,month)", bizFinancialSalaryDetail.getYear() + bizFinancialSalaryDetail.getMonth()).orderByDesc("concat(year, month)").last("limit 1").one();
            if (detail != null) {
                List<BizFinancialSalaryDetailEmployee> employees = bizFinancialSalaryDetailEmployeeService.query().eq("financial_salary_detail_id", detail.getId()).list();
                employees.forEach(l -> l.setId(null));
                //社保存在
                BizSocialSecurityConfirmDetail one = socialSecurityConfirmDetailService.getOne(new LambdaQueryWrapper<BizSocialSecurityConfirmDetail>()
                        .eq(BizSocialSecurityConfirmDetail::getYear, bizFinancialSalaryDetail.getYear())
                        .eq(BizSocialSecurityConfirmDetail::getMonth, bizFinancialSalaryDetail.getMonth())
                        .eq(BizSocialSecurityConfirmDetail::getCompanyId, bizFinancialSalaryDetail.getCompanyId())
                        .last("limit 1"));

                BizHousingFundConfirmDetail one1 = housingFundConfirmDetailService.getOne(new LambdaQueryWrapper<BizHousingFundConfirmDetail>()
                        .eq(BizHousingFundConfirmDetail::getYear, bizFinancialSalaryDetail.getYear())
                        .eq(BizHousingFundConfirmDetail::getMonth, bizFinancialSalaryDetail.getMonth())
                        .eq(BizHousingFundConfirmDetail::getCompanyId, bizFinancialSalaryDetail.getCompanyId())
                        .last("limit 1"));
                if (one != null){
                    List<BizSocialSecurityConfirmDetailEmployee> employeeList = socialSecurityConfirmDetailEmployeeService.list(new LambdaQueryWrapper<BizSocialSecurityConfirmDetailEmployee>()
                            .eq(BizSocialSecurityConfirmDetailEmployee::getSocialSecurityConfirmDetailId, one.getId()));
                    if (employeeList != null){
                        List<String> employeeName = employeeList.stream().map(BizSocialSecurityConfirmDetailEmployee::getEmployeeName).collect(Collectors.toList());
                        for (BizFinancialSalaryDetailEmployee employee : employees) {
                            if (employeeName.contains(employee.getEmployeeName())){
                                employee.setSocialSecurityStatus(1);
                            }
                        }
                    }
                }
                if (one1 != null){
                    List<BizHousingFundConfirmDetailEmployee> employeeList = housingFundConfirmDetailEmployeeService.list(new LambdaQueryWrapper<BizHousingFundConfirmDetailEmployee>()
                            .eq(BizHousingFundConfirmDetailEmployee::getHousingFundConfirmDetailId, one1.getId()));
                    if (employeeList != null){
                        List<String> employeeName = employeeList.stream().map(BizHousingFundConfirmDetailEmployee::getEmployeeName).collect(Collectors.toList());
                        for (BizFinancialSalaryDetailEmployee employee : employees) {
                            if (employeeName.contains(employee.getEmployeeName())){
                                employee.setHousingFundStatus(1);
                            }
                        }
                    }
                }
                bizFinancialSalaryDetail.setDetails(employees);
            } else {
                bizFinancialSalaryDetail.setDetails(new ArrayList<>());
            }
            return success(bizFinancialSalaryDetail);
        }

        BizFinancialSalaryDetail bizFinancialSalaryDetail1 = bizFinancialSalaryDetails.get(0);
        List<BizFinancialSalaryDetailEmployee> details = bizFinancialSalaryDetail1.getDetails();

        //社保存在
        BizSocialSecurityConfirmDetail one = socialSecurityConfirmDetailService.getOne(new LambdaQueryWrapper<BizSocialSecurityConfirmDetail>()
                .eq(BizSocialSecurityConfirmDetail::getYear, bizFinancialSalaryDetail.getYear())
                .eq(BizSocialSecurityConfirmDetail::getMonth, bizFinancialSalaryDetail.getMonth())
                .eq(BizSocialSecurityConfirmDetail::getCompanyId, bizFinancialSalaryDetail.getCompanyId())
                .last("limit 1"));

        BizHousingFundConfirmDetail one1 = housingFundConfirmDetailService.getOne(new LambdaQueryWrapper<BizHousingFundConfirmDetail>()
                .eq(BizHousingFundConfirmDetail::getYear, bizFinancialSalaryDetail.getYear())
                .eq(BizHousingFundConfirmDetail::getMonth, bizFinancialSalaryDetail.getMonth())
                .eq(BizHousingFundConfirmDetail::getCompanyId, bizFinancialSalaryDetail.getCompanyId())
                .last("limit 1"));
        if (one != null){
            List<BizSocialSecurityConfirmDetailEmployee> employeeList = socialSecurityConfirmDetailEmployeeService.list(new LambdaQueryWrapper<BizSocialSecurityConfirmDetailEmployee>()
                    .eq(BizSocialSecurityConfirmDetailEmployee::getSocialSecurityConfirmDetailId, one.getId()));
            if (employeeList != null){
                List<String> employeeName = employeeList.stream().map(BizSocialSecurityConfirmDetailEmployee::getEmployeeName).collect(Collectors.toList());
                for (BizFinancialSalaryDetailEmployee employee : details) {
                    if (employeeName.contains(employee.getEmployeeName())){
                        employee.setSocialSecurityStatus(1);
                    }
                }
            }
        }
        if (one1 != null){
            List<BizHousingFundConfirmDetailEmployee> employeeList = housingFundConfirmDetailEmployeeService.list(new LambdaQueryWrapper<BizHousingFundConfirmDetailEmployee>()
                    .eq(BizHousingFundConfirmDetailEmployee::getHousingFundConfirmDetailId, one1.getId()));
            if (employeeList != null){
                List<String> employeeName = employeeList.stream().map(BizHousingFundConfirmDetailEmployee::getEmployeeName).collect(Collectors.toList());
                for (BizFinancialSalaryDetailEmployee employee : details) {
                    if (employeeName.contains(employee.getEmployeeName())){
                        employee.setHousingFundStatus(1);
                    }
                }
            }
        }
        return success(bizFinancialSalaryDetail1);
    }

    @PreAuthorize("@ss.hasPermi('business:salary:edit')")
    @PostMapping("/saveDetail")
    @Log(title = "生产管理-工资非零申报-新增", businessType = BusinessType.INSERT)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult saveDetail(@RequestBody BizFinancialSalaryDetail bizFinancialSalaryDetail) {
        String join = LockKey.join(LockKey.SALARY, getUserId());
        DistributionLock lock = new DistributionLock(join);
        try {
            lock.lock();
            // 判断之前是否有保存一个明细
            BizFinancialSalaryDetail conditions = new BizFinancialSalaryDetail();
            conditions.setFinancialSalaryId(bizFinancialSalaryDetail.getFinancialSalaryId());
            conditions.setYear(bizFinancialSalaryDetail.getYear());
            conditions.setMonth(bizFinancialSalaryDetail.getMonth());
            if (!bizFinancialSalaryDetailService.getList(conditions).isEmpty()) {
                return error("该月已添加工资信息,请刷新列表。");
            }
            return toAjax(bizFinancialSalaryDetailService.save(bizFinancialSalaryDetail) && addRecord(bizFinancialSalaryDetail.getFinancialSalaryId(), bizFinancialSalaryDetail.getYear(), bizFinancialSalaryDetail.getMonth(), SecurityUtils.getUserId(), "填写工资信息"));
        } catch (Exception e) {
            e.printStackTrace();
            return error("保存失败");
        } finally {
            lock.unlock();
        }
    }

    @Log(title = "生产管理-工资非零申报-更新", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('business:salary:edit')")
    @PostMapping("/updateDetail")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateDetail(@RequestBody BizFinancialSalaryDetail bizFinancialSalaryDetail) {
        return toAjax(bizFinancialSalaryDetailService.updateById(bizFinancialSalaryDetail) && addRecord(bizFinancialSalaryDetail.getFinancialSalaryId(), bizFinancialSalaryDetail.getYear(), bizFinancialSalaryDetail.getMonth(), SecurityUtils.getUserId(), "修改工资信息"));
    }

    @Log(title = "生产管理-工资非零申报-审核通过", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('business:salary:verify')")
    @PostMapping("/verifyDetail")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult verifyDetail(@RequestBody BizFinancialSalaryDetail bizFinancialSalaryDetail) {
        String join = LockKey.join(LockKey.VERIFYNOZERO, getUserId());
        DistributionLock lock = new DistributionLock(join);
        try {
            lock.lock();
            boolean bool = true;
            bizFinancialSalaryDetail.setVerifierId(SecurityUtils.getUserId());
            if (bizFinancialSalaryDetail.getStatus().equals(3)) {
                BizFinancialSalary bizFinancialSalary = bizFinancialSalaryService.getById(bizFinancialSalaryDetail.getFinancialSalaryId());
                QueryWrapper<BizFinancialIndividualIncomeTaxIsZero> qw = new QueryWrapper<>();
                qw.eq("work_order_id", bizFinancialSalary.getWorkOrderId());
                BizFinancialIndividualIncomeTaxIsZero financialIndividualIncomeTax = financialIndividualIncomeTaxService.getOne(qw);
                if (financialIndividualIncomeTax != null) {
                    QueryWrapper<BizFinancialIndividualIncomeTaxDetailIsZero> kqw = new QueryWrapper<>();
                    kqw.eq("financial_individual_income_tax_id", financialIndividualIncomeTax.getId());
                    kqw.eq("year", bizFinancialSalaryDetail.getYear());
                    kqw.eq("month", bizFinancialSalaryDetail.getMonth());
                    BizFinancialIndividualIncomeTaxDetailIsZero financialIndividualIncomeTaxDetail =
                            financialIndividualIncomeTaxDetailService.getOne(kqw);
                    if (financialIndividualIncomeTaxDetail == null) {
                        financialIndividualIncomeTaxDetail = new BizFinancialIndividualIncomeTaxDetailIsZero();
                    }
                    financialIndividualIncomeTaxDetail.setFinancialIndividualIncomeTaxId(financialIndividualIncomeTax.getId());
                    financialIndividualIncomeTaxDetail.setYear(bizFinancialSalaryDetail.getYear());
                    financialIndividualIncomeTaxDetail.setMonth(bizFinancialSalaryDetail.getMonth());
                    financialIndividualIncomeTaxDetail.setCompanyId(bizFinancialSalaryDetail.getCompanyId());
                    financialIndividualIncomeTaxDetail.setStatus(financialIndividualIncomeTaxDetail.getStatus() != null && financialIndividualIncomeTaxDetail.getStatus() > 1 ? financialIndividualIncomeTaxDetail.getStatus() : 1);

                    if (financialIndividualIncomeTaxDetail.getId() == null) {
                        bool = financialIndividualIncomeTaxDetailService.save(financialIndividualIncomeTaxDetail);
                    } else {
                        bool = financialIndividualIncomeTaxDetailService.updateById(financialIndividualIncomeTaxDetail);
                    }
                }
                bool = bool && checkKeepAccount(bizFinancialSalaryDetail) && addRecord(bizFinancialSalaryDetail.getFinancialSalaryId(), bizFinancialSalaryDetail.getYear(), bizFinancialSalaryDetail.getMonth(), SecurityUtils.getUserId(), "工资审核通过");
//            return bool;
            } else {
                bool = bool && addRecord(bizFinancialSalaryDetail.getFinancialSalaryId(), bizFinancialSalaryDetail.getYear(), bizFinancialSalaryDetail.getMonth(), SecurityUtils.getUserId(), "工资审核不通过");
            }
            bizFinancialSalaryDetail.setVerifierTime(new Date());
            bool = bool && bizFinancialSalaryDetailService.updateById(bizFinancialSalaryDetail, false);
            return toAjax(bool);
        } catch (Exception e) {
            e.printStackTrace();
            return error("保存失败");
        } finally {
            lock.unlock();
        }
    }

    @Log(title = "生产管理-公司非零申报-退回", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('business:salary:back')")
    @PostMapping("/turnBackDetail")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult turnBackDetail(@RequestBody BizFinancialSalaryDetail detail) {
        // 先判断是否收票完成，收票完成状态不能进行工资退回
        BizFinancialReceiveTicketDetail financialReceiveTicketDetail = financialReceiveTicketDetailService.query().eq("company_id", detail.getCompanyId()).eq("year", detail.getYear()).eq("month", detail.getMonth()).one();
        if (financialReceiveTicketDetail != null && financialReceiveTicketDetail.getStatus() == 3) {
            return error("请先进行收票退回操作再进行工资退回。");
        } else {
            detail.setStatus(2);
        }
        return toAjax(bizFinancialSalaryDetailService.updateById(detail) && addRecord(detail.getFinancialSalaryId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "工资退回"));
    }

    private Boolean checkKeepAccount(BizFinancialSalaryDetail detail) {
        BizFinancialReceiveTicketDetail financialReceiveTicketDetail = financialReceiveTicketDetailService.query().eq("company_id", detail.getCompanyId()).eq("year", detail.getYear()).eq("month", detail.getMonth()).one();
        if (financialReceiveTicketDetail != null) {
            QueryWrapper<BizFinancialKeepAccount> qw = new QueryWrapper<>();
            qw.eq("company_id", detail.getCompanyId());
            qw.eq("is_stop", 0);
            BizFinancialKeepAccount BizFinancialKeepAccount = financialKeepAccountService.getOne(qw);
            if (BizFinancialKeepAccount != null) {
                QueryWrapper<BizFinancialKeepAccountDetail> kqw = new QueryWrapper<>();
                kqw.eq("financial_keep_account_id", BizFinancialKeepAccount.getId());
                kqw.eq("year", detail.getYear());
                kqw.eq("month", detail.getMonth());
                BizFinancialKeepAccountDetail financialKeepAccountDetail =
                        financialKeepAccountDetailService.getOne(kqw);
                if (financialKeepAccountDetail == null) {
                    financialKeepAccountDetail = new BizFinancialKeepAccountDetail();
                }
                financialKeepAccountDetail.setFinancialKeepAccountId(BizFinancialKeepAccount.getId());
                financialKeepAccountDetail.setYear(detail.getYear());
                financialKeepAccountDetail.setMonth(detail.getMonth());
                financialKeepAccountDetail.setCompanyId(detail.getCompanyId());
                List<BizFinancialSalaryDetailEmployee> employees = detail.getDetails();
                financialKeepAccountDetail.setStatus(financialReceiveTicketDetail.getSumNumber().equals(0) && employees.stream().mapToDouble(v -> v.getActuallySalary().doubleValue()).sum() == 0 ? 2 : 1);
                Date receiveDate = financialReceiveTicketDetail.getReceiveDate();
                if (receiveDate != null) {
                    Timestamp timestamp = new Timestamp(receiveDate.getTime());
                    financialKeepAccountDetail.setReceiveDate(timestamp);
                }
//                financialKeepAccountDetailService.saveOrUpdate(financialKeepAccountDetail);
                if (financialKeepAccountDetail.getId() == null) {
                    return financialKeepAccountDetailService.save(financialKeepAccountDetail);
                } else {
                    return financialKeepAccountDetailService.updateById(financialKeepAccountDetail);
                }
            }
        }
        return true;
    }

    private boolean addRecord(Long bizFinancialSalaryId, String year, String month, Long recorderId, String description) {
        // 没拆分合同单价
        BizFinancialSalary bizFinancialSalary = bizFinancialSalaryService.getById(bizFinancialSalaryId);
        Long workOrderId = bizFinancialSalary.getWorkOrderId();
        List<BizWorkOrderRecord> records = bizWorkOrderRecordService.query().eq("work_order_id", workOrderId).eq("year", year).eq("month", month).eq("from_id", 0).list();
        if (records.isEmpty()) {
            // 新增一条记录
            BizWorkOrderRecord record = new BizWorkOrderRecord();
            record.setMonth(month);
            record.setYear(year);
            record.setTenantId(getTenantId());
            record.setWorkOrderId(workOrderId);
            record.setCompanyId(bizFinancialSalary.getCompanyId());
            record.setStatus(1);
            record.setStatusDescript(description);
            record.setRecorderId(recorderId);
            return bizWorkOrderRecordService.save(record);
        } else {
            // 新增一条子记录
            Long fromId = records.get(0).getId();
            BizWorkOrderRecord fromRecord = records.get(0);
            BizWorkOrderRecord record = new BizWorkOrderRecord();
            record.setFromId(fromId);
            record.setMonth(fromRecord.getMonth());
            record.setYear(fromRecord.getYear());
            record.setTenantId(fromRecord.getTenantId());
            record.setCompanyId(bizFinancialSalary.getCompanyId());
            record.setWorkOrderId(fromRecord.getWorkOrderId());
            record.setStatus(fromRecord.getStatus());
            record.setStatusDescript(fromRecord.getStatusDescript());
            record.setRecorderId(fromRecord.getRecorderId());

            fromRecord.setMonth(month);
            fromRecord.setYear(year);
            fromRecord.setTenantId(getTenantId());
            fromRecord.setWorkOrderId(workOrderId);
            fromRecord.setCompanyId(bizFinancialSalary.getCompanyId());
            fromRecord.setStatus(1);
            fromRecord.setStatusDescript(description);
            fromRecord.setRecorderId(recorderId);
            return bizWorkOrderRecordService.save(record) &&
                    bizWorkOrderRecordService.updateById(fromRecord);
        }
    }

    @ApiOperation("导出工资数据")
    @PostMapping("/exportDetailExcel")
    public void exportDetailExcel(@RequestParam Long id, HttpServletResponse response) {
        BizFinancialSalaryDetail financialSalaryDetail = bizFinancialSalaryDetailService.getById(id);
        BizCompany company;

        if (null != financialSalaryDetail) {
            BizFinancialSalaryDetailEmployee map = new BizFinancialSalaryDetailEmployee();
            map.setFinancialSalaryDetailId(financialSalaryDetail.getId());
            List<BizFinancialSalaryDetailEmployee> financialSalaryDetailEmployeeList = bizFinancialSalaryDetailEmployeeService.getList(map);
            financialSalaryDetail.setDetails(financialSalaryDetailEmployeeList);
            company = companyService.getById(financialSalaryDetail.getCompanyId());
        } else {
            return;
        }

        ExcelWriter writer = cn.hutool.poi.excel.ExcelUtil.getWriter(true);
        writer.merge(0, 0, 0, 12, "工资单", true);
        writer.merge(1, 1, 0, 3, company.getName(), false);
        writer.merge(1, 1, 4, 7, financialSalaryDetail.getYear() + "年 第" + financialSalaryDetail.getMonth() + "期", false);
        writer.merge(1, 1, 8, 12, "单位：元", false);
        writer.writeCellValue(0, 2, "员工名");
        writer.writeCellValue(1, 2, "身份证号");
        writer.writeCellValue(2, 2, "应发工资");
        writer.writeCellValue(3, 2, "实发工资");
        writer.writeCellValue(4, 2, "奖金及其他");
        writer.writeCellValue(5, 2, "养老保险");
        writer.writeCellValue(6, 2, "医疗保险");
        writer.writeCellValue(7, 2, "失业险");
        writer.writeCellValue(8, 2, "大病险");
        writer.writeCellValue(9, 2, "公积金");
        writer.writeCellValue(10, 2, "个税");
        writer.writeCellValue(11, 2, "其他扣款");
        writer.writeCellValue(12, 2, "备注");

//        List<String> rowHead = CollUtil.newArrayList("员工名", "公司名称", "身份证号", "应发工资", "实发工资", "奖金及其他", "养老保险", "医疗保险", "失业险", "大病险", "公积金", "个税", "其他扣款", "备注");
        // 自定义标题别名

//        writer.writeHeadRow(rowHead);
        int row = 0;
        for (int i = 0; i < financialSalaryDetail.getDetails().size(); i++) {
            writer.writeCellValue(0, i + 3, financialSalaryDetail.getDetails().get(i).getEmployeeName());
//            writer.writeCellValue(1, i + 1, company.getName());
            writer.writeCellValue(1, i + 3, financialSalaryDetail.getDetails().get(i).getIdCode());
            writer.writeCellValue(2, i + 3, financialSalaryDetail.getDetails().get(i).getPlanSalary());
            writer.writeCellValue(3, i + 3, financialSalaryDetail.getDetails().get(i).getActuallySalary());
            writer.writeCellValue(4, i + 3, financialSalaryDetail.getDetails().get(i).getBonusAmount());
            writer.writeCellValue(5, i + 3, financialSalaryDetail.getDetails().get(i).getEndowmentInsurance());
            writer.writeCellValue(6, i + 3, financialSalaryDetail.getDetails().get(i).getMedicalInsurance());
            writer.writeCellValue(7, i + 3, financialSalaryDetail.getDetails().get(i).getUnemploymentBenefit());
            writer.writeCellValue(8, i + 3, financialSalaryDetail.getDetails().get(i).getSeriousIllnessInsurance());
            writer.writeCellValue(9, i + 3, financialSalaryDetail.getDetails().get(i).getHousingFund());
            writer.writeCellValue(10, i + 3, financialSalaryDetail.getHasIndividualIncomeTax().equals(1) ? financialSalaryDetail.getDetails().get(i).getIndividualIncomeTaxConfirm() : financialSalaryDetail.getDetails().get(i).getCurrentIndividualIncomeTax());
            writer.writeCellValue(11, i + 3, financialSalaryDetail.getDetails().get(i).getOtherCut());
            writer.writeCellValue(12, i + 3, financialSalaryDetail.getDetails().get(i).getRemark());
            row = i + 1;
        }
        writer.writeCellValue(0, row + 3, "合计");
        writer.writeCellValue(1, row + 3, "");
        writer.writeCellValue(2, row + 3, BigDecimal.valueOf(financialSalaryDetail.getDetails().stream().mapToDouble(v -> v.getPlanSalary().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        writer.writeCellValue(3, row + 3, BigDecimal.valueOf(financialSalaryDetail.getDetails().stream().mapToDouble(v -> v.getActuallySalary().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        writer.writeCellValue(4, row + 3, BigDecimal.valueOf(financialSalaryDetail.getDetails().stream().mapToDouble(v -> v.getBonusAmount().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        writer.writeCellValue(5, row + 3, BigDecimal.valueOf(financialSalaryDetail.getDetails().stream().mapToDouble(v -> v.getEndowmentInsurance().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        writer.writeCellValue(6, row + 3, BigDecimal.valueOf(financialSalaryDetail.getDetails().stream().mapToDouble(v -> v.getMedicalInsurance().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        writer.writeCellValue(7, row + 3, BigDecimal.valueOf(financialSalaryDetail.getDetails().stream().mapToDouble(v -> v.getUnemploymentBenefit().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        writer.writeCellValue(8, row + 3, BigDecimal.valueOf(financialSalaryDetail.getDetails().stream().mapToDouble(v -> v.getSeriousIllnessInsurance().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        writer.writeCellValue(9, row + 3, BigDecimal.valueOf(financialSalaryDetail.getDetails().stream().mapToDouble(v -> v.getHousingFund().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        writer.writeCellValue(10, row + 3, BigDecimal.valueOf(financialSalaryDetail.getDetails().stream().mapToDouble(v -> v.getIndividualIncomeTaxConfirm().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));
        writer.writeCellValue(11, row + 3, BigDecimal.valueOf(financialSalaryDetail.getDetails().stream().mapToDouble(v -> v.getOtherCut().doubleValue()).sum()).setScale(2, RoundingMode.HALF_UP));

        writer.writeCellValue(12, row + 3, "");

        // 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除之
        writer.setOnlyAlias(true);
        // 设置列宽行高
        writer.setDefaultRowHeight(22);
        // 设置第一行 列宽
        // writer.setColumnWidth(0, 20);
        // 合并单元格后的标题行，使用默认标题样式
//        writer.merge(9, "客户");
//        writer.setRowHeight(0, 22);
        //设置标题单元格 样式
        Font headFont = writer.createFont();
        // 设置字体大小，加载到样式中
        headFont.setFontHeightInPoints((short) 11);
        headFont.setFontName("楷体_GB2312");
        headFont.setBold(true);
        CellStyle headCellStyle = writer.getStyleSet().getHeadCellStyle();
        headCellStyle.setFont(headFont);
        headCellStyle.setAlignment(HorizontalAlignment.CENTER);
        headCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //设置普通单元格 样式
        Font contentFont = writer.createFont();
        // 设置字体大小，加载到样式中
        contentFont.setFontHeightInPoints((short) 11);
        contentFont.setFontName("宋体");
        CellStyle cellstyle = writer.getStyleSet().getCellStyle();
        cellstyle.setFont(contentFont);
        cellstyle.setAlignment(HorizontalAlignment.CENTER);
        cellstyle.setVerticalAlignment(VerticalAlignment.CENTER);
        writer.setRowHeight(1, 22);
        // headSize 为表格 标题 和 表头所占的 行数
        int headSize = 2;
        // 设置所有列宽自适应
        writer.autoSizeColumnAll();
        //out为OutputStream，需要写出到的目标流 response为HttpServletResponse对象
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        response.setHeader("Content-Disposition", "attachment;filename=test.xlsx");
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.flush(out, true);
        // 关闭writer，释放内存
        writer.close();
        //此处记得关闭输出Servlet流
        IoUtil.close(out);
    }


    @ApiOperation("打印工资信息")
    @PostMapping("/printDetailPdf")
    public void printDetailPdf(@RequestParam Long id, HttpServletResponse response) throws IOException, TemplateException {
        //查询工资对象
        BizFinancialSalaryDetail financialSalaryDetail = bizFinancialSalaryDetailService.getById(id);
        BizCompany company;

        if (null != financialSalaryDetail) {
            BizFinancialSalaryDetailEmployee map = new BizFinancialSalaryDetailEmployee();
            map.setFinancialSalaryDetailId(financialSalaryDetail.getId());
            //查询员工信息
            List<BizFinancialSalaryDetailEmployee> financialSalaryDetailEmployeeList = bizFinancialSalaryDetailEmployeeService.getList(map);
            financialSalaryDetail.setDetails(financialSalaryDetailEmployeeList);
            //计算每一列的合计金额
            for (BizFinancialSalaryDetailEmployee employee : financialSalaryDetailEmployeeList) {
                employee.setIndividualIncomeTax(financialSalaryDetail.getHasIndividualIncomeTax() == 1 ? employee.getIndividualIncomeTaxConfirm() : employee.getCurrentIndividualIncomeTax());
                financialSalaryDetail.setPlanSalary(financialSalaryDetail.getPlanSalary() == null ? employee.getPlanSalary() : financialSalaryDetail.getPlanSalary().add(employee.getPlanSalary()));
                financialSalaryDetail.setActuallySalary(financialSalaryDetail.getActuallySalary() == null ? employee.getActuallySalary() : financialSalaryDetail.getActuallySalary().add(employee.getActuallySalary()));
                financialSalaryDetail.setBonusAmount(financialSalaryDetail.getBonusAmount() == null ? employee.getBonusAmount() : financialSalaryDetail.getBonusAmount().add(employee.getBonusAmount()));
                financialSalaryDetail.setEndowmentInsurance(financialSalaryDetail.getEndowmentInsurance() == null ? employee.getEndowmentInsurance() : financialSalaryDetail.getEndowmentInsurance().add(employee.getEndowmentInsurance()));
                financialSalaryDetail.setMedicalInsurance(financialSalaryDetail.getMedicalInsurance() == null ? employee.getMedicalInsurance() : financialSalaryDetail.getMedicalInsurance().add(employee.getMedicalInsurance()));
                financialSalaryDetail.setUnemploymentBenefit(financialSalaryDetail.getUnemploymentBenefit() == null ? employee.getUnemploymentBenefit() : financialSalaryDetail.getUnemploymentBenefit().add(employee.getUnemploymentBenefit()));
                financialSalaryDetail.setSeriousIllnessInsurance(financialSalaryDetail.getSeriousIllnessInsurance() == null ? employee.getSeriousIllnessInsurance() : financialSalaryDetail.getSeriousIllnessInsurance().add(employee.getSeriousIllnessInsurance()));
                financialSalaryDetail.setHousingFund(financialSalaryDetail.getHousingFund() == null ? employee.getHousingFund() : financialSalaryDetail.getHousingFund().add(employee.getHousingFund()));
                financialSalaryDetail.setIndividualIncomeTax(financialSalaryDetail.getIndividualIncomeTax() == null ? employee.getIndividualIncomeTax() : financialSalaryDetail.getIndividualIncomeTax().add(employee.getIndividualIncomeTax()));
                financialSalaryDetail.setOtherCut(financialSalaryDetail.getOtherCut() == null ? employee.getOtherCut() : financialSalaryDetail.getOtherCut().add(employee.getOtherCut()));
            }
            if (financialSalaryDetailEmployeeList.size() == 0) {
                financialSalaryDetail.setPlanSalary(BigDecimal.valueOf(0));
                financialSalaryDetail.setActuallySalary(BigDecimal.valueOf(0));
                financialSalaryDetail.setBonusAmount(BigDecimal.valueOf(0));
                financialSalaryDetail.setEndowmentInsurance(BigDecimal.valueOf(0));
                financialSalaryDetail.setMedicalInsurance(BigDecimal.valueOf(0));
                financialSalaryDetail.setUnemploymentBenefit(BigDecimal.valueOf(0));
                financialSalaryDetail.setSeriousIllnessInsurance(BigDecimal.valueOf(0));
                financialSalaryDetail.setHousingFund(BigDecimal.valueOf(0));
                financialSalaryDetail.setIndividualIncomeTax(BigDecimal.valueOf(0));
                financialSalaryDetail.setOtherCut(BigDecimal.valueOf(0));
            }
            financialSalaryDetail.setTime(financialSalaryDetail.getYear() + "年" + " " + "第" + financialSalaryDetail.getMonth() + "期");

            //查询客户信息
            company = companyService.getById(financialSalaryDetail.getCompanyId());
            //获取客户名称
            financialSalaryDetail.setCompanyName(company.getName());
        } else {
            return;
        }
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("financialSalaryDetail", financialSalaryDetail);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        Writer out = new StringWriter();
        //获取模板地址
        Template template = freeMarkerConfigurer.getConfiguration().getTemplate("salaryTemplate.html");

        template.process(paramMap, out);
        out.flush();
        out.close();
        String templateContent = out.toString();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/pdf");

        String fileName = "工资表";
        response.setHeader("Content-Disposition", "filename=" + new String(fileName.getBytes()));
//        byte[] resources = PdfUtil.html2Pdf(2, templateContent, "/icon/logo.png", bizFinancialSalaryService);
        byte[] resources = PdfUtil.html2Pdf(templateContent, PageSize.A5.rotate());
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(resources);
        outputStream.close();
    }


    @PostMapping("/rpc/filterCompletedOrders")
    @Anonymous
    public String filterCompletedOrders(@RequestBody FilterRequest filterRequest) {
        List<Long> workOrderIds = filterRequest.getWorkOrderIds();
        Date sqlDate = filterRequest.getDate();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(sqlDate);
        int year = calendar.get(Calendar.YEAR);
        int month = sqlDate.getMonth() + 1;
        String format = String.format("%02d", month);
        int year2 = year;
        int month2 = month;

        // 处理一月份情况
        if (month2 == Calendar.JANUARY) {
            // 如果是1月份，设置为上年的12月份
            year2--; // 前一年
            month2 = Calendar.UNDECIMBER; // 上个月
        } else {
            // 其他月份，获取上个月
            month2--; // 上个月
        }
        String formattedMonth = String.format("%02d", month2);
        //通过 workOrderId 查询出所有代理记账公积金 社保是否有已完成
        //代理记账
        ArrayList<Long> oneList = new ArrayList<>();
        ArrayList<Long> twoList = new ArrayList<>();
        ArrayList<Long> threeList = new ArrayList<>();
        //通过workId筛选代理记账
        for (Long workOrderId : workOrderIds) {
            BizFinancialSalary bizFinancialSalary =
                    bizFinancialSalaryService.getOne(new LambdaQueryWrapper<BizFinancialSalary>()
                            .eq(BizFinancialSalary::getWorkOrderId, workOrderId));
            if (bizFinancialSalary != null) {
                List<BizFinancialSalaryDetail> list = bizFinancialSalaryDetailService.list(new LambdaQueryWrapper<BizFinancialSalaryDetail>()
                        .eq(BizFinancialSalaryDetail::getFinancialSalaryId, bizFinancialSalary.getId())
                        .eq(BizFinancialSalaryDetail::getYear, year2 + "")
                        .eq(BizFinancialSalaryDetail::getMonth, formattedMonth)
                        .eq(BizFinancialSalaryDetail::getStatus, 3));
                if (!CollectionUtils.isEmpty(list)) {
                    oneList.add(workOrderId);
                }
            }
        }
        if (!CollectionUtils.isEmpty(oneList)) {
            workOrderIds.removeAll(oneList);
        }

        //通过workId筛选社保代缴
        if (!CollectionUtils.isEmpty(workOrderIds)) {
            for (Long workOrderId : workOrderIds) {

                BizSocialSecurityConfirm one = socialSecurityConfirmService.getOne(new LambdaQueryWrapper<BizSocialSecurityConfirm>()
                        .eq(BizSocialSecurityConfirm::getWorkOrderId, workOrderId));
                if (one != null) {
                    List<BizSocialSecurityConfirmDetail> list = socialSecurityConfirmDetailService.list(new LambdaQueryWrapper<BizSocialSecurityConfirmDetail>()
                            .eq(BizSocialSecurityConfirmDetail::getSocialSecurityConfirmId, one.getId())
                            .eq(BizSocialSecurityConfirmDetail::getYear, year + "")
                            .eq(BizSocialSecurityConfirmDetail::getMonth, format)
                            .eq(BizSocialSecurityConfirmDetail::getStatus, 3));
                    if (!CollectionUtils.isEmpty(list)) {
                        twoList.add(workOrderId);
                    }
                }
            }
        }
        if (!CollectionUtils.isEmpty(twoList)) {
            workOrderIds.removeAll(twoList);
        }
        if (!CollectionUtils.isEmpty(workOrderIds)) {
            //通过workId筛选公积金
            for (Long workOrderId : workOrderIds) {
                BizHousingFundConfirm one = housingFundConfirmService.getOne(new LambdaQueryWrapper<BizHousingFundConfirm>()
                        .eq(BizHousingFundConfirm::getWorkOrderId, workOrderId));
                if (one != null) {
                    List<BizHousingFundConfirmDetail> list = housingFundConfirmDetailService.list(new LambdaQueryWrapper<BizHousingFundConfirmDetail>()
                            .eq(BizHousingFundConfirmDetail::getHousingFundConfirmId, one.getId())
                            .eq(BizHousingFundConfirmDetail::getYear, year + "")
                            .eq(BizHousingFundConfirmDetail::getMonth, format)
                            .eq(BizHousingFundConfirmDetail::getStatus, 3));
                    if (!CollectionUtils.isEmpty(list)) {
                        threeList.add(workOrderId);
                    }
                }

            }
        }
        if (!CollectionUtils.isEmpty(threeList)) {
            workOrderIds.removeAll(threeList);
        }
        Map<String, List<Long>> map = new HashMap<>();
        map.put("oneList", oneList);
        map.put("twoList", twoList);
        map.put("threeList", threeList);
        map.put("workOrderIds", workOrderIds);
        return JSON.toJSONString(map);


    }
}
