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

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.kingdee.service.KingDeePurchaseInWarehouseService;
import com.sifang.modules.kingdee.service.MiscellaneousService;
import com.sifang.modules.platform.utils.PlantformUtils;
import com.sifang.modules.sunshine.SystemSetting.dao.TraderDao;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmTrader;
import com.sifang.modules.sunshine.SystemSetting.service.TraderService;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.supply.order.constant.DeliverOrderConstants;
import com.sifang.modules.supply.order.constant.MaterialBatchConstants;
import com.sifang.modules.supply.order.constant.PendingOrderConstants;
import com.sifang.modules.supply.order.dao.CheckPendingOrderDao;
import com.sifang.modules.supply.order.dao.MaterialDeliverDao;
import com.sifang.modules.supply.order.dao.MaterialDeliverDetailDao;
import com.sifang.modules.supply.order.dao.MaterialDeliverOrderMsgDao;
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.order.request.InStockDetailReq;
import com.sifang.modules.supply.order.request.InStockReq;
import com.sifang.modules.supply.setting.dao.CrmSupplyMaterialTypeDao;
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.setting.service.CrmSupplySupplierService;
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.warehouse.constant.InventoryOrderConstants;
import com.sifang.modules.supply.warehouse.constant.MaterialKeepConstants;
import com.sifang.modules.supply.warehouse.dao.CrmSupplyMaterialKeepDao;
import com.sifang.modules.supply.warehouse.dao.SupplyMaterialBatchDao;
import com.sifang.modules.sys.entity.Operator;
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;

/**
 * @author hongzq
 */
@Service
public class InStockOrderService {

    @Autowired
    MaterialDeliverDao deliverDao;
    @Autowired
    MaterialDeliverDetailDao deliverDetailDao;
    @Autowired
    MaterialDeliverOrderMsgDao deliverOrderMsgDao;
    @Autowired
    MaterialStockDao materialStockDao;
    @Autowired
    CrmSupplyWarehouseDao warehouseDao;
    @Autowired
    CheckPendingOrderDao pendingOrderDao;

    @Autowired
    private CrmSupplyMaterialKeepDao materialKeepDao;

    @Autowired
    private SupplyMaterialDao materialDao;

    @Autowired
    private CrmSupplyMaterialTypeDao materialTypeDao;

    @Autowired
    private SupplyMaterialBatchDao materialBatchDao;

    @Autowired
    private TraderAccountDao traderAccountDao;

    @Autowired
    private CustomerEntryDao customerEntryDao;

    @Autowired
    private KingDeePurchaseInWarehouseService inWarehouseService;
    @Autowired
    private CrmSupplySupplierService supplierService;
    @Autowired
    private MiscellaneousService miscellaneousService;

    @Autowired
    private TraderDao traderDao;

    @Transactional(rollbackFor = Exception.class)
    public void giveBack(String id, String reason, Operator operator) {
        CrmSupplyMaterialDeliverOrder order = deliverDao.get(id);
        //待入库、审核未通过可以打回
        if (!DeliverOrderConstants.WAIT_IN_STOCK.equals(order.getStatus())
                && !DeliverOrderConstants.AUDIT_FAIL.equals(order.getStatus())) {
            throw new BusinessException("订单状态发生变化，请稍后再试");
        }
        List<CrmSupplyMaterialDeliverOrderDetail> details = deliverDetailDao.listDetailByOrderId(id);
        for (CrmSupplyMaterialDeliverOrderDetail detail : details) {
            //打回，重新冻结库存
            BigDecimal diff = detail.getApplyAmount().subtract(detail.getOutAmount());
            //实发数量比下单数量少，发货时解除冻结，打回时重新冻结
            if (diff.compareTo(BigDecimal.ZERO) > 0) {
                materialStockDao.reFrozeStock(detail.getMaterialId(), order.getOutWarehouseId(), diff);
            }
        }
        order.setWarehouseFailReason(reason);
        order.setStatus(DeliverOrderConstants.WAREHOUSE_REFUSE);
        deliverDao.save(order);
        String remark = String.format("原因：%s", reason);
        deliverOrderMsgDao.saveOptMsg(order.getId(), DeliverOrderConstants.OPT_DH, remark, operator);
    }


