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

import com.alibaba.fastjson.JSONObject;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.account.dao.TraderAccountDao;
import com.sifang.modules.account.entity.CrmTraderAccount;
import com.sifang.modules.customer.dao.CustomerEntryDao;
import com.sifang.modules.customer.entity.CustomerEntry;
import com.sifang.modules.flowpath.service.SettlementAmountAdjustmentApplyService;
import com.sifang.modules.kingdee.service.MiscellaneousService;
import com.sifang.modules.platform.utils.PlantformUtils;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sunshine.SystemSetting.utils.CustomException;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.supply.order.dao.MaterialDeliverDao;
import com.sifang.modules.supply.order.dao.MaterialReturnOrderDao;
import com.sifang.modules.supply.order.dao.MaterialReturnOrderDetailDao;
import com.sifang.modules.supply.order.dao.MaterialReturnOrderMsgDao;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialDeliverOrder;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialReturnOrder;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialReturnOrderDetail;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialReturnOrderMsg;
import com.sifang.modules.supply.order.request.AddReturnOrderReq;
import com.sifang.modules.supply.order.request.ReturnOrderDetailReq;
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.SupplyMaterialKeepService;
import com.sifang.modules.supply.warehouse.constant.InventoryOrderConstants;
import com.sifang.modules.supply.warehouse.entity.SupplyMaterialBatch;
import com.sifang.modules.supply.warehouse.service.SupplyMaterialBatchService;
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.IdGen;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.sys.util.SqlBuilder;
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class MaterialReturnOrderService extends BaseService {

    @Autowired
    private MaterialReturnOrderDao returnOrderDao;
    @Autowired
    private MaterialReturnOrderDetailDao detailDao;
    @Autowired
    private MaterialReturnOrderMsgDao msgDao;
    @Autowired
    private MaterialDeliverDao materialDeliverDao;
    @Autowired
    private SupplyMaterialBatchService batchService;
    @Autowired
    private MaterialStockDao materialStockDao;
    @Autowired
    private SupplyMaterialKeepService materialKeepService;
    @Autowired
    private CrmSupplyWarehouseDao warehouseDao;
    @Autowired
    private CustomerEntryDao customerEntryDao;
    @Autowired
    private SupplyMaterialDao materialDao;
    @Autowired
    private SettlementAmountAdjustmentApplyService saaApplyService;
    @Autowired
    private TraderAccountDao accountDao;


    //平台退货
    public void returnOrderPageList(LayuiPage<Record> page, Map<String, String> map) {
        List<Record> list = returnOrderDao.getList(page, map);
        Long count = returnOrderDao.countList(map);
        page.setData(list);
        page.setCount(count);
    }

    //代理商退货
    public void getTraderReturnList(LayuiPage<Record> page, Map<String, String> map, String traderId) {
        List<Record> list = returnOrderDao.getTraderReturnList(page, map, traderId);
        Long count = returnOrderDao.traderReturnCountList(map, traderId);
        page.setData(list);
        page.setCount(count);
    }

    //供应商退货
    public void getSupplyReturnList(LayuiPage<Record> page, Map<String, String> map, String supplyId) {
        List<Record> list = returnOrderDao.getSupplyReturnList(page, map, supplyId);
        Long count = returnOrderDao.supplyReturnCountList(map, supplyId);
        page.setData(list);
        page.setCount(count);
    }


    public List<Record> findDeliverOrderByNumber(String number, String belongType) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("SELECT od.material_id,od.material_type,od.material_spec,od.in_amount,od.apply_amount")
                .line(",od.sales_price,od.purchase_price,o.in_warehouse_id,m.code,m.material_name,m.material_brand,m.unit_name")
                .line(",(SELECT IFNULL(SUM(return_num),0) FROM crm_supply_material_return_order_detail rod")
                .line("LEFT JOIN crm_supply_material_return_order ro ON ro.id = rod.main_id AND ro.status <> '4'")
                .line("WHERE ro.relation_number = ? AND rod.status = '0' AND rod.material_id = od.material_id) AS returnNum", number)
                .line("FROM crm_supply_material_deliver_order_detail od")
                .line("LEFT JOIN crm_supply_material_deliver_order o ON o.id = od.main_id AND o.status = '7'")
                .line("LEFT JOIN crm_supply_material m ON m.id = od.material_id AND m.status = '1'")
                .line("WHERE o.number = ? AND od.status = '0'", number);
        if ("1".equals(belongType)) {//平台退货
            builder.line(" and o.pattern = '1' ");
        } else {//供应商退货
            builder.line(" and o.pattern in ('2','3') ");
        }
        return Db.find(builder.build(), builder.params());
    }

    public List<Record> findDeliverOrderById(String id) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("SELECT od.material_id,od.material_type,od.material_spec,od.in_amount,od.apply_amount")
                .line(",od.sales_price,od.purchase_price,o.in_warehouse_id,m.code,m.material_name,m.material_brand,m.unit_name")
                .line(",(SELECT IFNULL(SUM(return_num),0) FROM crm_supply_material_return_order_detail rod")
                .line("LEFT JOIN crm_supply_material_return_order ro ON ro.id = rod.main_id AND ro.status <> '4'")
                .line("WHERE ro.relation_id = ? AND rod.status = '0' AND rod.material_id = od.material_id) AS returnNum", id)
                .line("FROM crm_supply_material_deliver_order_detail od")
                .line("LEFT JOIN crm_supply_material_deliver_order o ON o.id = od.main_id AND o.status = '7'")
                .line("LEFT JOIN crm_supply_material m ON m.id = od.material_id AND m.status = '1'")
                .line("WHERE o.id = ? AND od.status = '0'", id);
        return Db.find(builder.build(), builder.params());
    }

    @Transactional(rollbackFor = Exception.class)
    public void addReturnOrder(AddReturnOrderReq orderVo) {
        User user = UserUtils.getUser();
        Date dt = new Date();
        StringBuffer sb = new StringBuffer();
        CrmSupplyMaterialDeliverOrder materialDeliverOrder = materialDeliverDao.getByHql("from CrmSupplyMaterialDeliverOrder where number =:p1 ", new Parameter(orderVo.getRelationNumber()));
        CrmSupplyMaterialReturnOrder returnOrder;
        if (StringUtil.isNotBlank(orderVo.getId())) {
            sb.append("编辑退货订单 ");
            returnOrder = returnOrderDao.get(orderVo.getId());
            if (returnOrder == null) {
                throw new BusinessException("未获取到退货单信息！");
            }
        } else {
            sb.append("创建退货订单 ");
            returnOrder = new CrmSupplyMaterialReturnOrder();
            returnOrder.setNumber(PlantformUtils.findOrderNumber("TH"));
            returnOrder.setId(IdGen.uuid());
            returnOrder.setCreator(CrmUtils.getUserXM(user));
            returnOrder.setCreateBy(user.getId());
            returnOrder.setCreateTime(dt);
            returnOrder.setType(orderVo.getType());
        }
        returnOrder.setStatus("1");
        returnOrder.setRelationId(materialDeliverOrder.getId());
        returnOrder.setRelationNumber(materialDeliverOrder.getNumber());
        returnOrder.setTraderId(materialDeliverOrder.getTraderId());
        returnOrder.setTraderName(CrmUtils.getTraderNameById(materialDeliverOrder.getTraderId()));
        returnOrder.setSupplyId(materialDeliverOrder.getSupplyId());
        returnOrder.setReturnMethodId(orderVo.getReturnMethodId());
        returnOrder.setReturnMethodName(orderVo.getReturnMethodName());
        returnOrder.setExpressNo(orderVo.getExpressNo());
        returnOrder.setReturnDriver(orderVo.getRetrunDriver());
        returnOrder.setReturnMobile(orderVo.getReturnMobile());
        returnOrder.setReturnCarNum(orderVo.getReturnCarNum());
        returnOrder.setReturnRemark(orderVo.getReturnRemark());
        returnOrder.setWarehouseId(orderVo.getWarehouseId());
        if (StringUtil.isNotEmpty(orderVo.getWarehouseId())) {
            CrmSupplyWarehouse warehouse =  warehouseDao.get(orderVo.getWarehouseId());
            returnOrder.setWarehouseName(warehouse.getName());
            returnOrder.setWarehouseAddress(warehouse.getAddress());
            returnOrder.setPersonInCharge(warehouse.getPersonInCharge());
            returnOrder.setPersonMobile(warehouse.getMobile());
        }
        returnOrder.setDeliverId(materialDeliverOrder.getDeliverId());
        returnOrder.setDeliverName(materialDeliverOrder.getDeliverName());
        returnOrderDao.save(returnOrder);
        msgDao.addMsg(user, MaterialReturnOrderMsgDao.STATUS_CJ, returnOrder.getId(), sb.toString());
        List<ReturnOrderDetailReq> details = orderVo.getDetails();
        List<CrmSupplyMaterialReturnOrderDetail> saveList = new ArrayList<>();
        int sort=1;
        for (ReturnOrderDetailReq detail : details) {
            //校验仓库库存
            MaterialWarehouseStocks warehouseStocks = materialStockDao.getByHql(" from MaterialWarehouseStocks where materialId = :p1 AND warehouseId = :p2", new Parameter(detail.getMaterialId(), returnOrder.getWarehouseId()));
            if (warehouseStocks == null) {
                throw new BusinessException(" 仓库里面没有该物料 ！");
            }
            if (warehouseStocks.getWarning().compareTo(new BigDecimal(detail.getNum())) < 0) {
                throw new BusinessException(" 库存数量不足 ！");
            }

            CrmSupplyMaterialReturnOrderDetail orderDetail = new CrmSupplyMaterialReturnOrderDetail();
            // 查询物料信息
            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            orderDetail.setMainId(returnOrder.getId());
            orderDetail.setNumber(returnOrder.getNumber());
            orderDetail.setMaterialId(detail.getMaterialId());
            orderDetail.setMaterialName(material.getMaterialName());
            orderDetail.setMaterialCode(material.getCode());
            orderDetail.setMaterialSpec(material.getMaterialSpecs());
            orderDetail.setMaterialType(detail.getMaterialType());
            orderDetail.setMaterialBrand(material.getMaterialBrand());
            orderDetail.setMaterialUnit(material.getUnitName());
            orderDetail.setMaterialRemarks(material.getRemarks());
            orderDetail.setOrderNum(new BigDecimal(detail.getApplyAmount()));
            orderDetail.setDeliverNum(new BigDecimal(detail.getOutAmount()));
            orderDetail.setReturnNum(new BigDecimal(detail.getNum()));
            orderDetail.setStatus("0");
            orderDetail.setSort(sort);
            orderDetail.setCostPrice(new BigDecimal(detail.getCostPrice()));
            orderDetail.setSalesPrice(new BigDecimal(detail.getSalesPrice()));
            saveList.add(orderDetail);
            sort++;
        }
        if (StringUtil.isNotBlank(orderVo.getId())) {
            //编辑——处理明细表旧数据
            detailDao.deleteAllDetail(returnOrder.getId());
        }
        detailDao.save(saveList);
    }

    public Record getReturnMethodDetail(String returnMethodId) {
        return Db.findFirst(" SELECT id,driver_name,mobile,car_number FROM `crm_supply_delivery_method_detail` WHERE delivery_method_id = ? and status = '1' ", returnMethodId);
    }

    //电站物料信息
    public List<Record> findPSOrderByNumber(String number, String traderId) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("SELECT me.material_id,me.code,me.name,me.type,me.spec,me.barcode,me.amount,m.material_brand,m.unit_name")
                .line("FROM crm_plan_material_entry me")
                .line("LEFT JOIN crm_customer_entry ce ON ce.id = me.entry_id AND ce.distributor_id=? AND ce.status = 'a'",traderId)
                .line("LEFT JOIN crm_supply_material m ON m.id = me.material_id AND m.status = '1'")
                .line("LEFT JOIN (SELECT rod.material_id FROM crm_supply_material_return_order_detail rod")
                .line("LEFT JOIN crm_supply_material_return_order ro ON ro.id = rod.main_id AND ro.status <> '4' WHERE ro.relation_number =?",number)
                .line(") rods ON rods.material_id <> me.material_id")
                .line("WHERE ce.power_station_code = ? AND me.status = '0'",number);
        logger.info("findPSOrderByNumber sql={}",builder.build());
        logger.info("findPSOrderByNumber params={}", JSONObject.toJSONString(builder.params()));
        return Db.find(builder.build(), builder.params());
    }

    //平台确认收货
    @Transactional(rollbackFor = Exception.class)
    public void confirmReturnOrder(String returnOrderId, String voucherImgs) {
        User user = UserUtils.getUser();
        CrmSupplyMaterialReturnOrder returnOrder = returnOrderDao.get(returnOrderId);
        String userXm = CrmUtils.getUserXM(user);
        if (returnOrder == null) {
            throw new BusinessException(" 退货单不存在！");
        }
        if (!"1".equals(returnOrder.getStatus())) {
            throw new BusinessException(" 订单状态已改变！");
        }
        returnOrder.setConfirmName(userXm);
        returnOrder.setConfirmTime(new Date());
        returnOrder.setVoucherImg(voucherImgs);
        returnOrder.setStatus("3");
        List<CrmSupplyMaterialReturnOrderDetail> details = detailDao.getDetail(returnOrder.getId());
        StringBuffer str = new StringBuffer(userXm + " 操作退货");
        for (CrmSupplyMaterialReturnOrderDetail detail : details) {
            BigDecimal sunReturnNum = detailDao.getAllReturnNum(returnOrder.getRelationNumber(), detail.getMaterialId());
            if (sunReturnNum.compareTo(detail.getDeliverNum()) > 0) {
                throw new BusinessException(" 退货总数不可大于签收数量！");
            }
            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            BigDecimal outAmount = detail.getReturnNum();
            logger.info(">>>>>>>>>>>>>>>>>>>平台退货入库 detailId:{},materialId:{},returnNum:{}", detail.getId(), detail.getMaterialId(), detail.getReturnNum());
            //修改仓库库存
            MaterialWarehouseStocks warehouseStocks = materialStockDao.getByHql(" from MaterialWarehouseStocks where materialId = :p1 AND warehouseId = :p2", new Parameter(detail.getMaterialId(), returnOrder.getWarehouseId()));
            if (warehouseStocks == null) {
                throw new BusinessException(" 仓库里面没有该物料 ！");
            }
            if (warehouseStocks.getWarning().compareTo(outAmount) < 0) {
                throw new BusinessException(" 库存数量不足 ！");
            }
            warehouseStocks.setWarning(warehouseStocks.getWarning().subtract(outAmount));
            warehouseStocks.setRealNum(warehouseStocks.getRealNum().subtract(outAmount));
            warehouseStocks.setNewestKeepTime(new Date());
            materialStockDao.save(warehouseStocks);
            List<SupplyMaterialBatch> batches = batchService.findBatchesByFIFO(detail.getMaterialId(), returnOrder.getWarehouseId(), null);
            if (batches == null || batches.isEmpty()) {
                throw new BusinessException(" 退货仓库库存不足！");
            }
            for (SupplyMaterialBatch batch : batches) {
                if (outAmount.compareTo(BigDecimal.ZERO) <= 0) {
                    break;
                }
                //出库记录id
                String keepId = IdGen.uuid();
                //可出库数量
                BigDecimal canOutNum = batch.getRemaining();
                //实际出库数量
                BigDecimal outNum = outAmount.compareTo(canOutNum) > 0 ? canOutNum : outAmount;
                outAmount = outAmount.subtract(outNum);
                //修改批次记录
                batchService.outStockForInventory(batch, outNum);
                //生成出库记录
                materialKeepService.createReturnOrderOutMatKeep(returnOrder, detail, outNum, user, "2", batch, keepId);
            }

        }
        returnOrderDao.save(returnOrder);
        msgDao.addMsg(user, MaterialReturnOrderMsgDao.STATUS_QRDD, returnOrder.getId(), str.toString());
    }

    /**
     * 供应商确认收货
     * 减去代理商库存  增加平台库存(添加新的批次)
     */
    @Transactional(rollbackFor = Exception.class)
    public void confirmTraderReturnOrder(String returnOrderId, String warehouseId, String voucherImgs) {
        User user = UserUtils.getUser();
        CrmSupplyMaterialReturnOrder returnOrder = returnOrderDao.get(returnOrderId);
        String userXm = CrmUtils.getUserXM(user);
        if (returnOrder == null) {
            throw new BusinessException(" 退货单不存在！");
        }
        if (!"1".equals(returnOrder.getStatus())) {
            throw new BusinessException(" 订单状态已改变！");
        }
//        CrmSupplyMaterialDeliverOrder deliverOrder = materialDeliverDao.get(returnOrder.getRelationId());
//        String traderWarehouseId = deliverOrder.getInWarehouseId();
        returnOrder.setConfirmName(userXm);
        returnOrder.setConfirmTime(new Date());
        returnOrder.setVoucherImg(voucherImgs);
        returnOrder.setInWarehouseId(warehouseId);
        CrmSupplyWarehouse warehouse =  warehouseDao.get(warehouseId);
        returnOrder.setInWarehouseName(warehouse.getName());
        returnOrder.setStatus("3");
        List<CrmSupplyMaterialReturnOrderDetail> details = detailDao.getDetail(returnOrder.getId());
        StringBuffer str = new StringBuffer(userXm + " 操作退货");
        BigDecimal adjustAmount = BigDecimal.ZERO;
        BigDecimal totalAmount=BigDecimal.ZERO;
        for (CrmSupplyMaterialReturnOrderDetail detail : details) {
            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            BigDecimal sunReturnNum = detailDao.getAllReturnNum(returnOrder.getRelationNumber(), detail.getMaterialId());
            if (sunReturnNum.compareTo(detail.getDeliverNum()) > 0) {
                throw new BusinessException(" 退货数量不可大于签收数量！");
            }
            BigDecimal outAmount = detail.getReturnNum();
            logger.info(">>>>>>>>>>>>>>>>>>>代理商退货出库 detailId:{},materialId:{},returnNum:{}", detail.getId(), detail.getMaterialId(), detail.getReturnNum());
            //修改供应商仓库库存
            MaterialWarehouseStocks warehouseStocks = materialStockDao.getByHql(" from MaterialWarehouseStocks where materialId = :p1 AND warehouseId = :p2", new Parameter(detail.getMaterialId(), returnOrder.getWarehouseId()));
            if (warehouseStocks == null) {
                throw new BusinessException(" 仓库里面没有该物料 ！");
            }
            if (warehouseStocks.getWarning().compareTo(outAmount) < 0) {
                throw new BusinessException(" 库存数量不足 ！");
            }
            warehouseStocks.setWarning(warehouseStocks.getWarning().subtract(outAmount));
            warehouseStocks.setRealNum(warehouseStocks.getRealNum().subtract(outAmount));
            warehouseStocks.setNewestKeepTime(new Date());
            materialStockDao.save(warehouseStocks);
            List<SupplyMaterialBatch> batches = batchService.findBatchesByFIFO(detail.getMaterialId(), returnOrder.getWarehouseId(), null);
            if (batches == null || batches.isEmpty()) {
                throw new BusinessException(" 退货仓库库存不足！");
            }
            //扣减代理商库存
            for (SupplyMaterialBatch batch : batches) {
                if (outAmount.compareTo(BigDecimal.ZERO) <= 0) {
                    break;
                }
                //供应商可出库数量
                BigDecimal canOutNum = batch.getRemaining();
                //供应商实际出库数量
                BigDecimal outNum = outAmount.compareTo(canOutNum) > 0 ? canOutNum : outAmount;
                outAmount = outAmount.subtract(outNum);
                //修改供应商批次记录
                batchService.outStockForInventory(batch, outNum);
                //生成出库记录
                materialKeepService.createReturnOrderOutMatKeep(returnOrder, detail, outNum, user, "2", batch, IdGen.uuid());
                //计算调整金额
                if ("1".equals(material.getMaterialAttribute())) {
                    adjustAmount = adjustAmount.add(outNum.multiply(detail.getSalesPrice()));
                }
                //计算释放金额   自选产品不参与
                if ("0".equals(material.getMaterialAttribute())) {
                    totalAmount = totalAmount.add(outNum.multiply(detail.getSalesPrice()));
                }
            }

            //修改平台仓库库存
            MaterialWarehouseStocks inWarehouseStocks = materialStockDao.getByHql(" from MaterialWarehouseStocks where materialId = :p1 AND warehouseId = :p2", new Parameter(detail.getMaterialId(), returnOrder.getInWarehouseId()));
            if (inWarehouseStocks == null) {
                inWarehouseStocks=new MaterialWarehouseStocks();
                inWarehouseStocks.setMaterialId(detail.getMaterialId());
                inWarehouseStocks.setWarehouseId(warehouse.getId());
                inWarehouseStocks.setType("1");
                inWarehouseStocks.setAscriptionId(warehouse.getAscriptionId());
                inWarehouseStocks.setAscriptionName(warehouse.getAscriptionName());
                inWarehouseStocks.setWarning(detail.getReturnNum());
                inWarehouseStocks.setRealNum(detail.getReturnNum());
                inWarehouseStocks.setTotal(detail.getReturnNum());
                inWarehouseStocks.setCreateBy(user.getId());
                inWarehouseStocks.setCreateTime(new Date());
                inWarehouseStocks.setNewestStorageTime(new Date());
                inWarehouseStocks.setCostPrice(detail.getCostPrice());
                inWarehouseStocks.setBdSalePrice(detail.getSalesPrice());
            } else {
                inWarehouseStocks.setWarning(inWarehouseStocks.getWarning().add(detail.getReturnNum()));
                inWarehouseStocks.setRealNum(inWarehouseStocks.getRealNum().add(detail.getReturnNum()));
                inWarehouseStocks.setTotal(inWarehouseStocks.getTotal().add(detail.getReturnNum()));
                inWarehouseStocks.setNewestStorageTime(new Date());
            }

            materialStockDao.save(inWarehouseStocks);
            //平台库存生成新批次
            String keepId = IdGen.uuid();
            SupplyMaterialBatch batch = batchService.createBatchForReturn(returnOrder, detail, keepId, "1","a");
            //生成出库记录
            materialKeepService.createReturnOrderInMatKeep(returnOrder, detail, user, "1", batch, keepId);
        }
        //结算账户生成[自选产品退货] 记录
        if (adjustAmount.compareTo(BigDecimal.ZERO) > 0) {
            saaApplyService.saveSettlementAmountApplyFromReturn(returnOrder, adjustAmount);
        }
        // 释放授信额
        if (totalAmount.compareTo(BigDecimal.ZERO) > 0) {

            int row = accountDao.addMaxQuotaAmountBalanceAll(returnOrder.getTraderId(), totalAmount);
            if (row == 0) {
                throw new BusinessException("释放授信额失败");
            }
        }
        returnOrderDao.save(returnOrder);
        msgDao.addMsg(user, MaterialReturnOrderMsgDao.STATUS_QRDD, returnOrder.getId(), str.toString());
    }

    public List<Record> getAllDetail(String returnId) {
        return detailDao.getAllDetail(returnId);
    }

    public Record findOrderById(String id) {
        return returnOrderDao.findOrderById(id);
    }

    public List<CrmSupplyMaterialReturnOrderMsg> listMsgByOrderId(String id) {
        return msgDao.listMsgByOrderId(id);
    }

    public void deleteOrder(String orderId) throws CustomException {
        CrmSupplyMaterialReturnOrder order = returnOrderDao.get(orderId);
        if("3".equals(order.getStatus())){
            throw new CustomException("已完成订单不可删除","501");
        }
        User user = UserUtils.getUser();
        String userXm = CrmUtils.getUserXM(user);
        order.setStatus("4");
        order.setUpdateBy(user.getId());
        order.setUpdateTime(new Date());
        returnOrderDao.save(order);
        //删除明细数
        detailDao.deleteAllDetail(orderId);
        //更新过程信息
        msgDao.addMsg(user, MaterialReturnOrderMsgDao.STATUS_SC, orderId, userXm + " 删除退货单");
    }

    public void returnReject(String orderId, String reason) throws CustomException {
        CrmSupplyMaterialReturnOrder order = returnOrderDao.get(orderId);
        if(!"1".equals(order.getStatus()) && !"2".equals(order.getStatus())){
            throw new CustomException("订单状态已改变","501");
        }
        User user = UserUtils.getUser();
        String userXm = CrmUtils.getUserXM(user);
        order.setStatus("2");
        order.setUpdateBy(user.getId());
        order.setUpdateTime(new Date());
        order.setCancelReason(reason);
        order.setCancelTime(new Date());
        returnOrderDao.save(order);
        //更新过程信息
        StringBuilder sb = new StringBuilder();
        sb.append(userXm).append("操作退货驳回,驳回原因：").append(reason);
        msgDao.addMsg(user, MaterialReturnOrderMsgDao.STATUS_BH, orderId, sb.toString());
    }

    public BigDecimal findAllReturnedNum(String deliverId, String materialId, String id) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("SELECT SUM(return_num) FROM crm_supply_material_return_order_detail rod")
                .line("LEFT JOIN crm_supply_material_return_order ro ON ro.id = rod.main_id AND ro.status <> '4'")
                .line("WHERE ro.relation_id = ? AND rod.status = '0'", deliverId)
                .line("AND ro.id <> ?",id)
                .line("AND rod.material_id = ?",materialId);
        return Db.queryBigDecimal(builder.build(), builder.params());
    }

    @Transactional(rollbackFor = Exception.class)
    public void addReturnOrderPS(AddReturnOrderReq orderVo) {
        User user = UserUtils.getUser();
        Date dt = new Date();
        String name = CrmUtils.getUserXM(user);
        StringBuffer sb = new StringBuffer();
        sb.append("创建退货订单 ");
        CustomerEntry customerEntry = customerEntryDao.getByHql("from CustomerEntry where powerStationCode =:p1 ", new Parameter(orderVo.getRelationNumber()));
        CrmSupplyMaterialReturnOrder returnOrder = new CrmSupplyMaterialReturnOrder();
        returnOrder.setNumber(PlantformUtils.findOrderNumber("TH"));
        returnOrder.setCreator(name);
        returnOrder.setCreateBy(user.getId());
        returnOrder.setCreateTime(dt);
        returnOrder.setStatus("3");
        returnOrder.setRelationId(customerEntry.getId());
        returnOrder.setRelationNumber(customerEntry.getPowerStationCode());
        returnOrder.setType(orderVo.getType());
        returnOrder.setTraderId(customerEntry.getDistributorId());
        returnOrder.setTraderName(customerEntry.getTraderName());
        returnOrder.setReturnRemark(orderVo.getReturnRemark());
        returnOrder.setWarehouseId(orderVo.getWarehouseId());
        CrmSupplyWarehouse warehouse =  warehouseDao.get(orderVo.getWarehouseId());
        returnOrder.setWarehouseName(warehouse.getName());
        returnOrder.setWarehouseAddress(warehouse.getAddress());
        returnOrder.setPersonInCharge(warehouse.getPersonInCharge());
        returnOrder.setPersonMobile(warehouse.getMobile());
        returnOrder.setInWarehouseId(returnOrder.getWarehouseId());
        returnOrder.setInWarehouseName(returnOrder.getWarehouseName());
        returnOrder.setConfirmName(name);
        returnOrder.setConfirmTime(dt);
        returnOrder.setId(IdGen.uuid());
        msgDao.addMsg(user, MaterialReturnOrderMsgDao.STATUS_CJ, returnOrder.getId(), sb.toString());
        List<ReturnOrderDetailReq> details = orderVo.getDetails();
        List<CrmSupplyMaterialReturnOrderDetail> saveList = new ArrayList<>();
        List<String> barcodeList = new ArrayList<>();
        boolean flag = InventoryOrderConstants.DISTRIBUTOR.equals(warehouse.getType());
        BigDecimal totalAccountAmount = BigDecimal.ZERO;//代理商授信额
        for (ReturnOrderDetailReq detail : details) {
            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            CrmSupplyMaterialReturnOrderDetail orderDetail = new CrmSupplyMaterialReturnOrderDetail();
            orderDetail.setMainId(returnOrder.getId());
            orderDetail.setNumber(returnOrder.getNumber());
            orderDetail.setMaterialId(detail.getMaterialId());
            orderDetail.setMaterialName(detail.getMaterialName());
            orderDetail.setMaterialCode(detail.getMaterialCode());
            orderDetail.setMaterialSpec(detail.getMaterialSpec());
            orderDetail.setMaterialType(detail.getMaterialType());
            orderDetail.setMaterialBrand(detail.getMaterialBrand());
            orderDetail.setMaterialUnit(material.getUnitName());
            orderDetail.setMaterialRemarks(material.getRemarks());
//            orderDetail.setOrderNum(detail.getApplyAmount());
//            orderDetail.setDeliverNum(detail.getOutAmount());
            orderDetail.setReturnNum(new BigDecimal(detail.getNum()));
            orderDetail.setStatus("0");
            Record materialKeep = getMaterialKeep(returnOrder.getRelationId(), orderDetail.getMaterialId());
            if (materialKeep != null) {
                orderDetail.setCostPrice(materialKeep.getBigDecimal("cost_price"));
                orderDetail.setSalesPrice(materialKeep.getBigDecimal("bd_sale_price"));
            }
            orderDetail.setMaterialCode(material.getCode());
            saveList.add(orderDetail);
            barcodeList.add(detail.getBarcode());

            if(flag && orderDetail.getReturnNum()!=null && orderDetail.getSalesPrice()!=null){
                totalAccountAmount=totalAccountAmount.add(orderDetail.getReturnNum().multiply(orderDetail.getSalesPrice()));
            }
        }
        detailDao.save(saveList);

        for (CrmSupplyMaterialReturnOrderDetail detail : saveList) {
            //修改代理商仓库库存
            MaterialWarehouseStocks inStocks = materialStockDao.getByHql(" from MaterialWarehouseStocks where materialId = :p1 AND warehouseId = :p2", new Parameter(detail.getMaterialId(), returnOrder.getInWarehouseId()));
            if (inStocks == null) {
                inStocks=new MaterialWarehouseStocks();
                inStocks.setMaterialId(detail.getMaterialId());
                inStocks.setWarehouseId(warehouse.getId());
                inStocks.setType("2");
                inStocks.setAscriptionId(warehouse.getAscriptionId());
                inStocks.setAscriptionName(warehouse.getAscriptionName());
                inStocks.setWarning(detail.getReturnNum());
                inStocks.setRealNum(detail.getReturnNum());
                inStocks.setTotal(detail.getReturnNum());
                inStocks.setCreateBy(user.getId());
                inStocks.setCreateTime(dt);
                inStocks.setNewestStorageTime(dt);
                inStocks.setCostPrice(detail.getCostPrice());
                inStocks.setBdSalePrice(detail.getSalesPrice());
            } else {
                inStocks.setWarning(inStocks.getWarning().add(detail.getReturnNum()));
                inStocks.setRealNum(inStocks.getRealNum().add(detail.getReturnNum()));
                inStocks.setTotal(inStocks.getTotal().add(detail.getReturnNum()));
                inStocks.setNewestStorageTime(dt);
            }


            materialStockDao.save(inStocks);
            //代理商库存生成新批次
            String keepId = IdGen.uuid();
            SupplyMaterialBatch batch = batchService.createBatchForReturn(returnOrder, detail, keepId, "2",warehouse.getAscriptionId());
            //生成出库记录
            materialKeepService.createReturnOrderInMatKeep(returnOrder, detail, user, "1", batch, keepId);
        }
        //判断物料总额和 代理商授信额
        if (flag) {
            CrmTraderAccount account = accountDao.findByTraderId(warehouse.getAscriptionId());
            if (account == null) {
                throw new BusinessException("请新增代理商的可授信额度!");
            }
            if (account.getBasicQuotaAmountBalance().compareTo(totalAccountAmount) < 0) {
                throw new BusinessException("代理商标准授信额不足，不能通过!");
            }
            // 修改代理商账户
            if (totalAccountAmount.compareTo(BigDecimal.ZERO) > 0) {
                account.setBasicQuotaAmountBalance(account.getBasicQuotaAmountBalance().subtract(totalAccountAmount));
                account.setMaxQuotaAmountBalance(account.getMaxQuotaAmountBalance().subtract(totalAccountAmount));
                accountDao.save(account);
            }
        }
        returnOrderDao.save(returnOrder);
        if (!barcodeList.isEmpty() && StringUtil.isNotBlank(barcodeList.get(0))) {
            //将物料条码改为未使用
            SqlBuilder sql = new SqlBuilder();
            sql.line("update crm_supply_barcode set barcode_status='2' where barcode_status='1' and status = '0' ");
            sql.inst("and material_barcode in ", barcodeList);
            Db.update(sql.build(), sql.params());
        }
    }

    public Record getMaterialKeep(String sourceId, String materialId){
        return Db.findFirst("SELECT cost_price,bd_sale_price FROM crm_supply_material_keep where material_id=? AND source_id=?",materialId,sourceId);
    }

    public Record getCustomerEntryById(String id) {
        return Db.findFirst("select * from crm_customer_entry where id=?",id);
    }

    //电站物料信息
    public List<Record> findPSOrderById(String id) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("SELECT me.material_id,me.code,me.name,me.type,me.spec,me.barcode,me.amount,m.material_brand,m.unit_name")
                .line("FROM crm_plan_material_entry me")
                .line("LEFT JOIN crm_customer_entry ce ON ce.id = me.entry_id AND ce.status = 'a'")
                .line("LEFT JOIN crm_supply_material m ON m.id = me.material_id AND m.status = '1'")
                .line("WHERE ce.id = ? AND me.status = '0'",id);
        return Db.find(builder.build(), builder.params());
    }

    public String getWarehouseName(String sourceId) {
        return Db.queryStr("select warehouse_name from crm_supply_material_keep where source_id=? limit 1",sourceId);
    }

}
