package com.yh.saas.plugin.yiliangyiyun.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.google.common.collect.Lists;
import com.winsea.svc.base.base.entity.CommonRoleResource;
import com.winsea.svc.base.base.service.ICommonRoleResourceService;
import com.winsea.svc.base.base.util.DateUtils;
import com.winsea.svc.base.security.entity.User;
import com.winsea.svc.base.security.util.AuthSecurityUtils;
import com.winsea.svc.base.workflow.entity.Workflow;
import com.yh.saas.common.support.util.IdGenerator;
import com.yh.saas.plugin.base.service.ICommonBillOperateHisService;
import com.yh.saas.plugin.yiliangyiyun.constant.NumberConstant;
import com.yh.saas.plugin.yiliangyiyun.constant.StatusEnum;
import com.yh.saas.plugin.yiliangyiyun.entity.*;
import com.yh.saas.plugin.yiliangyiyun.exception.YException;
import com.yh.saas.plugin.yiliangyiyun.exception.YExceptionEnum;
import com.yh.saas.plugin.yiliangyiyun.mapper.ExpenseInfoMapper;
import com.yh.saas.plugin.yiliangyiyun.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 记录费用表信息 服务实现类
 * </p>
 *
 * @author Gdc
 * @since 2022-05-29
 */
@Service
@Slf4j
public class ExpenseInfoServiceImpl extends ServiceImpl<ExpenseInfoMapper, ExpenseInfo> implements IExpenseInfoService {
    @Autowired
    private INewWorkflowService workflowService;
    @SofaReference
    private ICommonRoleResourceService roleResourceService;
    @Autowired
    private IExpenseAllocationInfoService expenseAllocationInfoService;
    @Autowired
    private ICommonBillOperateHisService billOperateHisService;
    @Autowired
    private IWarehousingOrderService warehousingOrderService;
    @Autowired
    private IContractExpensesInfoService contractExpensesInfoService;
    @Autowired
    private IContractManagementInfoService contractManagementInfoService;
    @Autowired
    private IWarehouseBaseInfoService warehouseBaseInfoService;
    @Value("${file-root-path}")
    private String localPath;
    @Autowired
    private OSSClient ossClient;
    @Value("${oss.endpoint.internal:}")
    private String baseUrl;
    @Getter
    @Value("${oss.bucket.name:}")
    private String bucket;

    @Override
    public Page<ExpenseInfo> selectInfo(ExpenseInfo expenseInfo) {
        Map<String, Object> pageView = new HashMap<>();
        pageView.put("startRecord", (expenseInfo.getCurrentPage() - 1)
                * expenseInfo.getPageSize());
        List<String> businessKeys = null;
        if ("2".equals(expenseInfo.getSearchType())) {
            businessKeys = workflowService.getTaskBusinessKeysByCode("FEIYONGGUANLI-APPROVE");
        }
        List<String> statusSet = new ArrayList<>();
        List<String> resourceIdList = this.getResourceIdList();
        if (resourceIdList.contains("saleOutReport-Edit")) { // 填写，提交    权限做完以后替换
            List<String> statusList = Lists.newArrayList(StatusEnum.PUR_RETURN.getFlag());
            statusSet.addAll(statusList);
        }
        pageView.put("searchKeyWord", expenseInfo.getSearchKeyWord());
        pageView.put("searchType", expenseInfo.getSearchType());
        pageView.put("pageSize", expenseInfo.getPageSize());
        pageView.put("currentPage", expenseInfo.getCurrentPage());
        pageView.put("contractNo", expenseInfo.getContractNo());
        pageView.put("startDate", expenseInfo.getStartDate());
        pageView.put("endDate", expenseInfo.getEndDate());
        pageView.put("businessKeys", businessKeys);
        pageView.put("statusSet", statusSet);
        // 查询总数
        Integer dataCount = baseMapper.getCountByCondition(pageView);
        List<ExpenseInfo> dataList = baseMapper.getListByCondition(pageView);
        if (!CollectionUtils.isEmpty(dataList)) {
            dataList.forEach(expenseInfo1 -> {
                String taskId = "";
                // 只有待审核状态才有taskId
                if (StringUtils.isNotBlank(expenseInfo1.getWorkflowId())) {
                    JSONObject jsonObject = workflowService.getActiveTask(Lists.newArrayList(expenseInfo1.getWorkflowId()), expenseInfo1.getId());
                    taskId = jsonObject.getString("taskId");
                    expenseInfo1.setTaskId(taskId);
                }
                List<ExpenseAllocationInfo> expenseAllocationInfos=expenseAllocationInfoService.selectList(new EntityWrapper<ExpenseAllocationInfo>()
                        .eq("info_id",expenseInfo1.getId())
                        .eq("status","待确认"));
                if (expenseAllocationInfos.size()>0){
                    expenseInfo1.setDistributionStatus(StatusEnum.TO_BE_CONFIRMED.getName());
                    expenseInfo1.setExpenseAllocationInfoList(expenseAllocationInfos);
                }
                List<ExpenseAllocationInfo> expenseAllocationInfoList=expenseAllocationInfoService.selectList(new EntityWrapper<ExpenseAllocationInfo>()
                        .eq("info_id",expenseInfo1.getId())
                        .eq("status","已驳回"));
                if (expenseAllocationInfoList.size()>0){
                    expenseInfo1.setExpenseAllocationInfoListBH(expenseAllocationInfoList);
                }
            });

        }
        Page<ExpenseInfo> page = new Page<>();
        page.setRecords(dataList == null ? Lists.newArrayList() : dataList);
        page.setTotal(dataCount == null ? 0 : dataCount);
        page.setCurrent(expenseInfo.getCurrentPage());
        page.setSize(expenseInfo.getPageSize());
        return page;
    }

