package com.sifang.modules.supply.warehouse.service;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.platform.utils.PlantformUtils;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.supply.setting.dao.CrmSupplySupplierDao;
import com.sifang.modules.supply.setting.dao.CrmSupplyWarehouseDao;
import com.sifang.modules.supply.setting.entity.CrmSupplySupplier;
import com.sifang.modules.supply.setting.entity.CrmSupplyWarehouse;
import com.sifang.modules.supply.stock.dao.MaterialStockDao;
import com.sifang.modules.supply.stock.dao.SupplyMaterialDao;
import com.sifang.modules.supply.stock.entity.MaterialWarehouseStocks;
import com.sifang.modules.supply.stock.entity.SupplyMaterial;
import com.sifang.modules.supply.stock.utils.MaterialUtils;
import com.sifang.modules.supply.warehouse.dao.*;
import com.sifang.modules.supply.warehouse.entity.*;
import com.sifang.modules.supply.warehouse.vo.AddPurchaseOrderVo;
import com.sifang.modules.supply.warehouse.vo.ExamineDetailVo;
import com.sifang.modules.supply.warehouse.vo.ExaminePurchaseOrderVo;
import com.sifang.modules.supply.warehouse.vo.PurchaseOrderDetailVo;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.persistence.Parameter;
import com.sifang.modules.sys.common.service.BaseService;
import com.sifang.modules.sys.entity.Ascription;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;


@Service
public class CrmSupplyPurchaseOrderService extends BaseService {

    @Autowired
    private CrmSupplyPurchaseOrderDao purchaseOrderDao;

    @Autowired
    private SupplyMaterialDao materialDao;

    @Autowired
    private CrmSupplyPurchaseOrderDetailDao orderDetailDao;

    @Autowired
    private CrmSupplyPurchaseOrderMsgDao orderMsgDao;

    @Autowired
    private CrmSupplyMaterialKeepDao materialKeepDao;

    @Autowired
    private MaterialStockDao materialStockDao;

    @Autowired
    private CrmSupplyWarehouseDao crmSupplyWarehouseDao;

    @Autowired
    private CrmSupplySupplierDao supplySupplierDao;

    @Autowired
    private CrmSupplyPurchaseOrderInspectionDao purchaseOrderInspectionDao;

    @Autowired
    private CrmSupplyPurchaseOrderInspectionDetailDao purchaseOrderInspectionDetailDao;

    public void purchaseOrderList(LayuiPage<Record> page,Map<String, String> map){
        User user= UserUtils.getUser();
        String userType=CrmUtils.getCurrentUserType(user);
       // List<String> supplierIds= null;
        if("2".equals(userType)){
            Ascription ascription=CrmUtils.getAscription();
           map.put("supplierId",ascription.getAscriptionId());
        }else{
            if(User.USER_TYPE_WXG.equals(user.getUserType())){  //平台员工
                 String userRelId=CrmUtils.getUserRelId(user);  //找出员工绑定的供应商
                 String supplierId=Db.queryStr(" SELECT id FROM `crm_supply_supplier` WHERE supervision_id=? AND STATUS='0' AND binding_flag='1' limit 1",userRelId);
                map.put("supplierId",supplierId);
              //  supplierIds= MaterialUtils.findSupplierIdsList(userRelId);
            }
        }

        List<Record> list= purchaseOrderDao.getList(page,map);
        Long count=purchaseOrderDao.countList(map);
        page.setCount(count);
        page.setData(list);
    }

