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

import com.google.common.collect.Maps;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.account.dao.TraderAccountDao;
import com.sifang.modules.flowable.service.ProcessFlowableService;
import com.sifang.modules.flowable.utils.FormUtils;
import com.sifang.modules.flowpath.dao.BondApplyDao;
import com.sifang.modules.kingdee.service.MiscellaneousService;
import com.sifang.modules.order.utils.excelExt.ExcelReader;
import com.sifang.modules.platform.utils.PlantformUtils;
import com.sifang.modules.q7link.service.CrmSupplyMaterialProjectPriceService;
import com.sifang.modules.sunshine.SystemSetting.dao.DepartmentSettingDao;
import com.sifang.modules.sunshine.SystemSetting.dao.TraderDao;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmDepartment;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmTrader;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sunshine.handler.InventutyExcelImportHandler;
import com.sifang.modules.supply.order.constant.PendingOrderConstants;
import com.sifang.modules.supply.order.dao.CheckPendingOrderDao;
import com.sifang.modules.supply.order.entity.CrmSupplyCheckPendingOrder;
import com.sifang.modules.supply.setting.constant.WarehouseConstants;
import com.sifang.modules.supply.setting.dao.CrmSupplyMaterialTypeDao;
import com.sifang.modules.supply.setting.dao.CrmSupplyWarehouseDao;
import com.sifang.modules.supply.setting.entity.CrmSupplyMaterialType;
import com.sifang.modules.supply.setting.entity.CrmSupplyWarehouse;
import com.sifang.modules.supply.stock.constant.MaterialConstants;
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.MaterialStockService;
import com.sifang.modules.supply.stock.service.SupplyMaterialKeepService;
import com.sifang.modules.supply.warehouse.constant.InventoryMsgConstants;
import com.sifang.modules.supply.warehouse.constant.InventoryOrderConstants;
import com.sifang.modules.supply.warehouse.dao.InventoryOrderDao;
import com.sifang.modules.supply.warehouse.dao.InventoryOrderDetailDao;
import com.sifang.modules.supply.warehouse.dao.InventoryOrderMsgDao;
import com.sifang.modules.supply.warehouse.entity.CrmSupplyInventoryOrder;
import com.sifang.modules.supply.warehouse.entity.CrmSupplyInventoryOrderDetail;
import com.sifang.modules.supply.warehouse.entity.CrmSupplyMaterialKeep;
import com.sifang.modules.supply.warehouse.entity.SupplyMaterialBatch;
import com.sifang.modules.supply.warehouse.request.InventoryOrderDetailReq;
import com.sifang.modules.supply.warehouse.request.InventoryOrderReq;
import com.sifang.modules.supply.warehouse.vo.ImportMaterialInfo;
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.common.utils.DateUtils;
import com.sifang.modules.sys.common.utils.IdGen;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.sifang.modules.kingdee.service.MisDeliveryService;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

@Service
public class InventoryOrderService extends BaseService {
    @Autowired
    private InventoryOrderDao inventoryOrderDao;
    @Autowired
    private InventoryOrderDetailDao inventoryOrderDetailDao;
    @Autowired
    private InventoryOrderMsgDao inventoryOrderMsgDao;
    @Autowired
    private CrmSupplyWarehouseDao warehouseDao;
    @Autowired
    private TraderDao traderDao;
    @Autowired
    private SupplyMaterialDao materialDao;

    @Autowired
    private CrmSupplyMaterialTypeDao materialTypeDao;
    @Autowired
    private CheckPendingOrderDao pendingOrderDao;

    @Autowired
    private CrmSupplyAllocationOrderService allocationOrderService;

    @Autowired
    private MaterialStockService materialStockService;

    @Autowired
    private SupplyMaterialBatchService batchService;

    @Autowired
    private SupplyMaterialKeepService materialKeepService;

    @Autowired
    TaskService taskService;
    @Autowired
    private ProcessFlowableService flowableService;

    @Autowired
    private BondApplyDao bondApplyDao;
    @Autowired
    private DepartmentSettingDao departmentSettingDao;