    /**
     * 查看
     * @param id
     * @return
     */
    @Override
    public ExpenseInfo getInfo(String id) {
        ExpenseInfo expenseInfo=this.selectById(id);
        if (StringUtils.isNotBlank(expenseInfo.getWorkflowId())) {
            JSONObject jsonObject = workflowService.getActiveTask(Lists.newArrayList(expenseInfo.getWorkflowId()), expenseInfo.getId());
            String taskId = jsonObject.getString("taskId");
            expenseInfo.setTaskId(taskId);
        }
        //费用分配列表
        List<ExpenseAllocationInfo> expenseAllocationInfos = expenseAllocationInfoService.selectList(new EntityWrapper<ExpenseAllocationInfo>()
                .eq("info_id", id));
        if (!CollectionUtils.isEmpty(expenseAllocationInfos)) {
            expenseInfo.setExpenseAllocationInfoList(expenseAllocationInfos);
        }
        return expenseInfo;
    }

    /**
     * 删除
     * @param id
     */
    @Override
    public void deleteInfo(String id) {
        ExpenseInfo expenseInfo=this.selectById(id);
        if (expenseInfo != null) {
            this.deleteById(expenseInfo.getId());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addInfo(ExpenseInfo expenseInfo) {
        expenseInfo.setId(IdGenerator.generateUUID());
        //收入
        if ("1".equals(expenseInfo.getExpensesType())){
            expenseInfo.setStatusFlag(StatusEnum.TO_BE_CONFIRMED.getFlag());
            expenseInfo.setStatus(StatusEnum.TO_BE_CONFIRMED.getName());
            this.insert(expenseInfo);
            //合同费用
            if ("1".equals(expenseInfo.getExpensesPurpose())){
                //查是否有分配数据
                ExpenseAllocationInfo expenseAllocationInfo=expenseAllocationInfoService.selectOne(new EntityWrapper<ExpenseAllocationInfo>()
                .eq("contract_id",expenseInfo.getContractId())
                .eq("cost_type",expenseInfo.getCostType()));
                if (expenseAllocationInfo!=null){
                    //累加收回金额
                    expenseAllocationInfo.setRecoveryPrepayments(expenseAllocationInfo.getRecoveryPrepayments()+expenseInfo.getAmountMoney());
                    expenseAllocationInfoService.updateById(expenseAllocationInfo);
                }
                else {
                    ExpenseAllocationInfo expenseAllocationInfo1=new ExpenseAllocationInfo();
                    expenseAllocationInfo1.setId(IdGenerator.generateUUID());
                    expenseAllocationInfo1.setCostType(expenseInfo.getCostType());
                    expenseAllocationInfo1.setContractId(expenseInfo.getContractId());
                    expenseAllocationInfo1.setContractNo(expenseInfo.getContractNo());
                    expenseAllocationInfo1.setRecoveryPrepayments(expenseInfo.getAmountMoney());
                    expenseAllocationInfoService.insert(expenseAllocationInfo1);
                }
            }
            // 插入操作历史
            String staffName = this.billOperateHisService.getStaffAndName();
            // 插入操作历史
            this.billOperateHisService.saveBillOperateHis(expenseInfo.getId(), NumberConstant.EXPENSE_MANAGEMENT, staffName, null,
                    "收款", null, expenseInfo.getRemark());
        }
        //支出
        else
        {
            expenseInfo.setStatusFlag(StatusEnum.COST_PAYMENT.getFlag());
            expenseInfo.setStatus(StatusEnum.COST_PAYMENT.getName());
            expenseInfo.setUnallocatedAmount(expenseInfo.getAmountMoney()-expenseInfo.getTotalDistribution());
            this.insert(expenseInfo);
            //分配列表
            List<ExpenseAllocationInfo> expenseAllocationInfoList = expenseInfo.getExpenseAllocationInfoList();
            if (!CollectionUtils.isEmpty(expenseAllocationInfoList)) {
                for (ExpenseAllocationInfo expenseAllocationInfo : expenseAllocationInfoList) {
                    expenseAllocationInfo.setId(IdGenerator.generateUUID());
                    expenseAllocationInfo.setInfoId(expenseInfo.getId());
                    expenseAllocationInfo.setStatusFlag(StatusEnum.TO_BE_CONFIRMED.getFlag());
                    expenseAllocationInfo.setStatus(StatusEnum.TO_BE_CONFIRMED.getName());
                }
                expenseAllocationInfoService.insertBatch(expenseAllocationInfoList);
            }
            // 插入操作历史
            String staffName = this.billOperateHisService.getStaffAndName();
            // 插入操作历史
            this.billOperateHisService.saveBillOperateHis(expenseInfo.getId(), NumberConstant.EXPENSE_MANAGEMENT, staffName, null,
                    "请款", null, expenseInfo.getRemark());
            boolean isStartWorkflow = StringUtils.isBlank(expenseInfo.getWorkflowId());
            // 不是退回的单子
            if (isStartWorkflow) {
                Workflow workflow = workflowService
                        .findLatestWorkflowByBusinessCodeByApp(expenseInfo.getCompId(), "FEIYONGGUANLI-APPROVE");
                // 没配置审核流程，直接结束并处理信息
                if (workflow == null) {
                    throw new YException(YExceptionEnum.PURCHASE_ORDER_ERROR);
                }
                // 开启审核流
                else {
                    // 设置状态 已提交审核
                    expenseInfo.setWorkflowId(workflow.getId());
                    this.updateById(expenseInfo);
                    workflowService.startInstance(workflow.getId(), expenseInfo.getId());
                }
            }
            // 退回的单子 再启用
            else {
                this.updateById(expenseInfo);
                workflowService.activateInstance(expenseInfo.getWorkflowId(), expenseInfo.getId());
            }
        }
        return "ok";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String editInfo(ExpenseInfo expenseInfo) {
        ExpenseInfo expenseInfo1=this.selectById(expenseInfo.getId());
        //确认收款
        if ("0".equals(expenseInfo.getFlag())) {
            expenseInfo.setStatusFlag(StatusEnum.COST_RECEIVED.getFlag());
            expenseInfo.setStatus(StatusEnum.COST_RECEIVED.getName());
            ContractExpensesInfo contractExpensesInfo=new ContractExpensesInfo();
            contractExpensesInfo.setCompId(expenseInfo1.getCompId());
            contractExpensesInfo.setExpensesType("1");
            contractExpensesInfo.setExpensesName(expenseInfo1.getExpenseName());
            contractExpensesInfo.setPersonName(expenseInfo1.getAgent());
            contractExpensesInfo.setPayDeadline(new Date());
            contractExpensesInfo.setExpensesId(expenseInfo1.getId());
            contractExpensesInfo.setExpensesPrice(expenseInfo1.getAmountMoney());
            //保证金也属于粮款
            if ("5".equals(expenseInfo1.getCostType())){
                contractExpensesInfo.setGrainType("1");
            }
            else {
                contractExpensesInfo.setGrainType(expenseInfo1.getCostType());
            }
            //合同费用
            if ("1".equals(expenseInfo1.getExpensesPurpose())){
                contractExpensesInfo.setContractId(expenseInfo1.getContractId());
                contractExpensesInfo.setContractNo(expenseInfo1.getContractNo());
                contractExpensesInfo.setCostType("1");
            }
            //库点费用
            else if ("3".equals(expenseInfo1.getExpensesPurpose())){
                contractExpensesInfo.setWarehouseId(expenseInfo1.getWarehouseId());
                contractExpensesInfo.setWarehouseName(expenseInfo1.getWarehouseName());
                contractExpensesInfo.setCostType("3");
            }
            contractExpensesInfoService.insert(contractExpensesInfo);
            // 插入操作历史
            String staffName = this.billOperateHisService.getStaffAndName();
            // 插入操作历史
            this.billOperateHisService.saveBillOperateHis(expenseInfo.getId(), NumberConstant.EXPENSE_MANAGEMENT, staffName, null,
                    "确认", null, expenseInfo.getRemark());
        }
        //完成收款
        else if ("1".equals(expenseInfo.getFlag())){
            expenseInfo.setStatusFlag(StatusEnum.COMPLETED.getFlag());
            expenseInfo.setStatus(StatusEnum.COMPLETED.getName());
        }
        //确认分配
        else if ("2".equals(expenseInfo.getFlag())){
            expenseInfo.setDistributionStatusFlag("");
            expenseInfo.setDistributionStatus("");
            List<ExpenseAllocationInfo> expenseAllocationInfos=expenseAllocationInfoService.selectList(new EntityWrapper<ExpenseAllocationInfo>()
                    .eq("info_id",expenseInfo.getId())
                    .eq("status","待确认"));
            if (!CollectionUtils.isEmpty(expenseAllocationInfos)){
                for (ExpenseAllocationInfo expenseAllocationInfo:expenseAllocationInfos){
                    expenseAllocationInfo.setStatusFlag(StatusEnum.COST_ADOPTED.getFlag());
                    expenseAllocationInfo.setStatus(StatusEnum.COST_ADOPTED.getName());
                    expenseAllocationInfoService.updateById(expenseAllocationInfo);
                    //库点费用
                    if ("3".equals(expenseInfo1.getExpensesPurpose())) {
                        ContractExpensesInfo contractExpensesInfo = new ContractExpensesInfo();
                        contractExpensesInfo.setCompId(expenseInfo1.getCompId());
                        contractExpensesInfo.setExpensesType("2");
                        contractExpensesInfo.setExpensesName(expenseInfo1.getExpenseName());
                        contractExpensesInfo.setPersonName(expenseInfo1.getAgent());
                        contractExpensesInfo.setPayDeadline(new Date());
                        contractExpensesInfo.setExpensesId(expenseInfo1.getId());
                        contractExpensesInfo.setExpensesPrice(expenseAllocationInfo.getDistributionMoney());
                        //保证金也属于粮款
                        if ("5".equals(expenseInfo1.getCostType())) {
                            contractExpensesInfo.setGrainType("1");
                        } else {
                            contractExpensesInfo.setGrainType(expenseInfo1.getCostType());
                        }
                        WarehousingOrder warehousingOrder=warehousingOrderService.selectById(expenseAllocationInfo.getOrderId());
                        if (warehousingOrder!=null&&"采购入库".equals(warehousingOrder.getInType())){
                            ContractManagementInfo contractManagementInfo=contractManagementInfoService.selectOne(new EntityWrapper<ContractManagementInfo>()
                                    .eq("contract_no",warehousingOrder.getContractNo())
                                    .eq("comp_id",warehousingOrder.getCompId()));
                            if (contractManagementInfo!=null){
                                contractExpensesInfo.setContractId(contractManagementInfo.getId());
                                contractExpensesInfo.setContractNo(contractManagementInfo.getContractNo());
                                contractExpensesInfo.setCostType("1");
                                contractExpensesInfo.setWarehouseName(expenseInfo1.getWarehouseName());
                            }
                        }
                        else if(warehousingOrder!=null&&"收购入库".equals(warehousingOrder.getInType())){
                            WarehouseBaseInfo warehouseBaseInfo=warehouseBaseInfoService.selectOne(new EntityWrapper<WarehouseBaseInfo>()
                                    .eq("warehouse_name",warehousingOrder.getWarehouseName())
                                    .eq("comp_id",warehousingOrder.getCompId()));
                            if (warehouseBaseInfo!=null) {
                                contractExpensesInfo.setWarehouseId(warehouseBaseInfo.getId());
                                contractExpensesInfo.setWarehouseName(warehouseBaseInfo.getWarehouseName());
                                contractExpensesInfo.setCostType("3");
                            }
                        }
                        contractExpensesInfoService.insert(contractExpensesInfo);
                    }

                }
            }
        }
        //编辑分配
        else if ("3".equals(expenseInfo.getFlag())){
            expenseInfo.setDistributionStatusFlag(StatusEnum.TO_BE_CONFIRMED.getFlag());
            expenseInfo.setDistributionStatus(StatusEnum.TO_BE_CONFIRMED.getName());
            List<ExpenseAllocationInfo> expenseAllocationInfoList = expenseInfo.getExpenseAllocationInfoList();
            if (!CollectionUtils.isEmpty(expenseAllocationInfoList)) {
                for (ExpenseAllocationInfo expenseAllocationInfo : expenseAllocationInfoList) {
                    //有id的编辑
                    if (expenseAllocationInfo.getId()!=null) {
                        expenseAllocationInfo.setStatusFlag(StatusEnum.TO_BE_CONFIRMED.getFlag());
                        expenseAllocationInfo.setStatus(StatusEnum.TO_BE_CONFIRMED.getName());
                        expenseAllocationInfoService.updateById(expenseAllocationInfo);
                    }
                    else{
                        expenseAllocationInfo.setId(IdGenerator.generateUUID());
                        expenseAllocationInfo.setInfoId(expenseInfo.getId());
                        expenseAllocationInfo.setStatusFlag(StatusEnum.TO_BE_CONFIRMED.getFlag());
                        expenseAllocationInfo.setStatus(StatusEnum.TO_BE_CONFIRMED.getName());
                        expenseAllocationInfoService.insert(expenseAllocationInfo);
                    }
                }
            }
        }
        //主表编辑 flag==4
        else if ("4".equals(expenseInfo.getFlag())){
            boolean isStartWorkflow = StringUtils.isBlank(expenseInfo.getWorkflowId());
            // 不是退回的单子
            if (isStartWorkflow) {
                Workflow workflow = workflowService
                        .findLatestWorkflowByBusinessCodeByApp(expenseInfo.getCompId(), "FEIYONGGUANLI-APPROVE");
                // 没配置审核流程，直接结束并处理信息
                if (workflow == null) {
                    throw new YException(YExceptionEnum.PURCHASE_ORDER_ERROR);
                }
                // 开启审核流
                else {
                    // 设置状态 已提交审核
                    expenseInfo.setWorkflowId(workflow.getId());
                    this.updateById(expenseInfo);
                    workflowService.startInstance(workflow.getId(), expenseInfo.getId());
                }
            }
            // 退回的单子 再启用
            else {
                this.updateById(expenseInfo);
                workflowService.activateInstance(expenseInfo.getWorkflowId(), expenseInfo.getId());
            }
        }
        //驳回分配
        else if ("5".equals(expenseInfo.getFlag())){
            expenseInfo.setDistributionStatusFlag(StatusEnum.REJECTED.getFlag());
            expenseInfo.setDistributionStatus(StatusEnum.REJECTED.getName());
            List<ExpenseAllocationInfo> expenseAllocationInfos=expenseAllocationInfoService.selectList(new EntityWrapper<ExpenseAllocationInfo>()
                    .eq("info_id",expenseInfo.getId())
                    .eq("status","待确认"));
            if (!CollectionUtils.isEmpty(expenseAllocationInfos)){
                for (ExpenseAllocationInfo expenseAllocationInfo:expenseAllocationInfos){
                    expenseAllocationInfo.setStatusFlag(StatusEnum.REJECTED.getFlag());
                    expenseAllocationInfo.setStatus(StatusEnum.REJECTED.getName());
                    expenseAllocationInfoService.updateById(expenseAllocationInfo);
                }
            }
        }
        //驳回收款
        else if ("6".equals(expenseInfo.getFlag())) {
            expenseInfo.setStatusFlag(StatusEnum.REJECTED.getFlag());
            expenseInfo.setStatus(StatusEnum.REJECTED.getName());
        }
        // 主表信息编辑
        boolean one = this.updateById(expenseInfo);
        // 假如成功返回ok
        if (one) {
            return "OK";
        } else {
            return "NG";
        }
    }

    /**
     * 付款
     * @param expenseInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String payment(ExpenseInfo expenseInfo) {
        expenseInfo.setStatusFlag(StatusEnum.COST_PAID.getFlag());
        expenseInfo.setStatus(StatusEnum.COST_PAID.getName());
        this.updateById(expenseInfo);
        ExpenseInfo expenseInfo1=this.selectById(expenseInfo.getId());
        //合同费用
        if ("1".equals(expenseInfo1.getExpensesPurpose())) {
            ContractExpensesInfo contractExpensesInfo = new ContractExpensesInfo();
            contractExpensesInfo.setCompId(expenseInfo1.getCompId());
            contractExpensesInfo.setExpensesType("2");
            contractExpensesInfo.setExpensesName(expenseInfo1.getExpenseName());
            contractExpensesInfo.setPersonName(expenseInfo1.getAgent());
            contractExpensesInfo.setPayDeadline(new Date());
            contractExpensesInfo.setExpensesId(expenseInfo1.getId());
            contractExpensesInfo.setExpensesPrice(expenseInfo1.getAmountMoney());
            //保证金也属于粮款
            if ("5".equals(expenseInfo1.getCostType())) {
                contractExpensesInfo.setGrainType("1");
            } else {
                contractExpensesInfo.setGrainType(expenseInfo1.getCostType());
            }
            contractExpensesInfo.setContractId(expenseInfo1.getContractId());
            contractExpensesInfo.setContractNo(expenseInfo1.getContractNo());
            contractExpensesInfo.setCostType("1");
            contractExpensesInfoService.insert(contractExpensesInfo);
            //查是否有分配数据
            ExpenseAllocationInfo expenseAllocationInfo=expenseAllocationInfoService.selectOne(new EntityWrapper<ExpenseAllocationInfo>()
                    .eq("contract_id",expenseInfo1.getContractId())
                    .eq("cost_type",expenseInfo1.getCostType()));
            if (expenseAllocationInfo!=null){
                //累加付款金额
                expenseAllocationInfo.setAccumulatedPrepayment(expenseAllocationInfo.getAccumulatedPrepayment()+expenseInfo1.getAmountMoney());
                expenseAllocationInfoService.updateById(expenseAllocationInfo);
            }
            else {
                ExpenseAllocationInfo expenseAllocationInfo1=new ExpenseAllocationInfo();
                expenseAllocationInfo1.setId(IdGenerator.generateUUID());
                expenseAllocationInfo1.setCostType(expenseInfo1.getCostType());
                expenseAllocationInfo1.setContractId(expenseInfo1.getContractId());
                expenseAllocationInfo1.setContractNo(expenseInfo1.getContractNo());
                expenseAllocationInfo1.setAccumulatedPrepayment(expenseInfo1.getAmountMoney());
                expenseAllocationInfoService.insert(expenseAllocationInfo1);
            }
        }
        // 插入操作历史
        String staffName = this.billOperateHisService.getStaffAndName();
        // 插入操作历史
        this.billOperateHisService.saveBillOperateHis(expenseInfo.getId(), NumberConstant.EXPENSE_MANAGEMENT, staffName, null,
                "付款", null, "");
        return "ok";
    }

    /**
     * 删除分配
     * @param id
     */
    @Override
    public void deleteAllocationInfo(String id) {
        ExpenseInfo expenseInfo=this.selectById(id);
        expenseInfo.setDistributionStatusFlag("");
        expenseInfo.setDistributionStatus("");
        List<ExpenseAllocationInfo> expenseAllocationInfos=expenseAllocationInfoService.selectList(new EntityWrapper<ExpenseAllocationInfo>()
                .eq("info_id",id)
                .ne("status","已通过"));
        if (!CollectionUtils.isEmpty(expenseAllocationInfos)){
            for (ExpenseAllocationInfo expenseAllocationInfo:expenseAllocationInfos){
                expenseAllocationInfoService.deleteInfo(expenseAllocationInfo.getId());
            }
        }
        this.updateById(expenseInfo);
    }

    @Override
    public List<WarehousingOrder> selectWarehousingOrder(String contractNo, String warehouseName, String receiptDocDate) {
        Wrapper<WarehousingOrder> warehousingOrderWrapper = new EntityWrapper<>();
        if (contractNo!=null){
            warehousingOrderWrapper.eq("contract_no", contractNo);
        }
        if (warehouseName!=null){
            warehousingOrderWrapper.eq("warehouse_name", warehouseName);
        }
        if (receiptDocDate!=null){
            warehousingOrderWrapper.like("issuing_time", receiptDocDate);
        }
        warehousingOrderWrapper.ne("in_type","退库");
        warehousingOrderWrapper.orderBy("update_date");
        List<WarehousingOrder> warehousingOrderList = warehousingOrderService.selectList(warehousingOrderWrapper);
        return warehousingOrderList;
    }


    /**
     * 费用管理图表
     * @param compId
     * @param year
     * @return
     */
    @Override
    public List<ExpenseInfo> expenseChart(String compId, int year) {
        Map<String, Object> pageView = new HashMap<>();
        //  公司ID
        pageView.put("compId", compId);
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        String startDate = new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(currYearFirst);
        Calendar calendar1 = Calendar.getInstance();
        calendar1.clear();
        calendar1.set(Calendar.YEAR, year);
        calendar1.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearFirst1 = calendar1.getTime();
        String endDate = new SimpleDateFormat("yyyy-MM-dd 23:59:59").format(currYearFirst1);
        pageView.put("startDate", startDate);
        pageView.put("endDate", endDate);
        List<ExpenseInfo> dataList = baseMapper.getExpenseChartListByCondition(pageView);
        return dataList;
    }

    /**
     * 费用收支一览表
     * @param compId
     * @return
     */
    @Override
    public List<ExpenseInfo> expenseList(String compId, String startDate, String endDate) {
        Map<String, Object> pageView = new HashMap<>();
        //  公司ID
        pageView.put("compId", compId);
        pageView.put("startDate", startDate);
        pageView.put("endDate", endDate);
        List<ExpenseInfo> dataList = baseMapper.getExpenseListByCondition(pageView);
        return dataList;
    }

    @Override
    public String exportPhone(ExpenseInfo expenseInfo, HttpServletResponse response) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");


        // 1.Excel的头部信息
        String headerTitle = "";

        // 2.创建一个webbook 对应一个Excel文件
        HSSFWorkbook wb = new HSSFWorkbook();

        // 3.在webbook中添加一个sheet，对应Excel文件中的sheet
        HSSFSheet sheet;

        sheet = wb.createSheet("费用分配信息");
        headerTitle = "费用分配信息";

        // 4.设置打印参数
        sheet.setMargin(HSSFSheet.TopMargin, (short) 1);// 页边距（上）
        sheet.setMargin(HSSFSheet.BottomMargin, (short) 1);// 页边距（下）
        sheet.setMargin(HSSFSheet.LeftMargin, (short) 1);// 页边距（左）
        sheet.setMargin(HSSFSheet.RightMargin, (short) 1);// 页边距（右）

        // 不显示网格
        sheet.setDisplayGridlines(false);
        // 设置水平居中
        sheet.setHorizontallyCenter(true);

        /**************** 数据行样式 start ****************/
        HSSFFont fontTitle = wb.createFont();
        fontTitle.setFontName("宋体");
        fontTitle.setFontHeightInPoints((short) 14);
        // 设置字体加粗
        fontTitle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        HSSFFont fontComp = wb.createFont();
        fontComp.setFontName("宋体");
        fontComp.setFontHeightInPoints((short) 16);
        // 设置字体加粗
        fontComp.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        HSSFFont fontDetail = wb.createFont();
        fontDetail.setFontName("宋体");
        fontDetail.setFontHeightInPoints((short) 12);

        HSSFFont fontDetail1 = wb.createFont();
        fontDetail1.setFontName("宋体");
        fontDetail1.setFontHeightInPoints((short) 12);
        fontDetail1.setColor(HSSFColor.RED.index);

        // title
        HSSFCellStyle styleTitle = wb.createCellStyle();
        // 指定单元格居中对齐
        styleTitle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 指定单元格垂直居中对齐
        styleTitle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        styleTitle.setWrapText(true);
        // 设置单元格字体
        styleTitle.setFont(fontTitle);
        // 右边框
        styleTitle.setBorderRight(HSSFCellStyle.BORDER_NONE);
        // 左边框
        styleTitle.setBorderLeft(HSSFCellStyle.BORDER_NONE);
        // 上边框
        styleTitle.setBorderTop(HSSFCellStyle.BORDER_NONE);
        // 下边框
        styleTitle.setBorderBottom(HSSFCellStyle.BORDER_NONE);

        // title
        HSSFCellStyle styleComp = wb.createCellStyle();
        // 指定单元格居中对齐
        styleComp.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 指定单元格垂直居中对齐
        styleComp.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        styleComp.setWrapText(true);
        // 设置单元格字体
        styleComp.setFont(fontComp);
        // 右边框
        styleComp.setBorderRight(HSSFCellStyle.BORDER_NONE);
        // 左边框
        styleComp.setBorderLeft(HSSFCellStyle.BORDER_NONE);
        // 上边框
        styleComp.setBorderTop(HSSFCellStyle.BORDER_NONE);
        // 下边框
        styleComp.setBorderBottom(HSSFCellStyle.BORDER_NONE);

        HSSFCellStyle styleInfo = wb.createCellStyle();
        // 指定单元格居中对齐
        styleInfo.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        // 指定单元格垂直居中对齐
        styleInfo.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        styleInfo.setWrapText(true);
        // 设置单元格字体
        styleInfo.setFont(fontDetail);
        // 右边框
        styleInfo.setBorderRight(HSSFCellStyle.BORDER_NONE);
        // 左边框
        styleInfo.setBorderLeft(HSSFCellStyle.BORDER_NONE);
        // 上边框
        styleInfo.setBorderTop(HSSFCellStyle.BORDER_NONE);
        // 下边框
        styleInfo.setBorderBottom(HSSFCellStyle.BORDER_NONE);

        HSSFCellStyle styleDetail = wb.createCellStyle();
        // 指定单元格居中对齐
        styleDetail.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 指定单元格垂直居中对齐
        styleDetail.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        styleDetail.setWrapText(true);
        // 设置单元格字体
        styleDetail.setFont(fontDetail);
        // 右边框
        styleDetail.setBorderRight(HSSFCellStyle.BORDER_THIN);
        // 左边框
        styleDetail.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        // 上边框
        styleDetail.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 下styleDetailTitle
        styleDetail.setBorderBottom(HSSFCellStyle.BORDER_THIN);

        HSSFCellStyle styleDetail1 = wb.createCellStyle();
        // 指定单元格居中对齐
        styleDetail1.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 指定单元格垂直居中对齐
        styleDetail1.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        styleDetail1.setWrapText(true);
        // 设置单元格字体
        styleDetail1.setFont(fontDetail1);
        // 右边框
        styleDetail1.setBorderRight(HSSFCellStyle.BORDER_THIN);
        // 左边框
        styleDetail1.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        // 上边框
        styleDetail1.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 下styleDetailTitle
        styleDetail1.setBorderBottom(HSSFCellStyle.BORDER_THIN);

        HSSFCellStyle contextstyle = wb.createCellStyle();
        // 指定单元格居中对齐
        contextstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 指定单元格垂直居中对齐
        contextstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        contextstyle.setWrapText(true);
        // 设置单元格字体
        contextstyle.setFont(fontDetail);
        // 右边框
        contextstyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        // 左边框
        contextstyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        // 上边框
        contextstyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 下styleDetailTitle
        contextstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);

        HSSFCellStyle contextstyle1 = wb.createCellStyle();
        // 指定单元格居中对齐
        contextstyle1.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 指定单元格垂直居中对齐
        contextstyle1.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        contextstyle1.setWrapText(true);
        // 设置单元格字体
        contextstyle1.setFont(fontDetail1);
        // 右边框
        contextstyle1.setBorderRight(HSSFCellStyle.BORDER_THIN);
        // 左边框
        contextstyle1.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        // 上边框
        contextstyle1.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 下styleDetailTitle
        contextstyle1.setBorderBottom(HSSFCellStyle.BORDER_THIN);

        HSSFCellStyle styleDetailYellow = wb.createCellStyle();
        // 指定单元格居中对齐
        styleDetailYellow.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 指定单元格垂直居中对齐
        styleDetailYellow.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        styleDetailYellow.setWrapText(true);
        // 设置单元格字体
        styleDetailYellow.setFont(fontDetail);
        // 右边框
        styleDetailYellow.setBorderRight(HSSFCellStyle.BORDER_THIN);
        // 左边框
        styleDetailYellow.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        // 上边框
        styleDetailYellow.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 下styleDetailTitle
        styleDetailYellow.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        styleDetailYellow.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
        styleDetailYellow.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);


        HSSFCellStyle styleDetailLeft = wb.createCellStyle();
        // 指定单元格居中对齐
        styleDetailLeft.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        // 指定单元格垂直居中对齐
        styleDetailLeft.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        styleDetailLeft.setWrapText(true);
        // 设置单元格字体
        styleDetailLeft.setFont(fontDetail);
        // 右边框
        styleDetailLeft.setBorderRight(HSSFCellStyle.BORDER_THIN);
        // 左边框
        styleDetailLeft.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        // 上边框
        styleDetailLeft.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 下styleDetailTitle
        styleDetailLeft.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        /**************** 数据行样式 end ****************/

        // 设置列宽
        sheet.setColumnWidth(0, 1 * 256 + 184);
        sheet.setColumnWidth(1, "仓库名称".getBytes().length*3*256);
        sheet.setColumnWidth(2, "日期".getBytes().length*2*256);
        sheet.setColumnWidth(3, 12 * 256 + 184);
        sheet.setColumnWidth(4, 12 * 256 + 184);
        sheet.setColumnWidth(5, 1 * 256 + 184);

        // 创建单元格对象
        HSSFCell cell = null;

        // 创建打印设置对象
        HSSFPrintSetup ps = sheet.getPrintSetup();
        // 打印方向，true：横向，false：纵向(默认)
        ps.setLandscape(false);
        // // 打印质量
        // ps.setVResolution((short) 700)
        // 设置缩放比例
        ps.setScale((short) 80);
        // 纸张类型
        ps.setPaperSize(HSSFPrintSetup.A4_PAPERSIZE);


        int rownum = 1;
        HSSFRow row0 = sheet.createRow((int) rownum);
        row0.setHeightInPoints(25);
        cell = row0.createCell(1);
        cell.setCellStyle(styleTitle);
        cell.setCellValue("费用分配信息");
        sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, (short) 1, (short) 4));
        cell = row0.createCell(2);
        cell.setCellStyle(styleTitle);
        cell = row0.createCell(3);
        cell.setCellStyle(styleTitle);
        cell = row0.createCell(4);
        cell.setCellStyle(styleTitle);
        rownum++;


        // 费用分配总数
        List<ExpenseAllocationInfo> expenseAllocationInfos=expenseAllocationInfoService.selectList(new EntityWrapper<ExpenseAllocationInfo>()
                .eq("info_id",expenseInfo.getId())
                .ne("status","已通过"));

        HSSFRow rowp = sheet.createRow((int)(rownum));
        rowp.setHeightInPoints(20);
        cell = rowp.createCell(1);
        cell.setCellStyle(styleDetail);
        cell = rowp.createCell(2);
        cell.setCellStyle(styleDetail);
        cell = rowp.createCell(3);
        cell.setCellStyle(styleDetail);
        cell = rowp.createCell(4);
        cell.setCellStyle(styleDetail);
        rownum++;

        HSSFRow row1 = sheet.createRow((int) rownum);
        row1.setHeightInPoints(30);
        cell = row1.createCell(1);
        cell.setCellValue("仓库名称");
        cell.setCellStyle(styleDetail);
        cell = row1.createCell(2);
        cell.setCellValue("日期");
        cell.setCellStyle(styleDetail);
        cell = row1.createCell(3);
        cell.setCellValue("入库量(吨)");
        cell.setCellStyle(styleDetail);
        cell = row1.createCell(4);
        cell.setCellValue("分配金额(元)");
        cell.setCellStyle(styleDetail);
        rownum++;

        // 详情信息
        if (!CollectionUtils.isEmpty(expenseAllocationInfos)) {
            for (int i = 0; i < expenseAllocationInfos.size(); i++) {
                ExpenseAllocationInfo expenseAllocationInfo = expenseAllocationInfos.get(i);

                HSSFRow rowx = sheet.createRow((int) rownum);
                rowx.setHeightInPoints(20);
                cell = rowx.createCell(1);
                cell.setCellValue(editString(expenseAllocationInfo.getWarehouseName()));
                cell.setCellStyle(styleDetail);
                cell = rowx.createCell(2);
                String date = addDateOneDay(expenseAllocationInfo.getReceiptDocDate());
                cell.setCellValue(date);
                cell.setCellStyle(styleDetail);
                cell = rowx.createCell(3);
                cell.setCellValue(editFloat(expenseAllocationInfo.getInWarehouseWeight()));
                cell.setCellStyle(styleDetail);
                cell = rowx.createCell(4);
                cell.setCellValue(editDouble(expenseAllocationInfo.getDistributionMoney()));
                cell.setCellStyle(styleDetail);
                rownum++;
            }

        }


        String path = null;
        String tempPath = null;
        String excelPath = null;

        try {

            // 取得绝对路径
            tempPath = URLDecoder.decode((localPath), "utf-8");

            // EXCEL路径
            excelPath = "/web/temp/pay/" + DateUtil.formatDate(new Date(), DateUtils.DATE_FMT_YYYYMMDD_NS) + '/'
                    + UUID.randomUUID().toString().replaceAll("-", "");

            path = tempPath + excelPath + '/' + "费用分配信息"
                    + ".xlsx";

        } catch (Exception e) {
            log.debug(e.getMessage());
        }

        return downloadPhone(path, response, wb);
    }

    @Override
    public Integer expenseCount(ExpenseInfo expenseInfo) {
        //当天零点
        SimpleDateFormat now = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.YEAR, 0);
        Date y = c.getTime();
        String year = now.format(y);
        Integer count = this.selectCount(new EntityWrapper<ExpenseInfo>()
                .eq("comp_id", expenseInfo.getCompId())
                .ge("create_date", year));
        return count;
    }

    private String addDateOneDay(Date date) {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        return sdf.format(date);
    }
    /**
     * 判断字符串
     *
     * @param example
     * @return
     */
    private String editString(String example) {
        String exampleOne = example != null ? example : "";
        return exampleOne;
    }
    /**
     * 判断浮点数
     *
     * @param example
     * @return
     */
    private Float editFloat(Float example) {
        Float exampleOne = example != null ? example : 0f;
        return exampleOne;
    }
    /**
     * 判断浮点数
     *
     * @param example
     * @return
     */
    private Double editDouble(Double example) {
        Double exampleOne = example != null ? example : 0d;
        return exampleOne;
    }

    /**
     * 下载
     *
     * @param path
     * @param response
     */
    private String downloadPhone(String path, HttpServletResponse response, Workbook wb) {

        try {
            // 取得文件名。
            String fileName = "excel";
            // 给文件名编码
            fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");

            response.setContentType("application/vnd.ms-excel");
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);

            // 定义byte输出流
            ByteArrayOutputStream out = new ByteArrayOutputStream();

            // 写导出文件
            wb.write(out);

            // 取得模板文件中的数据
            byte[] result = out.toByteArray();

            // 设置输出数据类型
            response.setContentType("application/vnd.ms-excel");
            // 设置输出数据长度
            response.setContentLength(result.length);

            // 设置文件名称
            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
            // 将文件流输出到画面
//            response.getOutputStream().write(result);

            out.flush();
            out.close();
            //生成的新文件路径
            String outputFile = "templates" + File.separator + fileName + ".xlsx";
            File file1 = new File(new String(outputFile.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));
            try (FileOutputStream fos = new FileOutputStream(file1)) {
                wb.write(fos);
            }

            FileInputStream fileInputStream = new FileInputStream(file1.getAbsoluteFile());

            MultipartFile multipartFile = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
            String result1 = upload(multipartFile, fileName);
            file1.delete();
            return result1;
        } catch (IOException ex) {
            log.debug(ex.getMessage());
        }
        return "ng";
    }
    /**
     * 后台通过服务器间接传文件
     *
     * @param file
     * @return
     * @throws IOException
     */
    public String upload(MultipartFile file, String name) throws IOException {
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(file.getSize());
        objectMetadata.setContentType(file.getContentType());
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, "pcfiles/" + name + ".xlsx", file.getInputStream(), objectMetadata);
        ossClient.putObject(putObjectRequest);
        return baseUrl + "pcfiles/" + name + ".xlsx";
    }


    private List<String> getResourceIdList() {
        User currentUser = AuthSecurityUtils.getCurrentUserInfo();
        // 当前登录人主要角色
        return roleResourceService.getBindResourcesByUserId(currentUser.getUserId()).stream()
                .map(CommonRoleResource::getResourceId).collect(Collectors.toList());
    }
}
