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

import com.alibaba.fastjson.JSONObject;
import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
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.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.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.PurchaseReceiptReportMapper;
import com.yh.saas.plugin.yiliangyiyun.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.yh.saas.toolkit.workflow.service.IWorkflowService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 采购入库报表 服务实现类
 * </p>
 *
 * @author Gongdc
 * @since 2021-07-31
 */
@Service
public class PurchaseReceiptReportServiceImpl extends ServiceImpl<PurchaseReceiptReportMapper, PurchaseReceiptReport> implements IPurchaseReceiptReportService {

    @Autowired
    private INewWorkflowService workflowService;

    @SofaReference
    private ICommonRoleResourceService roleResourceService;
    @Autowired
    private IContractManagementInfoService contractManagementInfoService;
    @Autowired
    private IPurchaseOrderService purchaseOrderService;
    @Autowired
    private IWarehouseInOutInfoService warehouseInOutInfoService;

    /**
     * 采购入库统计
     *
     * @param purchaseReceiptReport
     * @return
     */
    @Override
    public Page<PurchaseReceiptReport> selectPurchaseOrder(PurchaseReceiptReport purchaseReceiptReport) {
        Map<String, Object> pageView = new HashMap<>();
        pageView.put("startRecord", (purchaseReceiptReport.getCurrentPage() - 1)
                * purchaseReceiptReport.getPageSize());
        List<String> businessKeys = null;
        if ("1".equals(purchaseReceiptReport.getSearchType())) {
            businessKeys = workflowService.getTaskBusinessKeysByCode("PROCUREMENT-RECEIPT-REPORT");
        }
        List<String> statusSet = new ArrayList<>();
        List<String> resourceIdList = this.getResourceIdList();
        if (resourceIdList.contains("procurementInReport-Edit")) { // 填写，提交    权限做完以后替换
            List<String> statusList = Lists.newArrayList(StatusEnum.PUR_RETURN.getFlag());
            statusSet.addAll(statusList);
        }
        //公司id
        pageView.put("compId", purchaseReceiptReport.getCompId());
        pageView.put("searchKeyWord", purchaseReceiptReport.getSearchKeyWord());
        pageView.put("searchType", purchaseReceiptReport.getSearchType());
        pageView.put("pageSize", purchaseReceiptReport.getPageSize());
        pageView.put("currentPage", purchaseReceiptReport.getCurrentPage());
        pageView.put("contractNo", purchaseReceiptReport.getContractNo());
        pageView.put("roleFlag", purchaseReceiptReport.getRoleFlag());
        pageView.put("statusFlag", purchaseReceiptReport.getStatusFlag());
        pageView.put("businessKeys", businessKeys);
        pageView.put("statusSet", statusSet);
        // 查询采购入库总数
        Integer dataCount = baseMapper.getCountByCondition(pageView);
        List<PurchaseReceiptReport> dataList = baseMapper.getListByCondition(pageView);
        if (!CollectionUtils.isEmpty(dataList)) {
            dataList.forEach(purchaseReceiptReport1 -> {

                String taskId = "";
                // 只有待审核状态才有taskId
                if (StringUtils.isNotBlank(purchaseReceiptReport1.getWorkflowId())) {
                    JSONObject jsonObject = workflowService.getActiveTask(Lists.newArrayList(purchaseReceiptReport1.getWorkflowId()), purchaseReceiptReport1.getId());
                    taskId = jsonObject.getString("taskId");
                    purchaseReceiptReport1.setTaskId(taskId);
                }
            });

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

    /**
     * 编辑采购入库统计
     *
     * @param purchaseReceiptReport
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String editProcurementReceiptReport(PurchaseReceiptReport purchaseReceiptReport) {
        PurchaseReceiptReport purchaseReceiptReport1 = this.selectById(purchaseReceiptReport.getId());
        boolean one = this.updateById(purchaseReceiptReport);
        if (purchaseReceiptReport.getStatusFlag().equals(StatusEnum.TASK_RETURN.getFlag())) {
            boolean isStartWorkflow = org.apache.commons.lang3.StringUtils.isBlank(purchaseReceiptReport1.getWorkflowId());
            // 不是退回的单子
            if (isStartWorkflow) {
                Workflow workflow = workflowService
                        .findLatestWorkflowByBusinessCodeByApp(purchaseReceiptReport1.getCompId(), "PROCUREMENT-RECEIPT-REPORT");
                // 没配置审核流程，直接结束并处理信息
                if (workflow == null) {
                    throw new YException(YExceptionEnum.PURCHASE_ORDER_ERROR);
                }
                // 开启审核流
                else {

                    // 设置状态 已提交审核
                    purchaseReceiptReport1.setWorkflowId(workflow.getId());
                    this.updateById(purchaseReceiptReport1);
                    workflowService.startInstance(workflow.getId(), purchaseReceiptReport1.getId());
                }
            }
            // 退回的单子 再启用
            else {

                this.updateById(purchaseReceiptReport1);
                workflowService.activateInstance(purchaseReceiptReport1.getWorkflowId(), purchaseReceiptReport1.getId());
            }
        }
        if (one) {
            return "OK";
        } else {
            return "NG";
        }
    }

    /**
     * 补货结转
     *
     * @param purchaseReceiptReport
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String replenishment(PurchaseReceiptReport purchaseReceiptReport) {
        PurchaseReceiptReport purchaseReceiptReport1 = this.selectById(purchaseReceiptReport.getId());
        if ("3".equals(purchaseReceiptReport.getCustomerConfirmationStatusFlag())) {
            // 未付金额不等0 可补货结转
            if (purchaseReceiptReport.getAmountNotPayable() != 0) {
                purchaseReceiptReport1.setCarryForward("出" + purchaseReceiptReport.getCarryOverWeight() + "+" + purchaseReceiptReport.getContractNo());
                //被结转条目净重要减去结转重量
                purchaseReceiptReport1.setNetWeight(purchaseReceiptReport1.getNetWeight() - purchaseReceiptReport.getCarryOverWeight());
                this.updateById(purchaseReceiptReport1);
                PurchaseReceiptReport receiptReport = purchaseReceiptReport.getPurchaseReceiptReport();
                //结转到其他合同
                if (purchaseReceiptReport.getPurchaseReceiptReport().getId() != null) {
                    //更新原数据
                    receiptReport.setCarryForward("入" + purchaseReceiptReport.getCarryOverWeight() + "+" + purchaseReceiptReport1.getContractNo());
                    this.updateById(receiptReport);
                }
                //结转到本合同
                else {
                    receiptReport.setContractNo(purchaseReceiptReport.getContractNo());
                }
                receiptReport.setId(IdGenerator.generateUUID());
                receiptReport.setCompId(purchaseReceiptReport1.getCompId());
                //净重为结转重量
                receiptReport.setNetWeight(purchaseReceiptReport.getCarryOverWeight());
                this.insert(receiptReport);
            }
        } else {
            throw new YException(YExceptionEnum.PURCHASE_ORDER_ERROR1);
        }
        return "OK";
    }

    /**
     * 出纳付款
     *
     * @param purchaseReceiptReport
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String payMoney(PurchaseReceiptReport purchaseReceiptReport) {
        List<PurchaseReceiptReport> purchaseReceiptReportList = purchaseReceiptReport.getPurchaseReceiptReportList();
        Float money = purchaseReceiptReport.getMoney();
        //付款多条
        if (!CollectionUtils.isEmpty(purchaseReceiptReportList)) {
            for (PurchaseReceiptReport purchaseReceiptReport1 : purchaseReceiptReportList) {
                PurchaseReceiptReport purchaseReceiptReport2 = this.selectById(purchaseReceiptReport1.getId());
                //付款金额大于本次循环未付金额
                if (money >= purchaseReceiptReport1.getAmountNotPayable()) {
                    money = money - purchaseReceiptReport1.getAmountNotPayable();
                    //全部付款
                    purchaseReceiptReport1.setStatus(StatusEnum.PUR_PAYaLL.getName());
                    purchaseReceiptReport1.setStatusFlag(StatusEnum.PUR_PAYaLL.getFlag());
                    purchaseReceiptReport1.setPaymentDate(purchaseReceiptReport.getPaymentDate());
                    purchaseReceiptReport1.setPaymentScreenshot(purchaseReceiptReport2.getPaymentScreenshot() != null ? purchaseReceiptReport2.getPaymentScreenshot() + '$' + purchaseReceiptReport.getPaymentScreenshot() : purchaseReceiptReport.getPaymentScreenshot());
                    purchaseReceiptReport1.setAmountEdPayable(purchaseReceiptReport1.getAmountEdPayable() + purchaseReceiptReport1.getAmountNotPayable());
                    purchaseReceiptReport1.setAmountNotPayable(0.0f);
                    this.updateById(purchaseReceiptReport1);
                } else if (money > 0) {
                    Float moneyTmp = money - purchaseReceiptReport1.getAmountNotPayable();
                    //部分付款
                    purchaseReceiptReport1.setStatus(StatusEnum.PUR_PAY.getName());
                    purchaseReceiptReport1.setStatusFlag(StatusEnum.PUR_PAY.getFlag());
                    purchaseReceiptReport1.setPaymentDate(purchaseReceiptReport.getPaymentDate());
                    purchaseReceiptReport1.setPaymentScreenshot(purchaseReceiptReport2.getPaymentScreenshot() != null ? purchaseReceiptReport2.getPaymentScreenshot() + '$' + purchaseReceiptReport.getPaymentScreenshot() : purchaseReceiptReport.getPaymentScreenshot());
                    purchaseReceiptReport1.setAmountEdPayable(purchaseReceiptReport1.getAmountEdPayable() + money);
                    purchaseReceiptReport1.setAmountNotPayable(purchaseReceiptReport1.getAmountNotPayable() - money);
                    this.updateById(purchaseReceiptReport1);
                    money = moneyTmp;
                } else {
                    break;
                }
            }
        }
        return "ok";
    }

    /**
     * 开发票
     *
     * @param purchaseReceiptReport
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String openInvoice(PurchaseReceiptReport purchaseReceiptReport) {
        //查询采购入库报表
        PurchaseReceiptReport purchaseReceiptReport1 = this.selectById(purchaseReceiptReport.getId());
        if (purchaseReceiptReport1 != null) {
            //更改已开发票
            purchaseReceiptReport1.setAlreadyInvoice(purchaseReceiptReport1.getAlreadyInvoice() + purchaseReceiptReport.getAlreadyInvoice());
            purchaseReceiptReport1.setInvoiceType(purchaseReceiptReport.getInvoiceType());
            //更改采购入库报表信息
            this.updateById(purchaseReceiptReport1);
            return "OK";
        }
        return "NG";
    }

    /**
     * 批量开发票
     *
     * @param purchaseReceiptReport
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String openInvoiceList(PurchaseReceiptReport purchaseReceiptReport) {
        List<PurchaseReceiptReport> purchaseReceiptReportList = purchaseReceiptReport.getPurchaseReceiptReportList();
        //批量
        if (!CollectionUtils.isEmpty(purchaseReceiptReportList)) {
            for (PurchaseReceiptReport purchaseReceiptReport1 : purchaseReceiptReportList) {
                //已开发票金额等于已付金额
                purchaseReceiptReport1.setAlreadyInvoice(purchaseReceiptReport1.getAmountEdPayable());
                this.updateById(purchaseReceiptReport1);
            }
        }
        return "ok";
    }


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

    /**
     * 审核采购入库报表
     *
     * @param purchaseReceiptReport
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String examinePurchaseOrder(PurchaseReceiptReport purchaseReceiptReport) {
        List<PurchaseReceiptReport> purchaseReceiptReportList = purchaseReceiptReport.getPurchaseReceiptReportList();
        //批量
        if (!CollectionUtils.isEmpty(purchaseReceiptReportList)) {
            for (PurchaseReceiptReport purchaseReceiptReport1 : purchaseReceiptReportList) {
                //统计审核
                if ("1".equals(purchaseReceiptReport.getRoleFlag())) {
                    purchaseReceiptReport1.setStatus(StatusEnum.STATISTICAL_AUDIT.getName());
                    purchaseReceiptReport1.setStatusFlag(StatusEnum.STATISTICAL_AUDIT.getFlag());
                }
                //财务通过
                else if ("2".equals(purchaseReceiptReport.getRoleFlag()) && "1".equals(purchaseReceiptReport.getFlag())) {
                    purchaseReceiptReport1.setStatus(StatusEnum.FINANCIAL_AUDIT.getName());
                    purchaseReceiptReport1.setStatusFlag(StatusEnum.FINANCIAL_AUDIT.getFlag());
                }
                //财务驳回
                else if ("2".equals(purchaseReceiptReport.getRoleFlag()) && "2".equals(purchaseReceiptReport.getFlag())) {
                    purchaseReceiptReport1.setStatus(StatusEnum.FINANCIAL_REJECTION.getName());
                    purchaseReceiptReport1.setStatusFlag(StatusEnum.FINANCIAL_REJECTION.getFlag());
                }
                //决策人同意
                else if ("3".equals(purchaseReceiptReport.getRoleFlag()) && "1".equals(purchaseReceiptReport.getFlag())) {
                    purchaseReceiptReport1.setStatus(StatusEnum.MAKER_AUDIT.getName());
                    purchaseReceiptReport1.setStatusFlag(StatusEnum.MAKER_AUDIT.getFlag());
                }
                //决策人驳回
                else {
                    purchaseReceiptReport1.setStatus(StatusEnum.MAKER_REJECTION.getName());
                    purchaseReceiptReport1.setStatusFlag(StatusEnum.MAKER_REJECTION.getFlag());
                }
                this.updateById(purchaseReceiptReport1);
            }
        }
        return "OK";
    }

    /**
     * 合同编号下拉列表
     *
     * @param compId
     */
    @Override
    public List<ContractManagementInfo> selectContractNoList(String compId) {
        //查采购合同
        List<ContractManagementInfo> contractManagementInfoList = contractManagementInfoService.selectList(new EntityWrapper<ContractManagementInfo>()
                .eq("comp_id", compId)
                .eq("contract_type", "2")
                .eq("delete_flag", "0")
                .orderBy("update_date", false));
        for (ContractManagementInfo contractManagementInfo : contractManagementInfoList) {
            Float money = 0.0f;
            //查采购出库报表
            List<PurchaseReceiptReport> purchaseReceiptReportList = this.selectList(new EntityWrapper<PurchaseReceiptReport>()
                    .eq("contract_no", contractManagementInfo.getContractNo())
                    .eq("delete_flag", "0"));
            if (!CollectionUtils.isEmpty(purchaseReceiptReportList)) {
                for (PurchaseReceiptReport purchaseReceiptReport : purchaseReceiptReportList) {
                    money = money + purchaseReceiptReport.getAmountNotPayable();
                }
                //有未付金额
                if (money > 0) {
                    contractManagementInfo.setReportStatus("待结算");
                } else {
                    contractManagementInfo.setReportStatus("已结算");
                }
            }
        }
        return contractManagementInfoList;
    }

    /**
     * 查采购订单表
     *
     * @param purchaseReceiptReport
     */
    @Override
    public PurchaseOrder selectOrder(PurchaseReceiptReport purchaseReceiptReport) {
        PurchaseOrder purchaseOrder = purchaseOrderService.selectOne(new EntityWrapper<PurchaseOrder>()
                .eq("contract_no", purchaseReceiptReport.getContractNo())
                .eq("delete_flag", "0"));
        if (purchaseOrder != null) {
            //定义已入库量
            Float stockInQuantity = 0.0f;
            //查询入库量
            List<WarehouseInOutInfo> warehouseInOutInfoList = warehouseInOutInfoService.selectList(new EntityWrapper<WarehouseInOutInfo>()
                    .eq("contract_no", purchaseOrder.getContractNo())
                    .eq("task_type", "入库任务")
                    .eq("status_flag", "3")
                    .eq("delete_flag", "0"));
            if (!CollectionUtils.isEmpty(warehouseInOutInfoList)) {
                for (WarehouseInOutInfo warehouseInOutInfo : warehouseInOutInfoList) {
                    stockInQuantity = stockInQuantity + Float.valueOf(String.valueOf(warehouseInOutInfo.getNetWeight()));
                }
            }
            purchaseOrder.setStockInQuantity(stockInQuantity);
        }
        return purchaseOrder;
    }

    /**
     * 根据客户名查合同编号
     *
     * @param customerName
     */
    @Override
    public List<PurchaseReceiptReport> selectContractNo(String customerName, String contractNo) {
        List<PurchaseReceiptReport> purchaseReceiptReportList = this.selectList(new EntityWrapper<PurchaseReceiptReport>()
                .eq("customer_name", customerName)
                .eq("delete_flag", 0)
                .orderBy("update_date", false)
                .groupBy("contract_no"));
        if (!CollectionUtils.isEmpty(purchaseReceiptReportList)) {
            for (int i = 0; i < purchaseReceiptReportList.size(); i++) {
                if (contractNo.equals(purchaseReceiptReportList.get(i).getContractNo())) {
                    purchaseReceiptReportList.remove(purchaseReceiptReportList.get(i));
                }
            }
        }
        return purchaseReceiptReportList;
    }

    /**
     * 查看
     *
     * @param id
     * @return
     */
    @Override
    public PurchaseReceiptReport getInfo(String id) {
        PurchaseReceiptReport purchaseReceiptReport = this.selectById(id);
        String taskId = "";
        // 只有待审核状态才有taskId
        if (StringUtils.isNotBlank(purchaseReceiptReport.getWorkflowId())) {
            JSONObject jsonObject = workflowService.getActiveTask(Lists.newArrayList(purchaseReceiptReport.getWorkflowId()), purchaseReceiptReport.getId());
            taskId = jsonObject.getString("taskId");
            purchaseReceiptReport.setTaskId(taskId);
        }
        return purchaseReceiptReport;
    }

}