    @Autowired
    TraderAccountDao accountDao;

    @Autowired
    CrmSupplyMaterialProjectPriceService  service;

    @Autowired
    private MiscellaneousService miscellaneousService;

    @Autowired
    private MisDeliveryService misDeliveryService;

    public LayuiPage getInventoryOrderPage(LayuiPage page, Map<String, String> map) {
        User user = UserUtils.getUser();
        List<Record> list = inventoryOrderDao.listInventoryOrder(page, map,user);
        page.setData(list);
        page.setCount(inventoryOrderDao.countInventoryOrder(map,user));
        return page;
    }

    public CrmSupplyInventoryOrder getByid(String id){
        return inventoryOrderDao.get(id);
    }

    public void save(CrmSupplyInventoryOrder order){
        inventoryOrderDao.save(order);
    }


    @Transactional(rollbackFor = Exception.class)
    public void saveInventoryOrder(InventoryOrderReq req) {
        User user = UserUtils.getUser();
        CrmDepartment dep = departmentSettingDao.get(user.getDepartmentId());
        if(dep ==null){
            throw new BusinessException("当前用户无操作权限");
        }
        // 保存前校验
        checkBeforeSave(req);

        BigDecimal totalAmount = BigDecimal.ZERO;
        BigDecimal totalDiff = BigDecimal.ZERO;
        CrmSupplyInventoryOrder order = null;
        //String id = IdGen.uuid();
        Date date = new Date();

        String xm = CrmUtils.getUserXM(user);

        CrmSupplyWarehouse warehouse = warehouseDao.get(req.getWarehouseId());
        if (StrKit.isBlank(req.getId())) {// 新增
            order = new CrmSupplyInventoryOrder();
            order.setId(IdGen.uuid());
            order.setCode(PlantformUtils.findOrderNumber("PD"));
            order.setCreateTime(date);
            order.setInventoryId(user.getId());
            order.setInventoryName(xm);
            order.setInventoryTime(date);
            order.setStatus(InventoryOrderConstants.WAIT_AUDIT_1);
            order.setDepartmentId(user.getDepartmentId());
            order.setDepartmentName(dep.getName());

        } else {// 编辑
            order = inventoryOrderDao.get(req.getId());
            if (!StrKit.notNull(order)) {
                throw new BusinessException("盘点单不存在");
            }
            if (!InventoryOrderConstants.REJECT.equals(order.getStatus()) && !InventoryOrderConstants.DETAIL_STATUS_NORMAL.equals(order.getStatus())) {
                throw new BusinessException("盘点单状态发生变化");
            }
            order.setReasonsForFailure(null);
            order.setStatus(InventoryOrderConstants.WAIT_AUDIT_1);
            // 将原来的明细置为失效
            inventoryOrderDetailDao.updateBySql("update crm_supply_inventory_order_detail set status = '1' where inventory_id=:p1", new Parameter(req.getId()));
        }
        order.setImg(req.getImg());
        order.setWarehouseId(warehouse.getId());
        order.setWarehouseName(warehouse.getName());
        order.setInventoryType(req.getInventoryType());
        order.setInventoryObjectId(warehouse.getAscriptionId());
        order.setInventoryObjectName(warehouse.getAscriptionName());

        order.setRemarks(req.getRemarks());
        order.setAmount(totalAmount);
        order.setDifferenceAmount(totalDiff);
        // 创建新的明细
        List<InventoryOrderDetailReq> details = req.getDetails();
        int sort = 1;

        for (InventoryOrderDetailReq detail : details) {
            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            CrmSupplyMaterialType materialType = materialTypeDao.get(material.getMaterialTypeId());

            MaterialWarehouseStocks stocks = allocationOrderService.findWatehouseStock(material.getId(), req.getWarehouseId(), user);

            CrmSupplyInventoryOrderDetail orderDetail = new CrmSupplyInventoryOrderDetail();
            orderDetail.setInventoryId(order.getId());
            orderDetail.setSort(sort);
            orderDetail.setMaterialId(material.getId());
            orderDetail.setMaterialCode(material.getCode());
            orderDetail.setMaterialType(materialType.getName());
            orderDetail.setMaterialRemarks(material.getRemarks());
            orderDetail.setMaterialUnit(material.getUnitName());
            orderDetail.setStock(stocks.getWarning());
            orderDetail.setAmount(detail.getAmount());
            orderDetail.setDifferenceAmount(orderDetail.getAmount().subtract(orderDetail.getStock()));
            orderDetail.setStatus(InventoryOrderConstants.DETAIL_STATUS_NORMAL);
            orderDetail.setCostPrice(BigDecimal.ZERO);
           /* orderDetail.setBdSalePrice(detail.getBdSalePrice());*/
            totalAmount = totalAmount.add(orderDetail.getAmount());
            totalDiff = totalDiff.add(orderDetail.getDifferenceAmount());
            inventoryOrderDetailDao.save(orderDetail);
            sort ++;
        }
        order.setAmount(totalAmount);
        order.setDifferenceAmount(totalDiff);
        /*if (StrKit.notBlank(req.getId())) {// 编辑
            inventoryOrderMsgDao.addMsg(user, InventoryMsgConstants.EDIT, order.getId(), "");
        } else */
        if(StrKit.isBlank(req.getId())) {
            inventoryOrderMsgDao.addMsg(user, InventoryMsgConstants.ADD, order.getId(), "");
            //提交流程
            Record rd = FormUtils.getdefLatest(FormUtils.INVEBNTORY_ORDER_APPLICATION);
            if(rd == null){
                throw  new RuntimeException("流程未定义，不可发布申请");
            }
            //启动流程
            String processName="盘点单申请-"+user.getUserName()+'-'+ DateUtils.formatDate(date,"yyyy-MM-dd HH:mm:ss");
            String processInstanceId=flowableService.startProcessFlowable(user,order.getId(),rd, FormUtils.INVEBNTORY_ORDER_APPLICATION,date,xm,req.getRemarks(),processName,"");
            order.setProcessInstanceId(processInstanceId);
            order.setProcessDefId(rd.getStr("id"));

            order.setOperateUserIds(user.getId()+","+rd.getStr("oneAuditUseId"));
            String taskName=FormUtils.getOneStepTaskName(rd.getStr("id"));
            order.setTaskName(taskName);

           /* Task vacationApply = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
            order.setTaskName(vacationApply.getName());
            order.setTaskId(vacationApply.getId());*/

        }else if(StringUtil.isNotBlank(order.getProcessInstanceId())){
            inventoryOrderMsgDao.addMsg(user, InventoryMsgConstants.EDIT, order.getId(), "");
           /* flowableService.approveTask(order.getTaskId(),"编辑后提交",order.getId(),user,date,FormUtils.INVEBNTORY_ORDER_APPLICATION,order.getProcessDefId());
            Task vacationApply = taskService.createTaskQuery().processInstanceId(order.getProcessInstanceId()).singleResult();
            if(vacationApply!=null){
                order.setTaskName(vacationApply.getName());
                order.setTaskId(vacationApply.getId());
            }*/
            Task task = taskService.createTaskQuery().processInstanceId(order.getProcessInstanceId()).taskAssignee(user.getId()).singleResult();
            flowableService.approveTask2(task,"编辑后提交",order.getId(),user, FormUtils.INVEBNTORY_ORDER_APPLICATION);
        }
        inventoryOrderDao.save(order);
    }