    public void inspectionPurchaseOrderList(LayuiPage<Record> page,Map<String, String> map){

        User user= UserUtils.getUser();
        String userType=CrmUtils.getCurrentUserType(user);
        List<String> supplierIds= null;
        if("2".equals(userType)){
            Ascription ascription=CrmUtils.getAscription();
            map.put("supplierId",ascription.getAscriptionId());
        }else{
            if(User.USER_TYPE_WXG.equals(user.getUserType())){  //平台员工
                String userRelId=CrmUtils.getUserRelId(user);  //找出员工绑定的供应商
                supplierIds= MaterialUtils.findSupplierIdsList(userRelId);
            }
        }
       List<Record> list=purchaseOrderInspectionDao.getList(page,map,supplierIds);
       Long count=purchaseOrderInspectionDao.countList(map,supplierIds);
       page.setData(list);
       page.setCount(count);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addPurchaseOrder(AddPurchaseOrderVo orderVo){
        checkBeforSave(orderVo);
        User user = UserUtils.getUser();
        CrmSupplyPurchaseOrder purchaseOrder;
        if("update".equals(orderVo.getModel())){  //更改采购单
            updatePurchaseOrder(orderVo,user);
             return;
        }
        StringBuffer sb=new StringBuffer();
        if(StringUtil.isBlank(orderVo.getId())){  //新增采购单
            purchaseOrder=new CrmSupplyPurchaseOrder();
            purchaseOrder.setNumber(PlantformUtils.findOrderNumber("CG"));
            purchaseOrder.setSpaNumber(orderVo.getSpaNumber());
            purchaseOrder.setSupplierId(orderVo.getSupplierId());
            purchaseOrder.setRemark(orderVo.getRemark());
            purchaseOrder.setCreator(CrmUtils.getUserXM(user));
            purchaseOrder.setCreatorBy(user.getId());
            purchaseOrder.setCreateTime(new Date());
            purchaseOrder.setStatus(CrmSupplyPurchaseOrder.STATUS_DQR);
            purchaseOrderDao.save(purchaseOrder);
            sb.append("创建采购订单 ");
            if(StringUtil.isNotBlank(orderVo.getRemark()))sb.append(" ："+orderVo.getRemark());
            orderMsgDao.addMsg(user,CrmSupplyPurchaseOrderMsgDao.STATUS_CJ,purchaseOrder.getId(),sb.toString(),"");
        }else{       //编辑采购单
            purchaseOrder=purchaseOrderDao.get(orderVo.getId());
            purchaseOrder.setSupplierId(orderVo.getSupplierId());
            purchaseOrder.setSpaNumber(orderVo.getSpaNumber());
            purchaseOrder.setRemark(orderVo.getRemark());
            purchaseOrder.setUpdateTime(new Date());
            purchaseOrder.setUpdateBy(user.getId());
            purchaseOrder.setStatus(CrmSupplyPurchaseOrder.STATUS_DQR);
            // 将原先的明细全部置为已删除
            purchaseOrderDao.updateBySql("update crm_supply_purchase_order_detail set status = '0' where purchase_id=:p1 ",new Parameter(orderVo.getId()));
            orderMsgDao.addMsg(user,CrmSupplyPurchaseOrderMsgDao.STATUS_BJ,purchaseOrder.getId(),"编辑采购订单","");
        }
        // 创建bom明细
        List<PurchaseOrderDetailVo> details = orderVo.getDetails();
        List<CrmSupplyPurchaseOrderDetail> saveList=new ArrayList<>();
        for (PurchaseOrderDetailVo detail : details) {
            CrmSupplyPurchaseOrderDetail orderDetail = new CrmSupplyPurchaseOrderDetail();
            orderDetail.setPurchaseId(purchaseOrder.getId());
            orderDetail.setMaterialId(detail.getMaterialId());
            orderDetail.setMaterialCode(detail.getMaterialCode());
            orderDetail.setMaterialType(detail.getMaterialType());
            orderDetail.setMaterialUnit(detail.getMaterialUnit());
            orderDetail.setMaterialRemark(detail.getMaterialRemark());
            orderDetail.setAmount(detail.getAmount());
            orderDetail.setStatus(CrmSupplyPurchaseOrderDetail.NORMAL);
            saveList.add(orderDetail);
        }
        orderDetailDao.save(saveList);
    }
    @Transactional(rollbackFor = Exception.class)
    public void updatePurchaseOrder(AddPurchaseOrderVo orderVo,User user){
        CrmSupplyPurchaseOrder purchaseOrder=purchaseOrderDao.get(orderVo.getId());
        List<CrmSupplyPurchaseOrderDetail> oldList=orderDetailDao.getDetailList(orderVo.getId());
        Map<String,CrmSupplyPurchaseOrderDetail> map=ListtoMap(oldList);
        List<PurchaseOrderDetailVo> details = orderVo.getDetails();
        List<CrmSupplyPurchaseOrderDetail> saveList=new ArrayList<>();
        Boolean  flag=true;
        StringBuffer sb=new StringBuffer();
        sb.append("更改订单，更改后的物料有：");
        for (PurchaseOrderDetailVo detail : details) {
            String materielId=detail.getMaterialId();
            CrmSupplyPurchaseOrderDetail orderDetail=map.get(materielId);
            logger.info("updatePurchaseOrder CrmSupplyPurchaseOrderDetail :orderDetail :{}",orderDetail);
            if(orderDetail==null){
                orderDetail = new CrmSupplyPurchaseOrderDetail();
                orderDetail.setPurchaseId(orderVo.getId());
                orderDetail.setMaterialId(detail.getMaterialId());
                orderDetail.setMaterialCode(detail.getMaterialCode());
                orderDetail.setMaterialType(detail.getMaterialType());
                orderDetail.setMaterialUnit(detail.getMaterialUnit());
                orderDetail.setMaterialRemark(detail.getMaterialRemark());
                orderDetail.setAmount(detail.getAmount());
                orderDetail.setStatus(CrmSupplyPurchaseOrderDetail.NORMAL);
                saveList.add(orderDetail);
                flag=false;
            }else{
                if(detail.getAmount().compareTo(orderDetail.getAmount())!= 0){
                    logger.info("detail.getAmount().compareTo(orderDetail.getAmount() : true {}. {}. {},{}",orderDetail.getMaterialCode(),detail.getMaterialCode(),detail.getAmount(),orderDetail.getAmount());
                    if(orderDetail.getInAmount()!=null && detail.getAmount().compareTo(orderDetail.getInAmount().add(orderDetail.getWaitAmount()))<0){
                        throw  new BusinessException(" 更改失败，"+orderDetail.getMaterialCode() +" 物料已检数量和待检数量的和大于修改后的采购数量，不可更改 ");
                    }
                    orderDetail.setAmount(detail.getAmount());
                    saveList.add(orderDetail);
                }else{
                    saveList.add(orderDetail);
                }

                if(orderDetail.getAmount().compareTo(orderDetail.getInAmount())!=0){
                    flag=false;
                }
            }
            sb.append(detail.getMaterialCode()+"，数量: "+orderDetail.getAmount()+";");
        }
        Map<String,CrmSupplyPurchaseOrderDetail> saveMap=ListtoMap(saveList);
        sb.append("本次更改，删除的原物料：");
        for(CrmSupplyPurchaseOrderDetail orderDetail:oldList){
            String materielId=orderDetail.getMaterialId();
            CrmSupplyPurchaseOrderDetail saveDetail=saveMap.get(materielId);
            if(saveDetail==null){   //新导入的物料没有该物料
                if(orderDetail.getInAmount()!=null && orderDetail.getInAmount().compareTo(BigDecimal.ZERO)>0){  //有入库数量
                    throw  new BusinessException(" 更改失败，"+orderDetail.getMaterialCode() +" 物料已检不可删除 ");
                }else if(orderDetail.getWaitAmount()!=null && orderDetail.getWaitAmount().compareTo(BigDecimal.ZERO)>0){//有报检数量
                    throw  new BusinessException(" 更改失败，"+ orderDetail.getMaterialCode()+" 物料已报检不可删除 ");
                }else{
                    logger.info("删除CrmSupplyPurchaseOrderDetail ：{}",orderDetail);
                    orderDetail.setStatus(CrmSupplyPurchaseOrderDetail.DELETE);
                    saveList.add(orderDetail);
                }
                sb.append(orderDetail.getMaterialCode()+",数量 "+orderDetail.getAmount()+";");
            }
        }
        purchaseOrder.setUpdateTime(new Date());
        purchaseOrder.setUpdateBy(user.getId());
        if(flag){
            if(CrmSupplyPurchaseOrder.STATUS_BFJY.equals(purchaseOrder.getStatus())){
                purchaseOrder.setStatus(CrmSupplyPurchaseOrder.STATUS_YWC);
                purchaseOrder.setFinishTime(new Date());
            }
        }
        logger.info("更改采购订单 内容： {}",sb.toString());
        purchaseOrderDao.save(purchaseOrder);
         orderDetailDao.save(saveList);
        orderMsgDao.addMsg(user,CrmSupplyPurchaseOrderMsgDao.STATUS_UPDATE,orderVo.getId(),"更改采购订单，更改说明："+orderVo.getUpdateReason(),sb.toString());
    }

    public Map<String,CrmSupplyPurchaseOrderDetail> ListtoMap(List<CrmSupplyPurchaseOrderDetail> list){
        Map<String,CrmSupplyPurchaseOrderDetail> map=new HashMap<>();
        for(CrmSupplyPurchaseOrderDetail detail:list){
            map.put(detail.getMaterialId(),detail);
        }
        return map;
    }

    public Map<String,CrmSupplyPurchaseOrderDetail> ListtoMap2(List<CrmSupplyPurchaseOrderDetail> list){
        Map<String,CrmSupplyPurchaseOrderDetail> map=new HashMap<>();
        for(CrmSupplyPurchaseOrderDetail detail:list){
            map.put(detail.getId(),detail);
        }
        return map;
    }

    public Map<String,CrmSupplyPurchaseOrderInspectionDetail> ListtoMap3(List<CrmSupplyPurchaseOrderInspectionDetail> list){
        Map<String,CrmSupplyPurchaseOrderInspectionDetail> map=new HashMap<>();
        for(CrmSupplyPurchaseOrderInspectionDetail detail:list){
            map.put(detail.getId(),detail);
        }
        return map;
    }

    public void checkBeforSave(AddPurchaseOrderVo orderVo){
        if(purchaseOrderDao.checkSpaNumber(orderVo.getSpaNumber(),orderVo.getId())){
            throw new BusinessException(" SAP采购订单号已存在，请勿重复添加!");
        }
        List<PurchaseOrderDetailVo> details = orderVo.getDetails();
        int index = 1;
        for (PurchaseOrderDetailVo detail : details) {
            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            if (!StrKit.notNull(material)) {
                throw new BusinessException("第" + index + "行物料不存在");
            }
            if (BigDecimal.ZERO.compareTo(detail.getAmount()) == 0) {
                throw new BusinessException("第" + index + "行数量不能为零");
            }
        }
    }

    public List<Record> orderMaterialList(String orderId){
        return Db.find(" SELECT d.* FROM `crm_supply_purchase_order_detail` d WHERE d.purchase_id=? AND d.status='1' ",orderId);
    }

    public List<Record> getExamineMaterialList(String inspectionId){
        String sql=" SELECT d.id AS inspectionId,d.amount AS currentAmount,pd.* FROM `crm_supply_purchase_order_inspection_detail` d " +
                "   LEFT JOIN `crm_supply_purchase_order_detail` pd ON d.purchase_detail_id=pd.id and pd.status='1' " +
                "   WHERE d.status='1' and d.inspection_id=? ";
        return Db.find(sql,inspectionId);
    }

    public Record getOrderDetail(String orderId){
      return Db.findFirst(" SELECT o.* ,w.name AS warehouseName  FROM `crm_supply_purchase_order` o " +
              "LEFT JOIN `crm_supply_warehouse` w ON o.warehouse_id=w.id " +
              "WHERE o.id=? ",orderId);
    }

    public Record getInspection(String inspectionId){
        return Db.findFirst(" SELECT * FROM crm_supply_purchase_order_inspection WHERE id=? ",inspectionId);
    }

    public List<Record> getInspectionMaterialList(String inspectionId){
        return Db.find("  SELECT d.amount ,(case when o.status='2' then 0 else i.amount end) AS wait_amount,i.inspection_amount AS in_amount,i.location,d.material_code,d.material_type,d.material_group,d.material_unit,d.material_remark " +
                "   FROM `crm_supply_purchase_order_inspection_detail` i " +
                "   LEFT JOIN `crm_supply_purchase_order_detail` d ON i.purchase_detail_id=d.id and d.status='1' " +
                " left join crm_supply_purchase_order_inspection o on o.id=i.inspection_id  "+
                "   WHERE i.inspection_id=? AND i.status='1' ",inspectionId);
    }

    //报检记录
    public List<Record> getInspectionDetail(String purchaseId){
        StringBuffer sb=new StringBuffer();
        sb.append("   SELECT de.*,i.status AS insStaus,i.create_time,i.finish_time,d.amount AS bjAmount,d.inspection_amount ");
        sb.append(" FROM `crm_supply_purchase_order_inspection` i ");
        sb.append("  LEFT JOIN `crm_supply_purchase_order_inspection_detail` d ON i.id=d.inspection_id AND d.status='1' ");
        sb.append("  LEFT JOIN `crm_supply_purchase_order_detail` de ON de.id=d.purchase_detail_id AND de.status='1' ");
        sb.append("  WHERE i.purchase_id=? ");
        return Db.find(sb.toString(),purchaseId);
    }

    public List<Record> getLocations(String warehouseId,String purchaseId){
        String materialIds=Db.queryStr(" SELECT GROUP_CONCAT(material_id) FROM `crm_supply_purchase_order_inspection_detail` d WHERE d.inspection_id=? AND d.status='1' GROUP BY d.inspection_id ",purchaseId);
        return Db.find("SELECT s.material_id,s.position FROM `crm_supply_material_warehouse_stocks` s WHERE s.warehouse_id=? AND s.material_id IN ("+ StringUtil.joinInSql(materialIds.split(","))+") ",warehouseId);
    }

    public List<Record> getMsgs(String orderId){
        return orderMsgDao.getMsgs(orderId);
    }

    public void cancelPurchaseOrder(String id,String remark){
        User user = UserUtils.getUser();
        CrmSupplyPurchaseOrder purchaseOrder=purchaseOrderDao.get(id);
        purchaseOrder.setStatus(CrmSupplyPurchaseOrder.STATUS_YCX);
        purchaseOrder.setUpdateTime(new Date());
        purchaseOrder.setUpdateBy(user.getId());
        purchaseOrder.setCancelReason(remark);
        purchaseOrderDao.save(purchaseOrder);
        orderMsgDao.addMsg(user,CrmSupplyPurchaseOrderMsgDao.STATUS_CX,id,"撤销采购订单，撤销原因: "+remark,"");
    }

    @Transactional(rollbackFor = Exception.class)
    public void deletePurchaseOrder(String ids){
        String[] arr=ids.split(",");
        User user = UserUtils.getUser();
        for(String id:arr){
            CrmSupplyPurchaseOrder purchaseOrder=purchaseOrderDao.get(id);
            if(!CrmSupplyPurchaseOrder.STATUS_YCX.equals(purchaseOrder.getStatus())){
                throw new BusinessException(" 您选择的有不能操作删除的采购订单，请重新选择! ");
            }
            purchaseOrder.setStatus(CrmSupplyPurchaseOrder.STATUS_DELETE);
            purchaseOrder.setUpdateTime(new Date());
            purchaseOrder.setUpdateBy(user.getId());
            purchaseOrderDao.save(purchaseOrder);
            orderMsgDao.addMsg(user,CrmSupplyPurchaseOrderMsgDao.STATUS_SC,id,"删除采购订单","");
            purchaseOrderDao.updateBySql("update crm_supply_purchase_order_detail set status = '0' where purchase_id=:p1 ",new Parameter(id));
        }
    }

    public void confirmPurchaseOrder(String id){
        User user = UserUtils.getUser();
        Date date=new Date();
        CrmSupplyPurchaseOrder purchaseOrder=purchaseOrderDao.get(id);
        purchaseOrder.setStatus(CrmSupplyPurchaseOrder.STATUS_DBJ);
        purchaseOrder.setConfirmTime(date);
        purchaseOrder.setConfirmBy(user.getId());
        purchaseOrder.setConfirmor(CrmUtils.getUserXM(user));
        purchaseOrder.setUpdateTime(date);
        purchaseOrder.setUpdateBy(user.getId());
        purchaseOrderDao.save(purchaseOrder);
        orderMsgDao.addMsg(user,CrmSupplyPurchaseOrderMsgDao.STATUS_QRDD,id,"确认采购订单","");
    }

    /**
     * 报检
     */
    @Transactional(rollbackFor = Exception.class)
    public void inspectionPurchaseOrder(ExaminePurchaseOrderVo examineOrderVo){
        User user = UserUtils.getUser();
        CrmSupplyPurchaseOrder purchaseOrder=purchaseOrderDao.get(examineOrderVo.getId());
        if(purchaseOrder==null){
            throw new BusinessException("对不起，采购单不存在!");
        }
        List<CrmSupplyPurchaseOrderDetail> purchaseOrderDetails=orderDetailDao.getDetailList(examineOrderVo.getId());
        Map<String,CrmSupplyPurchaseOrderDetail> orderMap=ListtoMap2(purchaseOrderDetails);
        List<ExamineDetailVo> examineDetailVos=examineOrderVo.getExamineDetailVos();
        List<CrmSupplyPurchaseOrderDetail> saveList=new ArrayList<>(); //采购单详情

        List<CrmSupplyPurchaseOrderInspectionDetail> saveInspectionDeatil=new ArrayList<>(); //报检单明细
        Date date=new Date();

        //生成报检单
        CrmSupplyPurchaseOrderInspection purchaseOrderInspection=new CrmSupplyPurchaseOrderInspection();
        purchaseOrderInspection.setPurchaseId(purchaseOrder.getId());
        purchaseOrderInspection.setPurchaseNumber(purchaseOrder.getNumber());
        purchaseOrderInspection.setCreateTime(date);
        purchaseOrderInspection.setCreateBy(user.getId());
        purchaseOrderInspection.setStatus("1");
        purchaseOrderInspectionDao.save(purchaseOrderInspection);

        for(ExamineDetailVo detailVo:examineDetailVos){
            BigDecimal currentAmount=detailVo.getCurrentInAmount();
            if(currentAmount.compareTo(BigDecimal.ZERO)>0){
                CrmSupplyPurchaseOrderDetail purchaseOrderDetail=orderMap.get(detailVo.getId());
                if(purchaseOrderDetail==null){
                    throw new BusinessException("对不起，您入库的物料详情不存在!");
                }
                BigDecimal syAmount=purchaseOrderDetail.getAmount().subtract(purchaseOrderDetail.getInAmount()).subtract(purchaseOrderDetail.getWaitAmount());
                if(syAmount.compareTo(currentAmount)<0){
                    throw new BusinessException("对不起，您报检的物料数量过多!");
                }
                purchaseOrderDetail.setWaitAmount(purchaseOrderDetail.getWaitAmount().add(currentAmount));
                saveList.add(purchaseOrderDetail);
                CrmSupplyPurchaseOrderInspectionDetail purchaseOrderInspectionDetail=new CrmSupplyPurchaseOrderInspectionDetail();
                purchaseOrderInspectionDetail.setInspectionId(purchaseOrderInspection.getId());
                purchaseOrderInspectionDetail.setPurchaseDetailId(purchaseOrderDetail.getId());
                purchaseOrderInspectionDetail.setMaterialId(purchaseOrderDetail.getMaterialId());
                purchaseOrderInspectionDetail.setAmount(currentAmount);
                saveInspectionDeatil.add(purchaseOrderInspectionDetail);
            }
        }
        if(CrmSupplyPurchaseOrder.STATUS_DBJ.equals(purchaseOrder.getStatus())){
            purchaseOrder.setStatus(CrmSupplyPurchaseOrder.STATUS_DJY);
            purchaseOrder.setInspectionTime(date);
            purchaseOrderDao.save(purchaseOrder);
        }

        orderDetailDao.save(saveList);
        purchaseOrderInspectionDetailDao.save(saveInspectionDeatil);
        orderMsgDao.addMsg(user,CrmSupplyPurchaseOrderMsgDao.STATUS_INSPEC,purchaseOrder.getId(),"采购单报检","");

    }

    /**
     * 检验入库
     * @param examineOrderVo
     */
    @Transactional(rollbackFor = Exception.class)
    public void examinePurchaseOrder(ExaminePurchaseOrderVo examineOrderVo){
        User user = UserUtils.getUser();
        String userId=user.getId();
        String userName=CrmUtils.getUserXM(user);
        Date date=new Date();
        CrmSupplyPurchaseOrderInspection inspection=purchaseOrderInspectionDao.get(examineOrderVo.getId());
        if(inspection==null){
            throw new BusinessException("对不起，报检单不存在，请联系管理员！");
        }
        if("2".equals(inspection.getStatus())){
            throw new BusinessException("对不起，该报检单已检验入库，请刷新页面！");
        }
        CrmSupplyPurchaseOrder purchaseOrder=purchaseOrderDao.get(inspection.getPurchaseId());
        if(purchaseOrder==null){
            throw new BusinessException("对不起，采购单不存在!");
        }
        //判断用户是否是供应商绑定的监造人员
        CrmSupplySupplier supplySupplier=supplySupplierDao.get(purchaseOrder.getSupplierId());
        /*if("0".equals(supplySupplier.getBindingFlag())){
            throw new BusinessException("对不起，供应商没绑定监造人员!");
        }*/
     //   String supervisionId=supplySupplier.getSupervisionId();
        String useRelId=CrmUtils.getUserRelId(user);
       /* if(!supervisionId.equals(useRelId)){
            throw new BusinessException("对不起，只有供应商绑定的监造人员才可以检验!");
        }*/
        List<CrmSupplyPurchaseOrderDetail> purchaseOrderDetails=orderDetailDao.getDetailList(purchaseOrder.getId());  //采购单明细
        Map<String,CrmSupplyPurchaseOrderDetail> orderMap=ListtoMap2(purchaseOrderDetails);  //明细id的map

        List<CrmSupplyPurchaseOrderInspectionDetail> inspectionDetails=purchaseOrderInspectionDetailDao.getDetailList(inspection.getId());  //报检单明细
        Map<String,CrmSupplyPurchaseOrderInspectionDetail> inspectionMap=ListtoMap3(inspectionDetails); //明细id的map

        List<ExamineDetailVo> examineDetailVos=examineOrderVo.getExamineDetailVos();  //本次检验的明细
        Boolean flag=true;
        List<CrmSupplyPurchaseOrderDetail> saveList=new ArrayList<>(); //要保持的采购单详情
        List<CrmSupplyMaterialKeep> saveKeep=new ArrayList<>(); //要保存的出入库记录

        if(CrmSupplyPurchaseOrder.STATUS_DJY.equals(purchaseOrder.getStatus())){  //首次检验
            purchaseOrder.setExamineTime(date);
        }
        CrmSupplyWarehouse warehouse = crmSupplyWarehouseDao.get(examineOrderVo.getWarehouseId());   //入库仓库

        StringBuffer msg=new StringBuffer("本次入库情况：");
        for(ExamineDetailVo detailVo:examineDetailVos){
               BigDecimal currentInAmount=detailVo.getCurrentInAmount();
            CrmSupplyPurchaseOrderInspectionDetail inspectionDetail=inspectionMap.get(detailVo.getId());
            if(inspectionDetail.getAmount().compareTo(currentInAmount)<0){
                throw new BusinessException("对不起，检验数量不能大于报检数量!");
            }
            inspectionDetail.setInspectionAmount(currentInAmount);
            String location=detailVo.getLocation();
            inspectionDetail.setLocation(location);
            inspectionDetail.setStatus("1");
            purchaseOrderInspectionDetailDao.save(inspectionDetail);

            CrmSupplyPurchaseOrderDetail purchaseOrderDetail=orderMap.get(inspectionDetail.getPurchaseDetailId());
            if(purchaseOrderDetail==null){
                throw new BusinessException("对不起，您入库的物料详情不存在!");
            }

                   BigDecimal totalInAmount=currentInAmount.add(purchaseOrderDetail.getInAmount());
                   if(purchaseOrderDetail.getAmount().compareTo(totalInAmount)<0){
                       throw new BusinessException("对不起，您入库的物料数量已超出订单采购数量!");
                   }
            purchaseOrderDetail.setInAmount(purchaseOrderDetail.getInAmount().add(currentInAmount));
            purchaseOrderDetail.setWaitAmount(purchaseOrderDetail.getWaitAmount().subtract(inspectionDetail.getAmount()));
            purchaseOrderDetail.setLocation(location);
            saveList.add(purchaseOrderDetail);

               if(currentInAmount.compareTo(BigDecimal.ZERO)>0){
                   msg.append(purchaseOrderDetail.getMaterialCode()+"本次入库数量："+currentInAmount+"，历史入库数量："+purchaseOrderDetail.getInAmount()+";");
                  //生成出入库记录
                   CrmSupplyMaterialKeep materialKeep=addCrmSupplyMaterialKeep(purchaseOrder,purchaseOrderDetail,currentInAmount,examineOrderVo.getWarehouseId(),userId,userName);
                   saveKeep.add(materialKeep);
                   //修改库存数量
                   MaterialWarehouseStocks warehouseStocks=editWarehouseStocks(warehouse,purchaseOrderDetail.getMaterialId(),currentInAmount,userId,detailVo.getLocation());
                   materialStockDao.save(warehouseStocks);
               }

        }
        for(CrmSupplyPurchaseOrderDetail orderDetail:purchaseOrderDetails){  //只要一个物料没有入全 那么该采购单就是部分入库的状态
            if(orderDetail.getAmount().compareTo(orderDetail.getInAmount()) != 0){
                flag=false;
                break;
            }
        }
        inspection.setRemark(examineOrderVo.getExamineRemark());
        inspection.setWarehouseId(examineOrderVo.getWarehouseId());
        inspection.setWarehouseName(warehouse.getName());
        inspection.setFinishTime(date);
        inspection.setStatus("2");
        inspection.setExamineName(userName);
        purchaseOrderInspectionDao.save(inspection);

        purchaseOrder.setLatestExamineTime(date);
        purchaseOrder.setWarehouseId(examineOrderVo.getWarehouseId());
        purchaseOrder.setExamineRemark(examineOrderVo.getExamineRemark());
        purchaseOrder.setExamineBy(userId);
        purchaseOrder.setExaminer(userName);
        if(flag){
            purchaseOrder.setStatus(CrmSupplyPurchaseOrder.STATUS_YWC);
            purchaseOrder.setFinishTime(date);
        }else{
            purchaseOrder.setStatus(CrmSupplyPurchaseOrder.STATUS_BFJY);
        }
        purchaseOrderDao.save(purchaseOrder);
        orderDetailDao.save(saveList);
        materialKeepDao.save(saveKeep);
        orderMsgDao.addMsg(user,CrmSupplyPurchaseOrderMsgDao.STATUS_JY,purchaseOrder.getId(),"检验入库："+examineOrderVo.getExamineRemark(),msg.toString());

    }

    public CrmSupplyMaterialKeep addCrmSupplyMaterialKeep(CrmSupplyPurchaseOrder purchaseOrder,CrmSupplyPurchaseOrderDetail purchaseOrderDetail,BigDecimal currentInAmount,String warehouseId,String userId,String userName){
        CrmSupplyMaterialKeep materialKeep=new CrmSupplyMaterialKeep();
        materialKeep.setBelongingType("2");
        materialKeep.setMaterialId(purchaseOrderDetail.getMaterialId());
        materialKeep.setMaterialRemarks(purchaseOrderDetail.getMaterialRemark());
        materialKeep.setMaterialType(purchaseOrderDetail.getMaterialType());
        materialKeep.setMaterialUnit(purchaseOrderDetail.getMaterialUnit());
        materialKeep.setMaterialCode(purchaseOrderDetail.getMaterialCode());
        materialKeep.setType("1");
        materialKeep.setAmount(currentInAmount);

        materialKeep.setCurBgNum(BigDecimal.ZERO);
        materialKeep.setWarehouseId(warehouseId);
        materialKeep.setWarehouseName(CrmSupplyWarehouseDao.getWatehouseName(warehouseId));

        materialKeep.setAscriptionId(purchaseOrder.getSupplierId());

        materialKeep.setAscriptionName(CrmSupplySupplierDao.getSupplyName(purchaseOrder.getSupplierId()));

        materialKeep.setCreateBy(userId);
        materialKeep.setCreator(userName);

        materialKeep.setCreateTime(new Date());
        materialKeep.setSource("1");
        materialKeep.setSourceId(purchaseOrder.getId());
        materialKeep.setSourceCode(purchaseOrder.getNumber());
        return materialKeep;
    }
    public MaterialWarehouseStocks editWarehouseStocks( CrmSupplyWarehouse warehouse, String materialId,BigDecimal amount,String userId,String location){
        MaterialWarehouseStocks stocks= materialStockDao.getByWarehouseId(warehouse.getId(), materialId);
        if(stocks==null){
            stocks=new MaterialWarehouseStocks();
            stocks.setMaterialId(materialId);
            stocks.setWarehouseId(warehouse.getId());
            stocks.setType("2");   //供应商才能入库
            stocks.setAscriptionId(warehouse.getAscriptionId());
            stocks.setAscriptionName(warehouse.getAscriptionName());
            stocks.setWarning(amount);
            stocks.setRealNum(amount);
            stocks.setTotal(amount);
            stocks.setCreateBy(userId);
            stocks.setCreateTime(new Date());
            stocks.setNewestStorageTime(new Date());
        }else{
            stocks.setWarning(stocks.getWarning().add(amount));
            stocks.setRealNum(stocks.getRealNum().add(amount));
            stocks.setTotal(stocks.getTotal().add(amount));
            stocks.setNewestStorageTime(new Date());

        }
        return stocks;
    }
}
