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

import cn.ezhizao.common.utils.PdfUtil;
import cn.ezhizao.common.utils.SecurityUtils;
import cn.ezhizao.common.utils.poi.ExcelUtil;
import cn.ezhizao.framework.aspectj.lang.annotation.Excel;
import cn.ezhizao.framework.aspectj.lang.annotation.Log;
import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;
import cn.ezhizao.framework.web.controller.BaseController;
import cn.ezhizao.framework.web.domain.AjaxResult;
import cn.ezhizao.framework.web.page.TableDataInfo;
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.housingFund.domain.BizHousingFundConfirmDetail;
import cn.ezhizao.project.business.housingFund.domain.BizHousingFundConfirmDetailEmployee;
import cn.ezhizao.project.business.salary.domain.BizFinancialSalaryDetail;
import cn.ezhizao.project.business.salary.domain.BizFinancialSalaryDetailEmployee;
import cn.ezhizao.project.business.socialSecurity.domain.*;
import cn.ezhizao.project.business.socialSecurity.service.*;
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.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itextpdf.text.FontFactory;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import io.swagger.annotations.Api;
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.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.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.xhtmlrenderer.pdf.ITextRenderer;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author 周晓
 */
@RestController
@Api(tags = "FinancialSocialSecurityConfirm数据接口")
@RequestMapping(value = "/business/socialSecurityConfirm")
public class SocialSecurityConfirmController extends BaseController {

    @Resource
    IBizSocialSecurityConfirmService socialSecurityConfirmService;
    @Resource
    IBizCompanyService companyService;
    @Resource
    IBizSocialSecurityConfirmDetailService socialSecurityConfirmDetailService;
    @Resource
    IBizSocialSecurityConfirmDetailEmployeeService socialSecurityConfirmDetailEmployeeService;
    @Resource
    SysUserMapper sysUserMapper;

    @Value("${ruoyi.pdfTemplate.url}")
    private String templatePath;

    /**
     * 生成pdf
     */
    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    @Resource
    IBizSocialSecurityDeclareService socialSecurityDeclareService;
    @Resource
    IBizSocialSecurityDeclareDetailService socialSecurityDeclareDetailService;

    @Resource
    IBizWorkOrderRecordService bizWorkOrderRecordService;

    @ApiOperation(value = "根据id查询", notes = "根据id查询")
    @GetMapping("/getById/{id}")
    @ResponseBody
    public AjaxResult getById(@PathVariable Long id) {
        return success(socialSecurityConfirmService.getById(id));
    }


    @PreAuthorize("@ss.hasAnyPermi('business:socialSecurityConfirm:query,business:socialSecurityConfirm:view')")
    @PostMapping("/getDetail")
    public AjaxResult getDetail(@RequestBody BizSocialSecurityConfirmDetail condition) {
//        List<BizSocialSecurityConfirmDetail> socialSecurityConfirmDetails = socialSecurityConfirmDetailService.getListByBean(condition);
        List<BizSocialSecurityConfirmDetail> socialSecurityConfirmDetails = socialSecurityConfirmDetailService.BaseResultMap2(condition);

        BizCompany company = companyService.getById(condition.getCompanyId());
        if (socialSecurityConfirmDetails.isEmpty()) {
            // 获取上个月的工资人员信息
            // 先获取之前的一个月是否已填报，然后获取填报后的工资人员信息
            BizSocialSecurityConfirmDetail detail = socialSecurityConfirmDetailService.query()
                    .eq("social_security_confirm_id", condition.getSocialSecurityConfirmId()).lt("concat(year,month)", condition.getYear() + condition.getMonth()).orderByDesc("concat(year, month)").last("limit 1").one();
            if (detail != null) {
                //获取当前月份人员详情中不等于删除状态的人员
                List<BizSocialSecurityConfirmDetailEmployee> employees = socialSecurityConfirmDetailEmployeeService.query()
                        .eq("social_security_confirm_detail_id", detail.getId())
                        .ne("change_status",2)
                        .list();


                employees.forEach(em->{
                    em.setId(null);
                    em.setChangeStatus(0);});
                condition.setDetails(employees);
            } else {
                condition.setDetails(new ArrayList<>());
            }
            condition.setEmployeePassword(company.getEmployeePassword());
            condition.setGovernmentAccountNo(company.getGovernmentAccountNo());
            condition.setGovernmentPassword(company.getGovernmentPassword());
            condition.setSocialSecurityAccountNo(company.getSocialSecurityAccountNo());
            condition.setSocialSecurityPassword(company.getSocialSecurityPassword());
            condition.setIsFirstSocialSecurity(company.getIsFirstSocialSecurity());
            return success(condition);
        }
        return success(socialSecurityConfirmDetails.get(0));
    }