    @Transactional(rollbackFor = Exception.class)
    public void agentFalse(InStockReq req, Operator operator) {
        //orderId=dc2d5019db754fb0a9d12e3a570c1730
        /*CrmSupplyMaterialDeliverOrder order = deliverDao.get(req.getOrderId());
        // 改变订单信息
        order.setStatus(DeliverOrderConstants.STATUS_WAIT_SIGN_IN);
        order.setReceiveInvoice(req.getReceiveInvoice());
        deliverDao.save(order);*/

        SqlBuilder builder=new SqlBuilder();
        builder.line("update crm_supply_material_deliver_order set status='6' where id=?",req.getOrderId());
        Db.update(builder.build(),builder.params());

    }
    @Transactional(rollbackFor = Exception.class)
    public void agentOk(InStockReq req, Operator operator) {
        //orderId=dc2d5019db754fb0a9d12e3a570c1730
        CrmSupplyMaterialDeliverOrder order = deliverDao.get(req.getOrderId());
        //待签收可以入库
        if (StringUtil.isBlank(req.getReceiveInvoice())) {
            throw new BusinessException("签收凭证不能为空!");
        }
        Date now = new Date();
        CrmSupplySupplier supplier = new CrmSupplySupplier();
        if (StringUtil.isNotBlank(order.getSupplyId())) {
            supplier = supplierService.getById(order.getSupplyId());
        }
        // 改变订单信息
        order.setStatus(DeliverOrderConstants.STATUS_TEMPLE_ONE);
        order.setReceiveInvoice(req.getReceiveInvoice());
        deliverDao.save(order);
    }

