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

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.setting.constant.EmpRoleConstants;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.supply.order.constant.DeliverOrderConstants;
import com.sifang.modules.supply.order.constant.PendingOrderConstants;
import com.sifang.modules.supply.order.dao.*;
import com.sifang.modules.supply.order.entity.CrmSupplyCheckPendingOrder;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialDeliverOrder;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialDeliverOrderDetail;
import com.sifang.modules.supply.setting.dao.CrmSupplyMaterialTypeDao;
import com.sifang.modules.supply.setting.dao.CrmSupplyWarehouseDao;
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.service.MaterialStockWaringService;
import com.sifang.modules.supply.warehouse.constant.InventoryMsgConstants;
import com.sifang.modules.supply.warehouse.constant.InventoryOrderConstants;
import com.sifang.modules.supply.warehouse.constant.MaterialKeepConstants;
import com.sifang.modules.supply.warehouse.dao.*;
import com.sifang.modules.supply.warehouse.entity.*;
import com.sifang.modules.supply.warehouse.service.CrmSupplyAllocationOrderService;
import com.sifang.modules.supply.warehouse.service.InventoryOrderService;
import com.sifang.modules.supply.warehouse.vo.OrderConstant;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.service.BaseService;
import com.sifang.modules.sys.entity.Ascription;
import com.sifang.modules.sys.entity.Operator;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class CheckPendingOrderService extends BaseService {
    @Autowired
    private CheckPendingOrderDao checkPendingOrderDao;
    @Autowired
    private InventoryOrderDao inventoryOrderDao;
    @Autowired
    private InventoryOrderDetailDao inventoryOrderDetailDao;
    @Autowired
    private InventoryOrderMsgDao inventoryOrderMsgDao;
    @Autowired
    private InventoryOrderService inventoryOrderService;
    @Autowired
    private MaterialStockDao materialStockDao;
    @Autowired
    private CrmSupplyMaterialKeepDao materialKeepDao;
    @Autowired
    private CrmSupplyWarehouseDao warehouseDao;
    @Autowired
    private SupplyExceptionDao supplyExceptionDao;
    @Autowired
    private MaterialStockWaringService materialStockWaringService;
    @Autowired
    private CrmSupplyAllocationOrderDao allocationOrderDao;
    @Autowired
    private CrmSupplyAllocationOrderDetailDao allocationOrderDetailDao;
    @Autowired
    private CrmSupplyAllocationOrderMsgDao allocationOrderMsgDao;
    @Autowired
    private CrmSupplyAllocationOrderService allocationOrderService;
    @Autowired
    private MaterialDeliverDao materialDeliverDao;
    @Autowired
    private MaterialDeliverDetailDao materialDeliverDetailDao;
    @Autowired
    private MaterialDeliverOrderMsgDao materialDeliverOrderMsgDao;
    @Autowired
    private SupplyMaterialDao supplyMaterialDao;

    @Autowired
    private CrmSupplyMaterialTypeDao materialTypeDao;

    private Logger logger = LoggerFactory.getLogger(CheckPendingOrderService.class);

    public LayuiPage getCheckPendingOrderPage(LayuiPage page, Map<String, String> map) {
        page.setData(checkPendingOrderDao.listPendingOrder(page, map));
        page.setCount(checkPendingOrderDao.countPendingOrder(map));
        return page;
    }

    public Map<String, String> getVoucherImg(CrmSupplyCheckPendingOrder order) {
        Map<String, String> retMap = new HashMap<>();
        if (PendingOrderConstants.PD.equals(order.getOrderType())) {
            CrmSupplyInventoryOrder inventoryOrder = inventoryOrderDao.get(order.getOrderId());
            retMap.put("deliverImg", inventoryOrder.getImg());
        } else if (PendingOrderConstants.DB.equals(order.getOrderType())) {
            CrmSupplyAllocationOrder allocationOrder = allocationOrderDao.get(order.getOrderId());
            retMap.put("deliverImg", allocationOrder.getReceivingImg());
            retMap.put("receivingImg", allocationOrder.getInReceivingImg());
        } else if (PendingOrderConstants.RK.equals(order.getOrderType())) {
            CrmSupplyMaterialDeliverOrder deliverOrder = materialDeliverDao.get(order.getOrderId());
            retMap.put("deliverImg", deliverOrder.getDeliverInvoice());
            retMap.put("receivingImg", deliverOrder.getReceiveInvoice());
        }
        return retMap;
    }

    /**
     * 审核通过
     */
    @Transactional(rollbackFor = Exception.class)
    public void auditOrder(String id, String reason) {
        User user = UserUtils.getUser();
        Date date = new Date();
        CrmSupplyCheckPendingOrder order = checkPendingOrderDao.get(id);
        logger.info("审核 通过 auditOrder {}",order.getCode() );
        checkBeforeAudit(order, user);
        order.setStatus(PendingOrderConstants.AUDITED);
        order.setReasonsForFailure(reason);
        order.setAuditBy(user.getId());
        order.setAuditName(CrmUtils.getUserXM(user));
        order.setAuditTime(date);
        checkPendingOrderDao.save(order);
        if (PendingOrderConstants.PD.equals(order.getOrderType())) {
          //  dealStockInfoForInventory(order, user);
        } else if (PendingOrderConstants.DB.equals(order.getOrderType())) {
            dealStockInfoForAllot(order, user);
        } else if (PendingOrderConstants.RK.equals(order.getOrderType())) {
            dealStockInfoForDeliver(order, user);
        }
    }

    /**
     * 审核不通过
     */
    @Transactional(rollbackFor = Exception.class)
    public void rejectOrder(String id, String reason) {
        CrmSupplyCheckPendingOrder order = checkPendingOrderDao.get(id);
        checkBeforeAudit(order, UserUtils.getUser());
        order.setStatus(PendingOrderConstants.DELETED);
        order.setReasonsForFailure(reason);
        checkPendingOrderDao.save(order);
        dealBusinessOrderWhenReject(order);

    }

    private void checkBeforeAudit(CrmSupplyCheckPendingOrder order, User user) {
        if (!StrKit.notNull(order)) {
            throw new BusinessException("待审核订单不存在");
        }
        if (!PendingOrderConstants.WAIT_AUDIT.equals(order.getStatus())) {
            throw new BusinessException("待审核订单状态发生改变");
        }
        if (!User.USER_TYPE_YYS.equals(user.getUserType()) && !User.USER_TYPE_WXG.equals(user.getUserType())) {
            String role = CrmUtils.getPlatEmployeRole(user.getId());
            if (!EmpRoleConstants.TREASURER.equals(role) && !EmpRoleConstants.SUPPLY_CHAIN.equals(role)) {
                throw new BusinessException("非财务员角色，不允许审批操作");
            }
        }
    }

    /**
     * 处理业务单信息
     */
    public void dealBusinessOrderWhenReject(CrmSupplyCheckPendingOrder order) {
        User user = UserUtils.getUser();
        if (PendingOrderConstants.PD.equals(order.getOrderType())) {
            CrmSupplyInventoryOrder inventoryOrder = inventoryOrderDao.get(order.getOrderId());
            inventoryOrder.setReasonsForFailure(order.getReasonsForFailure());
            inventoryOrder.setStatus(InventoryOrderConstants.REJECT);
            inventoryOrderDao.save(inventoryOrder);
            // 过程记录
            inventoryOrderMsgDao.addMsg(user, InventoryMsgConstants.REJECT, inventoryOrder.getId(), inventoryOrder.getReasonsForFailure());
            //例外统计
            Ascription ascription = new Ascription(inventoryOrder.getInventoryObjectId(), inventoryOrder.getInventoryObjectName());
            supplyExceptionDao.saveException(order.getCode(), "5", order.getReasonsForFailure(), "10", inventoryOrder.getCreateTime(), ascription);
        } else if (PendingOrderConstants.DB.equals(order.getOrderType())) {
            CrmSupplyAllocationOrder allocationOrder = allocationOrderDao.get(order.getOrderId());
            allocationOrder.setAuditBy(user.getId());
            allocationOrder.setAuditName(CrmUtils.getUserXM(user));
            allocationOrder.setAuditTime(new Date());
            allocationOrder.setReasonsForFailure(order.getReasonsForFailure());
            allocationOrder.setStatus(OrderConstant.STATUS_WTG);
            allocationOrderDao.save(allocationOrder);
            allocationOrderMsgDao.addMsg(user, OrderConstant.TYPE_SHWTG, allocationOrder.getId(), "审核驳回 "+order.getReasonsForFailure(), "");
            //例外统计
            Ascription ascription = new Ascription(allocationOrder.getOutAscriptionId(), allocationOrder.getOutName());
            supplyExceptionDao.saveException(order.getCode(), "6", order.getReasonsForFailure(), "10", allocationOrder.getCreateTime(), ascription);
            // 释放待出库库存，释放待入库库存
            List<CrmSupplyAllocationOrderDetail> details = allocationOrderDetailDao.getDetail(allocationOrder.getId());
            for (CrmSupplyAllocationOrderDetail detail : details) {
                materialStockDao.unFrozeStock(detail.getMaterialId(), allocationOrder.getWarehouseId(), detail.getInoutAmount());
                // 待入库的冻结不管
                //materialStockDao.unFrozeInStock(detail.getMaterialId(), allocationOrder.getInWarehouseId(), detail.getInoutAmount());
            }
        } else if (PendingOrderConstants.RK.equals(order.getOrderType())) {
            CrmSupplyMaterialDeliverOrder deliverOrder = materialDeliverDao.get(order.getOrderId());
            deliverOrder.setStatus(DeliverOrderConstants.AUDIT_FAIL);
            deliverOrder.setAuditTime(new Date());
            deliverOrder.setAuditRemark(order.getReasonsForFailure());
            //deliverOrder.setWarehouseFailReason(order.getReasonsForFailure());
            materialDeliverDao.save(deliverOrder);
            materialDeliverOrderMsgDao.saveOptMsg(deliverOrder.getId(), DeliverOrderConstants.OPT_AUDIT_FAIL, order.getReasonsForFailure(), Operator.of(user));
           /* List<CrmSupplyMaterialDeliverOrderDetail> details = materialDeliverDetailDao.listDetailByOrderId(deliverOrder.getId());
            for (CrmSupplyMaterialDeliverOrderDetail detail : details) {
                materialStockDao.unFrozeStock(detail.getMaterialId(), deliverOrder.getOutWarehouseId(), detail.getOutAmount());
            }*/
        }
    }

    /**
     * 处理库存信息 盘点业务
     */
    public void dealStockInfoForInventory(String orderId, User user,String remarks) {
        CrmSupplyInventoryOrder businessOrder = inventoryOrderDao.get(orderId);
        businessOrder.setStatus(InventoryOrderConstants.AUDITED);
        inventoryOrderDao.save(businessOrder);
        // 增加盘点单过程记录
        logger.info("增加盘点单过程记录  dealStockInfoForInventory :{}",orderId);
        inventoryOrderMsgDao.addMsg(user, InventoryMsgConstants.PASS, businessOrder.getId(), remarks);

        List<Record> materials = inventoryOrderService.getDetails(businessOrder.getId());
        for (Record material : materials) {

            MaterialWarehouseStocks warehouseStocks =  allocationOrderService.findWatehouseStock(material.getStr("material_id"), businessOrder.getWarehouseId(), user);
            CrmSupplyInventoryOrderDetail detail = inventoryOrderDetailDao.get(material.getStr("id"));
          logger.info("MaterialWarehouseStocks :{}  material:{}",warehouseStocks.getWarning(),material.getColumns());
            // 盘盈/盘亏数量
            BigDecimal diff = material.getBigDecimal("amount").subtract(warehouseStocks.getWarning());
            if (diff.compareTo(BigDecimal.ZERO) != 0) {
                // 处理库存
                warehouseStocks.setWarning(warehouseStocks.getWarning().add(diff));
                warehouseStocks.setRealNum(warehouseStocks.getRealNum().add(diff));
                warehouseStocks.setTotal(warehouseStocks.getTotal().add(diff));
                materialStockDao.save(warehouseStocks);
                createMaterialKeep(businessOrder, detail, diff, warehouseStocks.getWarning(), user);
                if(diff.compareTo(BigDecimal.ZERO)>0){
                    //盘盈 -- 增加库存
                }else{
                    //盘亏--扣减库存
                }

            }
            // 判断低库存预警
          //  materialStockWaringService.checkLowStockWarning(detail.getMaterialId(), businessOrder.getInventoryObjectId());
        }
    }

    /**
     * 处理库存信息 调拨业务
     */
    public void dealStockInfoForAllot(CrmSupplyCheckPendingOrder order, User user) {
        CrmSupplyAllocationOrder businessOrder = allocationOrderDao.get(order.getOrderId());
        businessOrder.setStatus(OrderConstant.STATUS_YWC);
        businessOrder.setAuditBy(user.getId());
        businessOrder.setAuditName(CrmUtils.getUserXM(user));
        businessOrder.setAuditTime(new Date());
        businessOrder.setReasonsForFailure(order.getReasonsForFailure());
        allocationOrderDao.save(businessOrder);
        allocationOrderMsgDao.addMsg(user, OrderConstant.TYPE_SH, businessOrder.getId(), "审核通过 "+order.getReasonsForFailure(), "");

        List<CrmSupplyAllocationOrderDetail> details = allocationOrderDetailDao.getDetail(businessOrder.getId());
        for (CrmSupplyAllocationOrderDetail detail : details) {
            // 出库仓的
            MaterialWarehouseStocks warehouseStocks = materialStockDao.findByWarehouse(detail.getMaterialId(), businessOrder.getWarehouseId());
            MaterialWarehouseStocks inWarehouseStocks = allocationOrderService.findWatehouseStock(detail.getMaterialId(), businessOrder.getInWarehouseId(), user);
            if (warehouseStocks.getRealNum().compareTo(detail.getInoutAmount()) < 0) {
                throw new BusinessException(String.format("物料代码【%s】库存数量不足", detail.getMaterialCode()));
            }
            // 扣减库存 释放待出库 生成出库记录
            warehouseStocks.setRealNum(warehouseStocks.getRealNum().subtract(detail.getInoutAmount()));
            warehouseStocks.setFrozeOutNum(warehouseStocks.getFrozeOutNum().subtract(detail.getInoutAmount()));
            warehouseStocks.setTotal(warehouseStocks.getTotal().subtract(detail.getInoutAmount()));
            warehouseStocks.setNewestKeepTime(new Date());
            materialStockDao.save(warehouseStocks);
            createMaterialKeepForAllot(businessOrder, detail, warehouseStocks.getWarning(), user, MaterialKeepConstants.OUT);
            // 增加库存 生成入库记录
            inWarehouseStocks.setRealNum(inWarehouseStocks.getRealNum().add(detail.getInoutAmount()));
            //inWarehouseStocks.setFrozeInNum(inWarehouseStocks.getFrozeInNum().subtract(detail.getInoutAmount()));
            inWarehouseStocks.setTotal(inWarehouseStocks.getTotal().add(detail.getInoutAmount()));
            inWarehouseStocks.setWarning(inWarehouseStocks.getWarning().add(detail.getInoutAmount()));
            inWarehouseStocks.setNewestStorageTime(new Date());
            materialStockDao.save(inWarehouseStocks);
            createMaterialKeepForAllot(businessOrder, detail, inWarehouseStocks.getWarning(), user, MaterialKeepConstants.IN);
            // 判断低库存预警 出库方的
            materialStockWaringService.checkLowStockWarning(detail.getMaterialId(), warehouseStocks.getType());
            // 判断低库存预警 入库方的
            materialStockWaringService.checkLowStockWarning(detail.getMaterialId(), inWarehouseStocks.getType());
        }
    }

    public void dealStockInfoForDeliver(CrmSupplyCheckPendingOrder order, User user) {
        CrmSupplyMaterialDeliverOrder businessOrder = materialDeliverDao.get(order.getOrderId());
        if(DeliverOrderConstants.WAIT_AUDIT.equals(businessOrder.getStatus())){
            businessOrder.setStatus(DeliverOrderConstants.COMPLETED);
        }
        businessOrder.setAuditRemark(order.getReasonsForFailure());
        businessOrder.setAuditTime(new Date());
        materialDeliverDao.save(businessOrder);
        //
        // materialDeliverOrderMsgDao.saveOptMsg(businessOrder.getId(), DeliverOrderConstants.OPT_DH, order.getReasonsForFailure(), Operator.of(user));
        List<CrmSupplyMaterialDeliverOrderDetail> details = materialDeliverDetailDao.listDetailByOrderId(businessOrder.getId());
        for (CrmSupplyMaterialDeliverOrderDetail detail : details) {
            SupplyMaterial material = supplyMaterialDao.get(detail.getMaterialId());
            // 出库仓的
            MaterialWarehouseStocks warehouseStocks = materialStockDao.findByWarehouse(detail.getMaterialId(), businessOrder.getOutWarehouseId());
            MaterialWarehouseStocks inWarehouseStocks = allocationOrderService.findWatehouseStock(detail.getMaterialId(), businessOrder.getInWarehouseId(), user);
            if (warehouseStocks.getRealNum().compareTo(detail.getInAmount()) < 0) {
                throw new BusinessException(String.format("物料代码【%s】库存数量不足", material.getCode()));
            }
            // 扣减库存 释放待出库 生成出库记录
            warehouseStocks.setRealNum(warehouseStocks.getRealNum().subtract(detail.getInAmount()));
            warehouseStocks.setFrozeOutNum(warehouseStocks.getFrozeOutNum().subtract(detail.getInAmount()));
            //warehouseStocks.setTotal(warehouseStocks.getTotal().subtract(detail.getInAmount()));
            warehouseStocks.setNewestKeepTime(new Date());
            materialStockDao.save(warehouseStocks);
            createMaterialKeepForDeliver(businessOrder, detail, warehouseStocks.getWarning(), user, MaterialKeepConstants.OUT, material);
            // 增加库存  生成入库记录
            inWarehouseStocks.setWarning(inWarehouseStocks.getWarning().add(detail.getInAmount()));
            inWarehouseStocks.setRealNum(inWarehouseStocks.getRealNum().add(detail.getInAmount()));
            //inWarehouseStocks.setFrozeInNum(inWarehouseStocks.getFrozeInNum().subtract(detail.getOutAmount()));
            inWarehouseStocks.setTotal(inWarehouseStocks.getTotal().add(detail.getInAmount()));
            inWarehouseStocks.setNewestStorageTime(new Date());
            materialStockDao.save(inWarehouseStocks);
            createMaterialKeepForDeliver(businessOrder, detail, inWarehouseStocks.getWarning(), user, MaterialKeepConstants.IN, material);
            // 判断低库存预警 出库方的
            materialStockWaringService.checkLowStockWarning(detail.getMaterialId(), warehouseStocks.getType());
            // 判断低库存预警 入库方的
            materialStockWaringService.checkLowStockWarning(detail.getMaterialId(), inWarehouseStocks.getType());
        }
    }

    public void createMaterialKeepForAllot(CrmSupplyAllocationOrder order, CrmSupplyAllocationOrderDetail detail, BigDecimal curBgNum, User user, String type) {
        CrmSupplyWarehouse warehouse = null;
        if (MaterialKeepConstants.OUT.equals(type)) {
            warehouse = warehouseDao.get(order.getWarehouseId());
        } else if (MaterialKeepConstants.IN.equals(type)) {
            warehouse = warehouseDao.get(order.getInWarehouseId());
        }
        CrmSupplyMaterialKeep keep = new CrmSupplyMaterialKeep();
        String belongingType = InventoryOrderConstants.DISTRIBUTOR.equals(warehouse.getType()) ?
                InventoryOrderConstants.SUPPLIER :
                (InventoryOrderConstants.SUPPLIER.equals(warehouse.getType()) ?
                        InventoryOrderConstants.DISTRIBUTOR : warehouse.getType());

        keep.setBelongingType(belongingType);
        keep.setMaterialId(detail.getMaterialId());
        keep.setMaterialCode(detail.getMaterialCode());
        keep.setMaterialType(detail.getMaterialType());
        keep.setMaterialRemarks(detail.getMaterialRemarks());
        keep.setMaterialUnit(detail.getMaterialUnit());
        keep.setType(type);
        keep.setAmount(detail.getInoutAmount());
        keep.setCurBgNum(curBgNum);
        keep.setWarehouseId(warehouse.getId());
        keep.setWarehouseName(warehouse.getName());


        keep.setAscriptionId(warehouse.getAscriptionId());
        keep.setAscriptionName(warehouse.getAscriptionName());
        keep.setCreateBy(user.getId());
        keep.setCreator(CrmUtils.getUserXM(user));
        keep.setCreateTime(new Date());
        keep.setSource(MaterialKeepConstants.IN.equals(type) ? MaterialKeepConstants.ALLOT_IN : MaterialKeepConstants.ALLOT_OUT);
        keep.setSourceId(order.getId());
        keep.setSourceCode(order.getCode());
        keep.setRemarks(order.getRemarks());
        keep.setDeliveryMethod(order.getDeliveryMethod());
        materialKeepDao.save(keep);
    }

    public void createMaterialKeepForDeliver(CrmSupplyMaterialDeliverOrder order, CrmSupplyMaterialDeliverOrderDetail detail, BigDecimal curBgNum, User user, String type, SupplyMaterial material) {
        CrmSupplyWarehouse warehouse = null;
        if (MaterialKeepConstants.OUT.equals(type)) {
            warehouse = warehouseDao.get(order.getOutWarehouseId());
        } else if (MaterialKeepConstants.IN.equals(type)) {
            warehouse = warehouseDao.get(order.getInWarehouseId());
        }
        CrmSupplyMaterialKeep keep = new CrmSupplyMaterialKeep();
        String belongingType = InventoryOrderConstants.DISTRIBUTOR.equals(warehouse.getType()) ?
                InventoryOrderConstants.SUPPLIER :
                (InventoryOrderConstants.SUPPLIER.equals(warehouse.getType()) ?
                        InventoryOrderConstants.DISTRIBUTOR : warehouse.getType());


        keep.setBelongingType(belongingType);
        keep.setMaterialId(detail.getMaterialId());
        keep.setMaterialCode(material.getCode());
        keep.setMaterialType(materialTypeDao.get(material.getMaterialTypeId()).getName());
        keep.setMaterialRemarks(material.getRemarks());
        keep.setMaterialUnit(material.getUnitName());
        keep.setType(type);
        keep.setAmount(detail.getOutAmount());
        keep.setCurBgNum(curBgNum);
        keep.setWarehouseId(warehouse.getId());
        keep.setWarehouseName(warehouse.getName());
        keep.setProjectCode(order.getProjectCode());

        keep.setAscriptionId(warehouse.getAscriptionId());
        keep.setAscriptionName(warehouse.getAscriptionName());
        keep.setCreateBy(user.getId());
        keep.setCreator(CrmUtils.getUserXM(user));
        keep.setCreateTime(new Date());
        if (MaterialKeepConstants.OUT.equals(type)) {
            keep.setSource(MaterialKeepConstants.DELIVER);
        } else if (MaterialKeepConstants.IN.equals(type)) {
            keep.setSource(MaterialKeepConstants.IN_STOCK_ORDER);
        }
        keep.setSourceId(order.getId());
        keep.setSourceCode(order.getNumber());
        keep.setRemarks(order.getRemarks());
        keep.setDeliveryMethod(order.getDeliverMethodName());
        materialKeepDao.save(keep);
    }

    public void createMaterialKeep(CrmSupplyInventoryOrder order, CrmSupplyInventoryOrderDetail detail, BigDecimal diff, BigDecimal curBgNum, User user) {
        CrmSupplyMaterialKeep keep = new CrmSupplyMaterialKeep();
        String belongingType = InventoryOrderConstants.DISTRIBUTOR.equals(order.getInventoryType()) ?
                InventoryOrderConstants.SUPPLIER :
                (InventoryOrderConstants.SUPPLIER.equals(order.getInventoryType()) ?
                        InventoryOrderConstants.DISTRIBUTOR : order.getInventoryType());

        keep.setBelongingType(belongingType);
        keep.setMaterialId(detail.getMaterialId());
        keep.setMaterialCode(detail.getMaterialCode());
        keep.setMaterialType(detail.getMaterialType());
        keep.setMaterialRemarks(detail.getMaterialRemarks());
        keep.setMaterialUnit(detail.getMaterialUnit());
        keep.setType(BigDecimal.ZERO.compareTo(diff) < 0 ? MaterialKeepConstants.IN : MaterialKeepConstants.OUT);
        keep.setAmount(diff.abs());
        keep.setCurBgNum(curBgNum);
        keep.setWarehouseId(order.getWarehouseId());
        keep.setWarehouseName(order.getWarehouseName());

        CrmSupplyWarehouse warehouse = warehouseDao.get(order.getWarehouseId());
        keep.setAscriptionId(warehouse.getAscriptionId());
        keep.setAscriptionName(warehouse.getAscriptionName());
        keep.setCreateBy(user.getId());
        keep.setCreator(CrmUtils.getUserXM(user));
        keep.setCreateTime(new Date());
        keep.setSource(MaterialKeepConstants.INVENTORY);
        keep.setSourceId(order.getId());
        keep.setSourceCode(order.getCode());
        keep.setRemarks(order.getRemarks());
        materialKeepDao.save(keep);
    }
}