    @PostMapping("/save")
    @ApiOperation(value = "保存", notes = "保存")
    @ResponseBody
    public AjaxResult save(@RequestBody BizSocialSecurityConfirm financialSocialSecurityConfirm) {
        return (financialSocialSecurityConfirm.getId() == null ? socialSecurityConfirmService.save(financialSocialSecurityConfirm) : socialSecurityConfirmService.updateById(financialSocialSecurityConfirm)) ? success() : error();
    }

    @PostMapping("/saveBatch")
    @ApiOperation(value = "批量保存", notes = "批量保存")
    @ResponseBody
    public AjaxResult saveBatch(@RequestBody List<BizSocialSecurityConfirm> list) {
        return socialSecurityConfirmService.saveOrUpdateBatch(list) ? success() : error();
    }

    @ApiOperation(value = "删除", notes = "删除")
    @GetMapping("/deleteById/{id}")
    @ResponseBody
    public AjaxResult deleteById(@PathVariable Long id) {
        return socialSecurityConfirmService.removeById(id) ? success() : error();
    }

    @ApiOperation(value = "批量删除", notes = "批量删除")
    @PostMapping("/batchDelete")
    @ResponseBody
    public AjaxResult batchDelete(@RequestBody List<Long> list) {
        return socialSecurityConfirmService.removeBatchByIds(list) ? success() : error();
    }

    @ApiOperation(value = "带条件List 分页查询", notes = "带条件List 分页查询")
    @PreAuthorize("@ss.hasPermi('business:socialSecurityConfirm:list')")
    @GetMapping("/list")
    @ResponseBody
    public TableDataInfo getList(BizSocialSecurityConfirm conditions) throws NoSuchFieldException, IllegalAccessException {
        String chooseYear = conditions.getYear();
        int nwoYear = LocalDate.now().getYear();
        setTenantId(conditions);
        startPage();
        startOrderBy();
        conditions.setYear(String.valueOf(nwoYear));
        List<BizSocialSecurityConfirm> list = socialSecurityConfirmService.getListByBean(conditions);
        if (!list.isEmpty()) {
            BizSocialSecurityConfirmDetail detailConditions = new BizSocialSecurityConfirmDetail();
            if (!chooseYear.equals(nwoYear)){
                detailConditions.setYear(chooseYear);
            }else {
                detailConditions.setYear(conditions.getYear());
            }
            detailConditions.setMainIds(list.stream().map(BizSocialSecurityConfirm::getId).collect(Collectors.toList()));
            List<BizSocialSecurityConfirmDetail> details = socialSecurityConfirmDetailService.getListByBean(detailConditions);
            list.forEach(l -> {
                l.setDetails(details.stream().filter(v -> v.getSocialSecurityConfirmId().equals(l.getId())).collect(Collectors.toList()));
            });
        }

        return getDataTable(list);
    }

    @ApiOperation("获取之前的员工信息")
    @PostMapping("/getPrevEmployee")
    @ResponseBody
    public AjaxResult getPrevEmployee(@RequestBody BizSocialSecurityConfirmDetail entity) {
        BizSocialSecurityConfirmDetail detail = socialSecurityConfirmDetailService.query().eq("social_security_confirm_id", entity.getSocialSecurityConfirmId()).lt("concat(year,month)", entity.getYear() + entity.getMonth()).orderByDesc("concat(year, month)").last("limit 1").one();
        if (detail != null) {
            List<BizSocialSecurityConfirmDetailEmployee> employees = socialSecurityConfirmDetailEmployeeService.query().eq("social_security_confirm_detail_id", detail.getId()).ne("change_status", 2).list();
            return success(employees);
        }
        return success(new ArrayList<>());
    }