    @Transactional(rollbackFor = Exception.class)
    public void inStock(InStockReq req, Operator operator) {
        //orderId=dc2d5019db754fb0a9d12e3a570c1730
        CrmSupplyMaterialDeliverOrder order = deliverDao.get(req.getOrderId());
        //待签收可以入库
        if (!DeliverOrderConstants.STATUS_TEMPLE_ONE.equals(order.getStatus())) {
            throw new BusinessException("仅待签收的订单可以操作签收");
        }
        Date now = new Date();
        CrmSupplySupplier supplier = new CrmSupplySupplier();
        if (StringUtil.isNotBlank(order.getSupplyId())) {
            supplier = supplierService.getById(order.getSupplyId());
        }

        //createPendingOrderForInStock(order);
        //入库
        // 查询入库仓库信息
        CrmSupplyWarehouse inWarehouse = warehouseDao.get(order.getInWarehouseId());
        // 数据类型
        String belongingType = InventoryOrderConstants.DISTRIBUTOR.equals(inWarehouse.getType()) ?
                MaterialKeepConstants.BELONGING_TYPE_TRADER : MaterialKeepConstants.BELONGING_TYPE_SUPPLY;
        // 判断是否入库代理商
        boolean flag = InventoryOrderConstants.DISTRIBUTOR.equals(inWarehouse.getType());

        // 改变订单信息
        order.setStatus(DeliverOrderConstants.STATUS_COMPLETED);
        /*if (flag) {
            if (UserConstants.TYPE_ADMIN.equals(operator.getUserType()) || UserConstants.TYPE_PLAT_EMP.equals(operator.getUserType())) {
                if (StringUtil.isBlank(req.getReceiveInvoice())) {
                    throw new BusinessException("平台签收代理商收货单，需传签收凭证");
                }
            }
        }*/
        //order.setReceiveInvoice(req.getReceiveInvoice());
        //order.setReceiveRemark(req.getReceiveRemark());

        order.setReceiveTime(now);

        //String remark = String.format("入库说明：%s", req.getReceiveRemark());
        deliverOrderMsgDao.saveOptMsg(order.getId(), DeliverOrderConstants.OPT_RK, null, operator);



        // 查询待签收物料明细
//        List<CrmSupplyMaterialDeliverOrderDetail> details = deliverDetailDao.listDetailByOrderId(req.getOrderId());
        List<CrmSupplyMaterialDeliverOrderDetail> detailList = new ArrayList<>();
        List<InStockDetailReq> details = req.getDetails();
        BigDecimal total = BigDecimal.ZERO;
        BigDecimal totalInAmount = BigDecimal.ZERO;// 签收总数
//        BigDecimal totalAmount=BigDecimal.ZERO; //dc2d5019db754fb0a9d12e3a570c1730
        for (InStockDetailReq detailReq : details) {
            CrmSupplyMaterialDeliverOrderDetail detail = deliverDetailDao.get(detailReq.getDetailId());
            detail.setInAmount(detailReq.getConfirmAmount());
            deliverDetailDao.save(detail);
            // 查询物料信息
            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            detail.setMaterialCode(material.getCode());
            detail.setUnitCode(material.getUnitCode());
            // 查询仓库物料库存
            MaterialWarehouseStocks warehouseStocks = materialStockDao.findByWarehouse(detail.getMaterialId(), inWarehouse.getId());
            if (warehouseStocks == null) {
                warehouseStocks = new MaterialWarehouseStocks();
                warehouseStocks.setMaterialId(detail.getMaterialId());
                warehouseStocks.setWarehouseId(inWarehouse.getId());
                warehouseStocks.setType(flag ? "3" : "1");
                warehouseStocks.setAscriptionId(inWarehouse.getAscriptionId());
                warehouseStocks.setAscriptionName(inWarehouse.getAscriptionName());
                warehouseStocks.setWarning(BigDecimal.ZERO);
                warehouseStocks.setFrozeInNum(BigDecimal.ZERO);
                warehouseStocks.setFrozeOutNum(BigDecimal.ZERO);
                warehouseStocks.setRealNum(BigDecimal.ZERO);
                warehouseStocks.setTotal(BigDecimal.ZERO);
                warehouseStocks.setCreateTime(now);
                warehouseStocks.setCreateBy(operator.getUserId());
                warehouseStocks.setCostPrice(detail.getPurchasePrice());
            } else {
                BigDecimal averageCost = warehouseStocks.getCostPrice().add(detail.getPurchasePrice());
                warehouseStocks.setCostPrice(averageCost.divide(new BigDecimal("2"), 2, BigDecimal.ROUND_HALF_UP));
            }
            warehouseStocks.setWarning(warehouseStocks.getWarning().add(detail.getInAmount()));
            warehouseStocks.setRealNum(warehouseStocks.getRealNum().add(detail.getInAmount()));
            warehouseStocks.setTotal(warehouseStocks.getTotal().add(detail.getInAmount()));
            warehouseStocks.setNewestKeepTime(now);
            warehouseStocks.setBdSalePrice(detail.getSalesPrice());
            materialStockDao.save(warehouseStocks);
            // 创建入库明细
            String name = materialTypeDao.get(material.getMaterialTypeId()).getName();
            String batchCode= materialBatchDao.getBatchCode(); //批次号
            String keepId = materialKeepDao.createOne(order, belongingType, material,
                    name, MaterialKeepConstants.IN, detail, warehouseStocks.getWarning(), inWarehouse, now, operator.getUserId(),
                    operator.getUserName(), MaterialKeepConstants.ORDER_IN, batchCode);
            // 生成批次明细
            String bizType  = MaterialBatchConstants.TYPE_PROCUREMENT;
            if (flag) {
                bizType = MaterialBatchConstants.TYPE_IN;
            }
            materialBatchDao.createOne(bizType, order.getId(), detail.getId(), order.getNumber(), keepId, material.getId(), belongingType,
                    inWarehouse.getAscriptionId(), inWarehouse.getId(), detail.getInAmount(), now, detail.getPurchasePrice(), detail.getSalesPrice(),batchCode);
            if (flag) {
                total = total.add(detail.getInAmount().multiply(detail.getSalesPrice()));
            }
            detailList.add(detail);
            totalInAmount = totalInAmount.add(detail.getInAmount());

//            if("0".equals(material.getMaterialAttribute()) && detail.getInAmount()!=null && detail.getSalesPrice()!=null){
//                totalAmount=totalAmount.add(detail.getInAmount().multiply(detail.getSalesPrice()));
//            }
        }
        if (totalInAmount.compareTo(BigDecimal.ZERO) == 0) {
            throw new BusinessException("签收总数不能为0");
        }

        order.setTotalInAmount(totalInAmount);

        //同步金蝶
      /*  if("3".equals(order.getType())){
            String id =  inWarehouseService.inWarehouse(order,detailList,supplier,inWarehouse);
            order.setKingDeeId(id);
        }*//* else if("1".equals(order.getType()) || "2".equals(order.getType()) || "4".equals(order.getType())){
            String id =  miscellaneousService.saveOrderToKingDee(order,details,supplier);
            order.setKingDeeId(id);
        }*/
        deliverDao.save(order);

        // 更新电站订单收货时间
        if (DeliverOrderConstants.TYPE_PROJECT.equals(order.getType()) && StringUtil.isNotBlank(order.getRelateNo())) {
            List<Record> list = customerEntryDao.findRelateNo(order.getRelateNo());
            for (Record r : list) {
                if (StringUtil.isBlank(r.getStr("id"))) {
                    continue;
                }
                CustomerEntry entry = customerEntryDao.get(r.getStr("id"));
                if (entry == null) {
                    continue;
                }
                entry.setReceiveTime(now);
                entry.setReceiveBy(operator.getUserId());
                entry.setReceiveName(operator.getUserName());
                customerEntryDao.save(entry);
            }
        }
        CrmTrader trader=traderDao.get(order.getTraderId());
        if(trader.getFirstDeliverTime()==null){
            trader.setFirstDeliverTime(new Date());
            traderDao.save(trader);
        }
    }

