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

import cn.ezhizao.common.utils.SecurityUtils;
import cn.ezhizao.common.utils.StringUtils;
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.lock.DistributionLock;
import cn.ezhizao.framework.lock.LockKey;
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.entrust.domain.BizEntrust;
import cn.ezhizao.project.business.entrust.service.IBizEntrustService;
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.IBizFinancialIndividualIncomeTaxDetailIsZeroService;
import cn.ezhizao.project.business.finance.IndividualIncomeTaxIsZero.service.IBizFinancialIndividualIncomeTaxIsZeroService;
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.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.BizFinancialSalary;
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.service.IBizFinancialSalaryDetailEmployeeService;
import cn.ezhizao.project.business.salary.service.IBizFinancialSalaryDetailService;
import cn.ezhizao.project.business.salary.service.IBizFinancialSalaryService;
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.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.ezhizao.project.tenant.service.ITenantService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.tomcat.jni.Lock;
import org.springframework.beans.BeanUtils;
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 javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 零申报工资Controller
 *
 * @author ruoyi
 * @date 2023-11-16
 */
@RestController
@RequestMapping("/business/salaryZero")
public class BizFinancialSalaryZeroController 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;
    @Resource
    private IBizSocialSecurityConfirmDetailService socialSecurityConfirmDetailService;
    @Resource
    private IBizFinancialSalaryDetailEmployeeService bizFinancialSalaryDetailEmployeeService;
    @Resource
    private IBizFinancialKeepAccountService financialKeepAccountService;
    @Resource
    private IBizFinancialKeepAccountDetailService financialKeepAccountDetailService;

    @Resource
    private IBizHousingFundConfirmDetailEmployeeService housingFundConfirmDetailEmployeeService;
    @Resource
    private IBizHousingFundConfirmDetailService housingFundConfirmDetailService;

    @Resource
    private IBizSocialSecurityConfirmDetailEmployeeService socialSecurityConfirmDetailEmployeeService;
    @Resource
    private IBizEntrustService bizEntrustService;

    @Resource
    private ITenantService tenantService;
    /**
     * 查询工资列表
     */
    @PreAuthorize("@ss.hasPermi('business:salaryZero: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.setIsZero(1);
        bizFinancialSalary.setYear(String.valueOf(nwoYear));
        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)
                        .eq("deleted", 0).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())
                        .eq("deleted", 0).list();
                list.forEach(l -> {
                    l.setDetails(details.stream().filter(v -> v.getFinancialSalaryId().equals(l.getId())).collect(Collectors.toList()));
                });
            }
        }
        return getDataTable(list);
    }

    @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.IMPORT)
    @PreAuthorize("@ss.hasPermi('business:salaryZero: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(), 1);
        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:salaryZero: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("/{ids}")
    public AjaxResult removeByIds(@PathVariable List<Long> ids) {
        return toAjax(bizFinancialSalaryService.removeBatchByIds(ids));
    }

    @PreAuthorize("@ss.hasAnyPermi('business:salaryZero:query,business:salaryZero:edit,business:salaryZero: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.SALARYZERO, 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(), "填写工资信息"));
        } finally {
            lock.unlock();
        }

    }

    @PreAuthorize("@ss.hasPermi('business:salary:edit')")
    @Log(title = "生产管理-工资零申报-更新", businessType = BusinessType.UPDATE)
    @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(), "修改工资信息"));
    }

    @PreAuthorize("@ss.hasPermi('business:salaryZero:verify')")
    @PostMapping("/verifyDetail")
    @Log(title = "生产管理-公司零申报-审核通过", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult verifyDetail(@RequestBody BizFinancialSalaryDetail bizFinancialSalaryDetail) {
        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(), "工资审核通过");
        } 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);
    }

    @PreAuthorize("@ss.hasPermi('business:salaryZero:back')")
    @PostMapping("/turnBackDetail")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "生产管理-工资零申报-审核退回", businessType = BusinessType.UPDATE)
    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());
            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);
                financialKeepAccountDetail.setReceiveDate((Timestamp) financialReceiveTicketDetail.getReceiveDate());
//                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.setCompanyId(bizFinancialSalary.getCompanyId());
            record.setTenantId(fromRecord.getTenantId());
            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);
        }
    }

    /**
     * 导出工资列表
     */
    @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(1);
        //查询数据
//        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("");
//            } else {
//                salaryDetail = bizFinancialSalaryDetails.get(0);
//                SysUser sysUser = sysUserMapper.selectUserById(salaryDetail.getVerifierId());
//                salary.setServiceName(sysUser == null ? "" : sysUser.getNickName());
//            }
            if (detailMap.get(query) == null) {
                salaryDetail.setStatus(0);
                salary.setServiceName("");
            } else {
                salaryDetail = detailMap.get(query);
                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, "工资数据");
    }
}