    @ApiOperation("审核")
    @PostMapping("/verify")
    @ResponseBody
    public AjaxResult verify(@RequestBody BizSocialSecurityConfirmDetail detail) {
        if (detail.getStatus().equals(3)) {
            QueryWrapper<BizSocialSecurityDeclare> qw = new QueryWrapper<>();
            qw.eq("company_id", detail.getCompanyId());

            BizSocialSecurityDeclare financialSocialSecurityDeclare = socialSecurityDeclareService.getOne(qw);
            if (financialSocialSecurityDeclare != null) {
                QueryWrapper<BizSocialSecurityDeclareDetail> kqw = new QueryWrapper<>();
                kqw.eq("social_security_declare_id", financialSocialSecurityDeclare.getId());
                kqw.eq("year", detail.getYear());
                kqw.eq("month", detail.getMonth());
                BizSocialSecurityDeclareDetail financialSocialSecurityDeclareDetail =
                        socialSecurityDeclareDetailService.getOne(kqw);
                if (financialSocialSecurityDeclareDetail == null) {
                    financialSocialSecurityDeclareDetail = new BizSocialSecurityDeclareDetail();
                }
                financialSocialSecurityDeclareDetail.setSocialSecurityDeclareId(financialSocialSecurityDeclare.getId());
                financialSocialSecurityDeclareDetail.setYear(detail.getYear());
                financialSocialSecurityDeclareDetail.setMonth(detail.getMonth());
                financialSocialSecurityDeclareDetail.setCompanyId(detail.getCompanyId());
                financialSocialSecurityDeclareDetail.setStatus(financialSocialSecurityDeclareDetail.getStatus() != null && financialSocialSecurityDeclareDetail.getStatus() > 1 ? financialSocialSecurityDeclareDetail.getStatus() : 1);

                if (financialSocialSecurityDeclareDetail.getId() == null) {
                    socialSecurityDeclareDetailService.save(financialSocialSecurityDeclareDetail);
                } else {
                    socialSecurityDeclareDetailService.updateById(financialSocialSecurityDeclareDetail);
                }
            }
        }
        return socialSecurityConfirmDetailService.updateById(detail) ? success() : error();
    }