    /**
     * 入库单 生成 待审核订单
     */
    @Transactional(rollbackFor = Exception.class)
    public void createPendingOrderForInStock(CrmSupplyMaterialDeliverOrder order) {
        CrmSupplyWarehouse inWarehouse = warehouseDao.get(order.getInWarehouseId());
        CrmSupplyCheckPendingOrder pendingOrder = new CrmSupplyCheckPendingOrder();
        pendingOrder.setOrderId(order.getId());
        pendingOrder.setCode(order.getNumber());
        pendingOrder.setWarehouseId(order.getInWarehouseId());
        pendingOrder.setWarehouseName(inWarehouse.getName());
        pendingOrder.setOrderType(PendingOrderConstants.RK);
        pendingOrder.setExpressNo(order.getExpressNo());
        pendingOrder.setDeliverMethodId(order.getDeliverMethodId());
        pendingOrder.setDeliverMethodName(order.getDeliverMethodName());
        pendingOrder.setForwardingUnit(order.getDeliverName());
        pendingOrder.setReceivingUnit(inWarehouse.getAscriptionName());
        pendingOrder.setDeliverTime(order.getDeliverTime());
        pendingOrder.setPlaceOrderTime(order.getPlaceTime());
        pendingOrder.setRemarks(order.getRemarks());
        pendingOrder.setDeliverRemarks(order.getDeliverRemark());
        pendingOrder.setStatus(PendingOrderConstants.WAIT_AUDIT);
        pendingOrder.setCreateTime(new Date());
        pendingOrderDao.save(pendingOrder);
    }

}