    @Transactional(rollbackFor = Exception.class)
    public void firstAudit(String id,String content) {
        User user = UserUtils.getUser();
        CrmSupplyInventoryOrder order = inventoryOrderDao.get(id);
        checkStatusBeforeAudit(order);
      //  order.setStatus(InventoryOrderConstants.WAIT_AUDIT_2);
        setAuditInfo(order);
        Date date=new Date();
       /* //审批通过
        flowableService.approveTask(order.getTaskId(),content,order.getId(),user,date,FormUtils.INVEBNTORY_ORDER_APPLICATION,order.getProcessDefId());
        Task vacationApply = taskService.createTaskQuery().processInstanceId(order.getProcessInstanceId()).singleResult();
        if(vacationApply!=null){
            order.setTaskName(vacationApply.getName());
            order.setTaskId(vacationApply.getId());
        }*/
        order.setOperateUserIds(order.getOperateUserIds()+","+user.getId());
        inventoryOrderDao.save(order);
        inventoryOrderMsgDao.addMsg(user, InventoryMsgConstants.PASS, order.getId(), "");
        Task task = taskService.createTaskQuery().processInstanceId(order.getProcessInstanceId()).taskAssignee(user.getId()).singleResult();
        flowableService.approveTask2(task,content,order.getId(),user, FormUtils.INVEBNTORY_ORDER_APPLICATION);
    }