    @PreAuthorize("@ss.hasPermi('business:socialSecurityConfirm:edit')")
    @PostMapping("/saveDetail")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "社保人员信息-新增", businessType = BusinessType.INSERT)
    public AjaxResult saveDetail(@RequestBody BizSocialSecurityConfirmDetail detail) {
        // 判断之前是否有保存一个明细
        BizSocialSecurityConfirmDetail conditions = new BizSocialSecurityConfirmDetail();
        conditions.setSocialSecurityConfirmId(detail.getSocialSecurityConfirmId());
        conditions.setYear(detail.getYear());
        conditions.setMonth(detail.getMonth());
        if (!socialSecurityConfirmDetailService.getListByBean(conditions).isEmpty()) {
            return error("该月已添加人员信息,请刷新列表。");
        }
        BizCompany company = companyService.getById(detail.getCompanyId());
//        if (company.getIsFirstSocialSecurity() == 0) {
        company.setGovernmentAccountNo(detail.getGovernmentAccountNo());
        company.setGovernmentPassword(detail.getGovernmentPassword());
        company.setSocialSecurityAccountNo(detail.getSocialSecurityAccountNo());
        company.setSocialSecurityPassword(detail.getSocialSecurityPassword());
        company.setEmployeePassword(detail.getEmployeePassword());
        company.setIsFirstSocialSecurity(1);
        companyService.updateById(company);

        // 获取上个月的人员信息
        List<BizSocialSecurityConfirmDetailEmployee> employees = detail.getDetails().stream().filter(v -> v.getChangeStatus()==null || v.getChangeStatus() != 2).collect(Collectors.toList());
        BizSocialSecurityConfirmDetail old = socialSecurityConfirmDetailService.query().eq("social_security_confirm_id", detail.getSocialSecurityConfirmId()).lt("concat(year,month)", detail.getYear() + detail.getMonth()).orderByDesc("concat(year, month)").last("limit 1").one();
        if(old != null) {
            List<BizSocialSecurityConfirmDetailEmployee> oldEmployees = socialSecurityConfirmDetailEmployeeService.query().eq("social_security_confirm_detail_id", old.getId()).ne("change_status", 2).list();
            employees.forEach(l -> {
                // 判断是新增还是不变
                if(oldEmployees.stream().anyMatch(v -> v.getPhone().equals(l.getPhone()) && v.getEmployeeName().equals(l.getEmployeeName()))) {
                    l.setChangeStatus(0);
                }
                if (oldEmployees.stream().noneMatch(v -> v.getPhone().equals(l.getPhone()) && v.getEmployeeName().equals(l.getEmployeeName()))) {
                    l.setChangeStatus(1);
                }
            });
            oldEmployees.stream().filter(v -> employees.stream().noneMatch(l -> v.getPhone().equals(l.getPhone()) && v.getEmployeeName().equals(l.getEmployeeName()))).forEach(l -> {
                BizSocialSecurityConfirmDetailEmployee item = new BizSocialSecurityConfirmDetailEmployee();
                item.setChangeStatus(2);
                item.setCompanyId(detail.getCompanyId());
                item.setPhone(l.getPhone());
                item.setEmployeeName(l.getEmployeeName());
                item.setCardinalNumber(l.getCardinalNumber());
                item.setIdCardImage(l.getIdCardImage());
                item.setIdCardImageBack(l.getIdCardImageBack());
                item.setMedicalCardinalNumber(l.getMedicalCardinalNumber());
                employees.add(item);
            });
        }


        return toAjax(socialSecurityConfirmDetailService.save(detail) && addRecord(detail.getSocialSecurityConfirmId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "填写社保人员信息"));
    }

    @Log(title = "社保导入", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('business:socialSecurityConfirm:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, @RequestParam String year, @RequestParam String month) throws Exception
    {
        ExcelUtil<BizSocialSecurityConfirmDetailEmployee> util = new ExcelUtil<>(BizSocialSecurityConfirmDetailEmployee.class);
        List<BizSocialSecurityConfirmDetailEmployee> detailList = util.importExcel(file.getInputStream());

        // 获取 入Excel 表头字段
        List<String> excelHeaders = util.readExcelHeaders(file.getInputStream());
        //获取实体类字段
        List<String> names=getExcelAnnotatedFields(BizSocialSecurityConfirmDetailEmployee.class);
        //如果不存在模板中的字段，返回错误
        if (!excelHeaders.containsAll(names)) {
            return error("导入数据与模板不匹配！");
        }

        String message=socialSecurityConfirmService.importSecurityConfirm(detailList,year,month,getTenantId()==null?0:getTenantId());
        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;
    }

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

    @PreAuthorize("@ss.hasPermi('business:socialSecurityConfirm:edit')")
    @PostMapping("/updateDetail")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateDetail(@RequestBody BizSocialSecurityConfirmDetail detail) {

        BizSocialSecurityConfirmDetail oldDetail = socialSecurityConfirmDetailService.query()
                .eq("social_security_confirm_id", detail.getSocialSecurityConfirmId())
                .lt("concat(year,month)", detail.getYear() + detail.getMonth())
                .orderByDesc("concat(year, month)")
                .last("limit 1").one();

        List<BizSocialSecurityConfirmDetailEmployee> employees;
        if (oldDetail != null) {
            employees = socialSecurityConfirmDetailEmployeeService.query()
                    .eq("social_security_confirm_detail_id", oldDetail.getId())
                    .ne("change_status",2)
                    .list();
        } else {
            employees = new ArrayList<>();
        }

        for (BizSocialSecurityConfirmDetailEmployee employee : detail.getDetails()) {
            if (employee.getChangeStatus() == 2) {
                Boolean deleted = employees.stream()
                        .noneMatch(e -> e.getEmployeeName().equals(employee.getEmployeeName())
                                && e.getPhone().equals(employee.getPhone()));
                employee.setDeleted(deleted ? 1 : 0);
            }
        }

        BizCompany company = companyService.getById(detail.getCompanyId());
//        if (company.getIsFirstSocialSecurity() == 0) {
        company.setGovernmentAccountNo(detail.getGovernmentAccountNo());
        company.setGovernmentPassword(detail.getGovernmentPassword());
        company.setSocialSecurityAccountNo(detail.getSocialSecurityAccountNo());
        company.setSocialSecurityPassword(detail.getSocialSecurityPassword());
        company.setEmployeePassword(detail.getEmployeePassword());
        company.setIsFirstSocialSecurity(1);
        companyService.updateById(company);

        return toAjax(socialSecurityConfirmDetailService.updateById(detail) && addRecord(detail.getSocialSecurityConfirmId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "修改社保人员信息"));
    }



    @PreAuthorize("@ss.hasPermi('business:socialSecurityConfirm:edit')")
    @PostMapping("/checkEmployees")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult checkEmployees(@RequestBody BizSocialSecurityConfirmDetail detail) {
        List<BizSocialSecurityConfirmDetailEmployee> employees =Optional.ofNullable(detail.getDetails().stream().filter(v ->  v.getChangeStatus() == null ||v.getChangeStatus() != 2).collect(Collectors.toList())).orElse(null) ;
        BizSocialSecurityConfirmDetail old = socialSecurityConfirmDetailService.query().eq("social_security_confirm_id", detail.getSocialSecurityConfirmId()).lt("concat(year,month)", detail.getYear() + detail.getMonth()).orderByDesc("concat(year, month)").last("limit 1").one();
        if (old == null) {
            // 第一次不判断是否相同
            return success(true);
        }
        List<BizSocialSecurityConfirmDetailEmployee> oldEmployees = socialSecurityConfirmDetailEmployeeService.query().eq("social_security_confirm_detail_id", old.getId()).ne("change_status", 2).list();
        // 判断是否有删除
        if (oldEmployees.stream().anyMatch(v -> employees.stream().noneMatch(e -> e.getEmployeeName().equals(v.getEmployeeName()) && e.getPhone().equals(v.getPhone())))) {
            // 判断为有删除变更
            return success(false);
        }
        // 判断是否有新增变更
        if (employees.stream().anyMatch(v -> oldEmployees.stream().noneMatch(e -> e.getEmployeeName().equals(v.getEmployeeName()) && e.getPhone().equals(v.getPhone())))) {
            // 判断是否有新增变更
            return success(false);
        }
        return success(true);
    }

    @PreAuthorize("@ss.hasPermi('business:socialSecurityConfirm:verify')")
    @PostMapping("/verifyDetail")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult verifyDetail(@RequestBody BizSocialSecurityConfirmDetail detail) {
        boolean bool = true;
        detail.setVerifierId(SecurityUtils.getUserId());
        if (detail.getStatus().equals(3)) {
            BizSocialSecurityConfirm bizSocialSecurityConfirm = socialSecurityConfirmService.getById(detail.getSocialSecurityConfirmId());
            QueryWrapper<BizSocialSecurityDeclare> qw = new QueryWrapper<>();
            qw.eq("work_order_id", bizSocialSecurityConfirm.getWorkOrderId());

            BizSocialSecurityDeclare bizSocialSecurityDeclare = socialSecurityDeclareService.getOne(qw);
            if (bizSocialSecurityDeclare != null) {
                QueryWrapper<BizSocialSecurityDeclareDetail> kqw = new QueryWrapper<>();
                kqw.eq("social_security_declare_id", bizSocialSecurityDeclare.getId());
                kqw.eq("year", detail.getYear());
                kqw.eq("month", detail.getMonth());
                BizSocialSecurityDeclareDetail socialSecurityDeclareDetail =
                        socialSecurityDeclareDetailService.getOne(kqw);
                if (socialSecurityDeclareDetail == null) {
                    socialSecurityDeclareDetail = new BizSocialSecurityDeclareDetail();
                }
                socialSecurityDeclareDetail.setSocialSecurityDeclareId(bizSocialSecurityDeclare.getId());
                socialSecurityDeclareDetail.setYear(detail.getYear());
                socialSecurityDeclareDetail.setMonth(detail.getMonth());
                socialSecurityDeclareDetail.setCompanyId(detail.getCompanyId());
                socialSecurityDeclareDetail.setStatus(socialSecurityDeclareDetail.getStatus() != null && socialSecurityDeclareDetail.getStatus() > 1 ? socialSecurityDeclareDetail.getStatus() : 1);

                if (socialSecurityDeclareDetail.getId() == null) {
                    bool = socialSecurityDeclareDetailService.save(socialSecurityDeclareDetail);
                } else {
                    bool = socialSecurityDeclareDetailService.updateById(socialSecurityDeclareDetail);
                }
            }
            bool = bool && addRecord(detail.getSocialSecurityConfirmId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "社保人员信息审核通过");
//            return bool;
        } else {
            bool = bool && addRecord(detail.getSocialSecurityConfirmId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "社保人员信息审核不通过");
        }
        detail.setVerifierTime(new Date());
        bool = bool && socialSecurityConfirmDetailService.updateById(detail);
        return toAjax(bool);
    }

    @PreAuthorize("@ss.hasPermi('business:socialSecurityConfirm:return')")
    @PostMapping("/turnBackDetail")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult turnBackDetail(@RequestBody BizSocialSecurityConfirmDetail detail) {
        // 先判断是否社保申报完成，申报完成状态不能进行工资退回
        BizSocialSecurityDeclareDetail financialReceiveTicketDetail = socialSecurityDeclareDetailService.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(socialSecurityConfirmDetailService.updateById(detail) && addRecord(detail.getSocialSecurityConfirmId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "社保人员退回"));
    }

    private boolean addRecord(Long mainId, String year, String month, Long recorderId, String description) {
        // 没拆分合同单价
        BizSocialSecurityConfirm socialSecurityConfirm = socialSecurityConfirmService.getById(mainId);
        Long workOrderId = socialSecurityConfirm.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(socialSecurityConfirm.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.setWorkOrderId(fromRecord.getWorkOrderId());
            record.setCompanyId(socialSecurityConfirm.getCompanyId());
            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(socialSecurityConfirm.getCompanyId());
            fromRecord.setStatus(1);
            fromRecord.setStatusDescript(description);
            fromRecord.setRecorderId(recorderId);
            return bizWorkOrderRecordService.save(record) &&
                    bizWorkOrderRecordService.updateById(fromRecord);
        }
    }

    /**
     * 导出列表
     */
    @PreAuthorize("@ss.hasPermi('business:socialSecurityConfirm:export')")
    @Log(title = "个税详情", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BizSocialSecurityConfirm financialSocialSecurityConfirm) throws NoSuchFieldException, IllegalAccessException
    {
        setTenantId(financialSocialSecurityConfirm);
        List<BizSocialSecurityConfirm> list = socialSecurityConfirmService.getListByBean(financialSocialSecurityConfirm);
        for (BizSocialSecurityConfirm l: list){
            l.setCurrentPeriod(financialSocialSecurityConfirm.getYear()+"-"+financialSocialSecurityConfirm.getMonth());
            BizSocialSecurityConfirmDetail detail = new BizSocialSecurityConfirmDetail();
            detail.setSocialSecurityConfirmId(l.getId());
            detail.setYear(financialSocialSecurityConfirm.getYear());
            detail.setMonth(financialSocialSecurityConfirm.getMonth());
            List<BizSocialSecurityConfirmDetail> details = socialSecurityConfirmDetailService.getListByBean(detail);
            if(details.size() == 0){
                l.setStatusText("未开始");
                l.setServiceName("");
            }else{
                detail=details.get(0);
                SysUser sysUser = sysUserMapper.selectUserById(detail.getVerifierId());
                l.setServiceName(sysUser==null?"":sysUser.getNickName());
                switch (detail.getStatus()){
                    case 0:
                        l.setStatusText("未开始");
                        break;
                    case 2:
                        l.setStatusText("待审核");
                        break;
                    case 3:
                        l.setStatusText("已完成");
                        break;
                    case 4:
                        l.setStatusText("驳回待处理");
                        break;
                    default:
                        break;
                }
            }
        }
        ExcelUtil<BizSocialSecurityConfirm> util = new ExcelUtil<BizSocialSecurityConfirm>(BizSocialSecurityConfirm.class);
        util.exportExcel(response, list, "社保人员确认数据");
    }

    @ApiOperation("导出社保人员信息")
    @PostMapping("/exportSocialSecurityExcel")
    public void exportDetailExcel(@RequestParam Long id, HttpServletResponse response) {
        BizSocialSecurityConfirmDetail socialSecurityConfirm = socialSecurityConfirmDetailService.getById(id);
        BizCompany company;

        if (null != socialSecurityConfirm) {
            Map<String, Object> map = new HashMap<>();
            map.put("socialSecurityConfirmDetailId", socialSecurityConfirm.getId());
            List<BizSocialSecurityConfirmDetailEmployee> socialSecurityDetailEmployeeList = socialSecurityConfirmDetailEmployeeService.getList(map);
            socialSecurityConfirm.setDetails(socialSecurityDetailEmployeeList);
            company = companyService.getById(socialSecurityConfirm.getCompanyId());
        } else {
            return;
        }
        ExcelWriter writer = cn.hutool.poi.excel.ExcelUtil.getWriter(true);
        writer.merge(0, 0, 0, 5, "社保人员信息", true);
        writer.merge(1, 1, 0, 3, company.getName(), false);
        writer.merge(1, 1, 4, 5, socialSecurityConfirm.getYear() + "年 第" + socialSecurityConfirm.getMonth() + "期", 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, "备注");

        int row = 0;
        for (int i = 0; i < socialSecurityConfirm.getDetails().size(); i++) {
            writer.writeCellValue(0, i + 3, socialSecurityConfirm.getDetails().get(i).getEmployeeName());
            writer.writeCellValue(1, i + 3, socialSecurityConfirm.getDetails().get(i).getPhone());
            writer.writeCellValue(2, i + 3, socialSecurityConfirm.getDetails().get(i).getHeatingFee());
            writer.writeCellValue(3, i + 3, socialSecurityConfirm.getDetails().get(i).getCardinalNumber());
            writer.writeCellValue(4, i + 3, socialSecurityConfirm.getDetails().get(i).getMedicalCardinalNumber());
            writer.writeCellValue(5, i + 3, socialSecurityConfirm.getDetails().get(i).getRemark());

            row = i + 1;
        }

        // 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除之
        writer.setOnlyAlias(true);
        // 设置列宽行高
        writer.setDefaultRowHeight(22);

        // 设置所有列宽自适应
        writer.autoSizeColumnAll();
        // 设置 列宽
        writer.setColumnWidth(0, 10);
        writer.setColumnWidth(1, 15);
        writer.setColumnWidth(2, 10);
        writer.setColumnWidth(3, 10);
        writer.setColumnWidth(4, 10);
        writer.setColumnWidth(5, 10);

        //设置标题单元格 样式
        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 = 3;

        //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("/SocialSecurityPdf")
    public void SocialSecurityPdf(@RequestParam Long id, HttpServletResponse response) throws IOException, TemplateException {
        BizSocialSecurityConfirmDetail socialSecurityConfirm = socialSecurityConfirmDetailService.getById(id);
        BizCompany company;

        if (null != socialSecurityConfirm) {
            Map<String, Object> map = new HashMap<>();
            map.put("socialSecurityConfirmDetailId", socialSecurityConfirm.getId());
            List<BizSocialSecurityConfirmDetailEmployee> socialSecurityDetailEmployeeList = socialSecurityConfirmDetailEmployeeService.getList(map);
            socialSecurityConfirm.setDetails(socialSecurityDetailEmployeeList);
            company = companyService.getById(socialSecurityConfirm.getCompanyId());
            socialSecurityConfirm.setTime(" "+socialSecurityConfirm.getYear()+"年"+" "+"第"+socialSecurityConfirm.getMonth()+"期");
            socialSecurityConfirm.setCompanyName(company.getName());
        } else {
            return;
        }
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("socialSecurityConfirm" , socialSecurityConfirm);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        Writer out = new StringWriter();
        //获取模板地址
        Template template = freeMarkerConfigurer.getConfiguration().getTemplate("socialSecurityTemplate.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(templateContent);
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(resources);
        outputStream.close();
    }



}