    private void checkStatusBeforeAudit(CrmSupplyInventoryOrder order) {
        if (!StrKit.notNull(order)) {
            throw new BusinessException("盘点单不存在");
        }
        if (!InventoryOrderConstants.WAIT_AUDIT_1.equals(order.getStatus())) {
            throw new BusinessException("盘点单状态发生改变");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void reject(String id,String reason) {
        User user = UserUtils.getUser();
        CrmSupplyInventoryOrder order = inventoryOrderDao.get(id);
        checkStatusBeforeAudit(order);
        order.setStatus(InventoryOrderConstants.WAIT_AUDIT_2);
        order.setReasonsForFailure(reason);
        setAuditInfo(order);
       /* flowableService.rejectTask(order.getTaskId(),reason,id,user,FormUtils.INVEBNTORY_ORDER_APPLICATION);
        Task vacationApply = taskService.createTaskQuery().processInstanceId(order.getProcessInstanceId()).singleResult();
        if(vacationApply!=null){
            order.setTaskName(vacationApply.getName());
            order.setTaskId(vacationApply.getId());
        }*/
        order.setOperateUserIds(order.getOperateUserIds()+","+user.getId());
        inventoryOrderDao.save(order);
        inventoryOrderMsgDao.addMsg(user, InventoryMsgConstants.REJECT, order.getId(), reason);
        Task task = taskService.createTaskQuery().processInstanceId(order.getProcessInstanceId()).taskAssignee(user.getId()).singleResult();
        flowableService.rejectTask2(task,reason,id,user,FormUtils.WITHDRAWAL_WARRANTY_APPLICATION,order.getInventoryId());
    }





    @Transactional(rollbackFor = Exception.class)
    public void deleteOrder(String ids) {
        User user = UserUtils.getUser();
        String[] idArray = ids.split(",");
        for (String s : idArray) {
            CrmSupplyInventoryOrder order = inventoryOrderDao.get(s);
            if (!StrKit.notNull(order)) {
                throw new BusinessException("盘点单不存在");
            }
            if (!InventoryOrderConstants.REJECT.equals(order.getStatus())) {
                throw new BusinessException("盘点单状态发生变化");
            }
            order.setStatus(InventoryOrderConstants.DELETED);
            inventoryOrderDao.save(order);
            inventoryOrderMsgDao.addMsg(user, InventoryMsgConstants.DELETE, order.getId(), "");
        }
    }

    /**
     * 设置审批信息
     */
    private void setAuditInfo(CrmSupplyInventoryOrder order) {
        Date date = new Date();
        User user = UserUtils.getUser();
        order.setAuditBy(user.getId());
        order.setAuditName(CrmUtils.getUserXM(user));
        order.setAuditTime(date);
    }



    /**审核通过后更新库存信息
    */
    @Transactional(rollbackFor = Exception.class)
    public void inventoryLogic(CrmSupplyInventoryOrder order) {
        User user = UserUtils.getUser();
        order.setAuditBy(String.valueOf(user.getId()));
        order.setAuditName(user.getUserName());
        order.setAuditTime(new Date());
        List<CrmSupplyInventoryOrderDetail> details = inventoryOrderDetailDao.findOrderDetailList(order.getId());
        //入库明细
        List<CrmSupplyInventoryOrderDetail> inDetails = new ArrayList<>();

        //出库明细
        List<CrmSupplyInventoryOrderDetail> outDetails=new ArrayList<>();
        CrmSupplyWarehouse warehouse = warehouseDao.get(order.getWarehouseId());
        BigDecimal xsCount = BigDecimal.ZERO;
        for (CrmSupplyInventoryOrderDetail detail : details) {
            //入库记录id
          //

            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            detail.setUnitCode(material.getUnitCode());

            BigDecimal diffAmount = detail.getAmount().subtract(detail.getStock());
            SupplyMaterial fitting = materialDao.get(detail.getMaterialId());

            if (diffAmount.compareTo(BigDecimal.ZERO) > 0) {
                String keepId = IdGen.uuid();
                //更新统计表
                MaterialWarehouseStocks stocks = materialStockService.updateStockForInStock(fitting.getId(), warehouse, diffAmount,order.getInventoryType(),user.getId(),detail);
                //盘盈 入库 生成新批次
                SupplyMaterialBatch batch = batchService.createBatchForInventory(order, detail, keepId);
                //生成入库记录
                CrmSupplyMaterialKeep keep = materialKeepService.createMaterialKeepForAllot(order,detail,diffAmount,
                        BigDecimal.ZERO,user,"1",batch,keepId);
               // xsCount=xsCount.add(diffAmount.multiply(detail.getBdSalePrice()));

                inDetails.add(detail);
            } else if (diffAmount.compareTo(BigDecimal.ZERO) < 0) {//盘亏
                BigDecimal outAmount = diffAmount.abs();
                //计算实际出库的成本单价
//                BigDecimal totalCostPrice = BigDecimal.ZERO;
                //盘亏 出库
                List<SupplyMaterialBatch> batches = batchService.findBatchesByFIFO(detail.getMaterialId(), order.getWarehouseId(), outAmount);
                for (SupplyMaterialBatch batch : batches) {
                    //可出库数量
                    BigDecimal canOutNum = batch.getRemaining();
                    //实际出库数量
                    BigDecimal outNum = outAmount.compareTo(canOutNum) > 0 ? canOutNum : outAmount;
//                    totalCostPrice = totalCostPrice.add(batch.getCostPrice().multiply(outNum));
                    //修改批次记录
                    batchService.outStockForInventory(batch, outNum);
                    //更新统计表
                    MaterialWarehouseStocks stocks = materialStockService.updateStockForOutStock(fitting.getId(), order.getWarehouseId(), outNum);
                    //生成出库记录
                    CrmSupplyMaterialKeep keep = materialKeepService.createMaterialKeepForAllot(order,detail,outNum,
                            canOutNum,user,"2",batch,IdGen.uuid());

                 //   xsCount=xsCount.subtract(outNum.multiply(batch.getBdSalePrice()));//出库数量*当前批次的销售价

                    outAmount = outAmount.subtract(outNum);
                    if (outAmount.compareTo(BigDecimal.ZERO) <= 0) {
                        break;
                    }
                }
                if (outAmount.compareTo(BigDecimal.ZERO) != 0) {
                    throw new BusinessException("盘亏出库失败");
                }
                 outDetails.add(detail);
            }

        }

        //修改代理商的可授信额度
        /*if ("2".equals(order.getInventoryType())) {
            CrmTraderAccount account = accountDao.findByTraderId(order.getInventoryObjectId());
            if (account == null) {
                throw new BusinessException("请新增调入方的可授信额度！");
            }
            SQLQuery sql = accountDao.getSession()
                    .createSQLQuery("UPDATE crm_trader_account SET " +
                            "basic_quota_amount_balance = basic_quota_amount_balance-:unuse," +
                            "max_quota_amount_balance = max_quota_amount_balance-:maxbal  WHERE id =:id  AND basic_quota_amount =:availa ");
//            sql.setParameter("amount", xsCount);
            sql.setParameter("unuse", xsCount);
//            sql.setParameter("maxamount", xsCount);
            sql.setParameter("maxbal", xsCount);
            sql.setParameter("id", account.getId());
            sql.setParameter("availa", account.getBasicQuotaAmount());
            int count = sql.executeUpdate();
            if (count < 1) {
                throw new IllegalArgumentException("修改代理商可授信额度失败");
            }
        }*/

    }



    /**添加代理商初始库存盘点
     */
    @Transactional(rollbackFor = Exception.class)
    public void initiMethod(String id,String warehouse_id) {
        User user = UserUtils.getUser();
        CrmTrader trader = traderDao.get(id);
        String qqProjectCode = trader.getQqProjectCode();
        CrmSupplyWarehouse warehouse = warehouseDao.get(warehouse_id);
        List<Record> list = inventoryOrderDao.inintStock();
        String bizId = IdGen.uuid();
        String bizCode = PlantformUtils.findOrderNumber("CSKC");
        if(list.size()>0){
            for (int i = 0; i <list.size() ; i++) {
                String keepId = IdGen.uuid();
                SupplyMaterial material = materialDao.get(list.get(i).getStr("materialId"));
                String materialQqCode = material.getQqCode();
                Record priceByCodes = service.findPriceByCodes(qqProjectCode, materialQqCode);
                BigDecimal price;
                if(priceByCodes!=null){
                    price= priceByCodes.getBigDecimal("price");
                }else{
                    price=BigDecimal.ZERO;
                }
                //更新统计表
                MaterialWarehouseStocks warehouseStocks = materialStockService.findByWarehouse(material.getId(), warehouse.getId());
                //库存差
                BigDecimal subtract;
                if(warehouseStocks!=null){
                     subtract = new BigDecimal(list.get(i).getStr("stocks")).subtract(warehouseStocks.getWarning());
                }else{
                    subtract= new BigDecimal(list.get(i).getStr("stocks"));
                }
                if(subtract.compareTo(BigDecimal.ZERO)>0){
                MaterialWarehouseStocks stocks = materialStockService.updateStockForInStocks(warehouseStocks, material.getId(),
                        warehouse, user.getId(),price,subtract);
                //盘盈 入库 生成新批次
                SupplyMaterialBatch batch = batchService.createBatchForInventorys(subtract,material,bizId, bizCode, warehouse,keepId,price,id);
                //生成入库记录
                CrmSupplyMaterialKeep keep = materialKeepService.createMaterialKeepForInit(material,warehouse,subtract,
                        BigDecimal.ZERO,user,"1",batch,keepId);
            }
            }
        }

    }




    /**
     * 创建 待审核订单
     */
    private void createCheckPendingOrder(CrmSupplyInventoryOrder order) {
        CrmSupplyCheckPendingOrder pendingOrder = new CrmSupplyCheckPendingOrder();
        Date date = new Date();
        pendingOrder.setOrderId(order.getId());
        pendingOrder.setCode(order.getCode());
        pendingOrder.setWarehouseId(order.getWarehouseId());
        pendingOrder.setWarehouseName(order.getWarehouseName());
        pendingOrder.setOrderType(PendingOrderConstants.PD);
        pendingOrder.setDeliverMethodId("");
        pendingOrder.setDeliverMethodName("");
        // “发货单位”、“收货单位”均填充“盘点对象”
        pendingOrder.setForwardingUnit(order.getInventoryObjectName());
        pendingOrder.setReceivingUnit(order.getInventoryObjectName());
        // 下单时间存盘点时间
        pendingOrder.setPlaceOrderTime(date);
        pendingOrder.setRemarks(order.getRemarks());
        pendingOrder.setStatus(PendingOrderConstants.WAIT_AUDIT);
        pendingOrder.setCreateTime(date);
        pendingOrderDao.save(pendingOrder);
    }

    public void checkBeforeSave(InventoryOrderReq req) {
        CrmSupplyWarehouse warehouse = warehouseDao.get(req.getWarehouseId());
        if (!StrKit.notNull(warehouse)) {
            throw new BusinessException("盘点仓库不存在");
        }
        if (!WarehouseConstants.NORMAL.equals(warehouse.getStatus())) {
            throw new BusinessException("盘点仓库状态异常");
        }
        List<InventoryOrderDetailReq> details = req.getDetails();
        if (details.isEmpty()) {
            throw new BusinessException("盘点明细不能为空");
        }

        int index = 1;
        for (InventoryOrderDetailReq detail : details) {
            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            if (!StrKit.notNull(material)) {
                throw new BusinessException("第" + index + "行物料不存在");
            }
            if (!MaterialConstants.NORMAL.equals(material.getStatus())) {
                throw new BusinessException("第" + index + "行物料状态异常");
            }
            if (BigDecimal.ZERO.compareTo(detail.getAmount()) > 0) {
                throw new BusinessException("第" + index + "行盘点数量不能小于0");
            }

            index ++;
        }

    }

    public List<Record> getDetails(String mainId) {
        return inventoryOrderDetailDao.listDetailByMainId(mainId);
    }

    public List<Record> listMsg(String id) {
        return inventoryOrderMsgDao.listMsg(id);
    }

    /**
     * 校验导入的物料
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> checkImportExcel(Map<String, String> params, InputStream in) {
        Map<String, Object> retMap = Maps.newHashMap();
        retMap.put("operType", "check");
        InventutyExcelImportHandler handler = new InventutyExcelImportHandler();
        handler.setStartSheet(1);
        handler.setStartRow(2);
        try {
            new ExcelReader().check(in, params.get("extName"), handler);
            Map<String, Object> map = (Map<String, Object>) handler.getHandlerResult();
            String templateError = (String) map.get("TemplateError");
            if(!handler.isCheckFlag()){
                handler.appendErrorDetail("<p>未填充数据</p>");
            }
            String hanl = handler.getErrorDetail();
            if (StrKit.notBlank(templateError)){
                retMap.put("errorDetail", templateError);
                retMap.put("errorMessage", "y");
            }else if (StringUtils.isNotBlank(hanl)) {
                retMap.put("errorDetail", hanl);
                retMap.put("errorMessage", "y");
            } else if ("overLimit".equalsIgnoreCase((String) map.get("overLimit"))) {
                retMap.put("overLimit", "y");
            } else {
                retMap.put("pass", "y");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return retMap;
    }

    /**
     * 导入物料数据
     */
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> importInventoryData(Map<String, String> params, InputStream in) {
        Map<String, Object> retMap = Maps.newHashMap();
        retMap.put("operType", "import");
        InventutyExcelImportHandler handler = new InventutyExcelImportHandler();
        handler.setStartSheet(1);
        handler.setStartRow(3);
        try {
            new ExcelReader().readExcel(in, params.get("fileName"), handler);
            retMap.put("pass", "y");
            List<ImportMaterialInfo> materialInfos = handler.getRetList();
            if (StrKit.notNull(params.get("warehouseId"))) {// 有仓库id，则需要set stocks再返回
                Map<String, Object> map = dealImportMaterialInfos(materialInfos, (String) params.get("warehouseId"));
                retMap.put("totalAmount", map.get("totalAmount"));
                retMap.put("totalDiff", map.get("totalDiff"));
            }
            retMap.put("materialList", handler.getRetList());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return retMap;
    }

    /**
     * 给导入结果set库存(stocks)
     * 盘点时 前端需要展示
     */
    public Map<String, Object> dealImportMaterialInfos(List<ImportMaterialInfo> materialInfos, String warehouseId) {
        Map<String, Object> retMap = new HashMap<>();
        BigDecimal totalAmount = BigDecimal.ZERO;
        BigDecimal totalStocks = BigDecimal.ZERO;
        for (ImportMaterialInfo info : materialInfos) {
            MaterialWarehouseStocks stocks = materialStockService.findByWarehouse(info.getMaterialId(), warehouseId);
            if(stocks== null){
                info.setStocks(BigDecimal.ZERO );
            }else{
                info.setStocks(stocks.getWarning());
//                info.setCostPrice(stocks.getCostPrice());
                info.setBdSalePrice(stocks.getBdSalePrice());

            }


            totalAmount = totalAmount.add(info.getAmount());
            totalStocks = totalStocks.add(info.getStocks());
        }
        retMap.put("totalAmount", totalAmount);
        retMap.put("totalDiff", totalAmount.subtract(totalStocks));
        return retMap;
    }

}
