package cn.iocoder.yudao.module.order.service.orderWarehouseIn;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.service.IService;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.module.customer.vo.zhongPao.ZhongPaoBestVO;
import cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderItem.OrderItemDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderWarehouseIn.OrderWarehouseInDO;
import cn.iocoder.yudao.module.order.vo.order.OrderWarehouseInCommonAttrVO;
import cn.iocoder.yudao.module.order.vo.order.OrderWarehouseInWithAttrVO;
import cn.iocoder.yudao.module.order.vo.order.WarehouseInInfoVO;
import cn.iocoder.yudao.module.order.vo.orderItem.OrderItemBackVO;
import cn.iocoder.yudao.module.order.vo.orderWarehouseIn.*;

import javax.validation.Valid;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * 入仓货物详情 Service 接口
 *
 * @author yanghao
 */
public interface OrderWarehouseInService extends IService<OrderWarehouseInDO> {

    /**
     * 创建入仓货物详情
     *
     * @param createReqVO 创建信息
     * @return 编号
     */
    boolean createOrderWarehouseIn(@Valid OrderWarehouseInCreateReqVO createReqVO);

    // /**
    //  * 更新入仓货物详情
    //  *
    //  * @param updateReqVO 更新信息
    //  * @return 是否更新成功
    //  */
    // boolean updateOrderWarehouseIn(OrderWarehouseInUpdateReqVO updateReqVO);

    /**
     * 删除入仓货物详情
     *
     * @param orderWarehouseInId 入仓id
     * @param packagingFlag
     * @return 是否删除成功
     */
    boolean deleteOrderWarehouseIn(Long orderWarehouseInId, boolean packagingFlag);

    /**
     * 完成入仓
     *
     * @param finishReqVO 入仓信息
     * @return 入仓是否包含异常
     */
    boolean finishWarehouseIn(OrderWarehouseInFinishReqVO finishReqVO);

    /**
     * 在切换运输方式之后重新完成入仓
     * @param orderId
     * @return
     */
    boolean finishWarehouseInWhenChangeTransportType(Long orderId);

    /**
     * 订单储位接口
     *
     * @param orderLocationReqVO
     */
    void orderLocation(OrderWarehouseInOrderLocationReqVO orderLocationReqVO);

    /**
     * 入仓货物退仓
     *
     * @param orderItemReqVo 入仓货物退仓请求
     */
    void deleteWarehouseInOrderItem(OrderWarehouseInRollbackOrderItemReqVO orderItemReqVo);

    /**
     * 获得入仓货物详情
     *
     * @param orderId 订单id
     * @return 入仓货物详情
     */
    List<OrderWarehouseInBackVO> getOrderWarehouseInList(Long orderId);

    /**
     * 根据订单和品名id查询已删除的入仓纪录
     *
     * @param orderId 订单id
     * @param orderItemId 品名id
     * @return
     */
    OrderWarehouseInBackVO getOrderWarehouseInListDeleted(Long orderId, Long orderItemId);

    OrderWarehouseInBackVO getOrderWarehouseInBackVO(Long orderId, Long orderItemId);

    /**
     * 获得入仓货物详情列表
     *
     * @param ids 编号
     * @return 入仓货物详情列表
     */
    List<OrderWarehouseInDO> getOrderWarehouseInList(Collection<Long> ids);

    /**
     * 获得入仓货物详情分页
     *
     * @param page  分页查询
     * @param query 查询
     * @return 入仓货物详情分页
     */
    PageResult<OrderWarehouseInDO> getOrderWarehouseInPage(OrderWarehouseInQueryVO query, PageVO page);

    /**
     * 获得入仓货物详情列表, 用于 Excel 导出
     *
     * @param query 查询
     * @return 入仓货物详情列表
     */
    List<OrderWarehouseInDO> getOrderWarehouseInList(OrderWarehouseInQueryVO query);


    /**
     * 根据商品id找到此订单最早的1条入仓纪录。即使有多个
     *
     * @param orderId 订单号
     * @param prodId  商品id
     * @return
     */
    OrderWarehouseInDO getFirstOneOrderWarehouseInByProdId(Long orderId, Long prodId);

    /**
     * 根据商品id找到此订单项最早的1条入仓纪录
     *
     * @param orderItemId 订单项ID
     * @return
     */
    OrderWarehouseInDO getMinOrderWarehouseInByOrderItemId(Long orderItemId);


    /**
     * 入仓修改申请
     *
     * @param updateReqVO
     * @return
     */
    String updateOrUpdateApply(@Valid OrderWarehouseInUpdateApplyReqVO updateReqVO);


    /**
     * 入仓修改回调
     *
     * @param formId 表单业务ID
     * @param result 1 处理中  2 通过 3 不通过 4 已取消
     */
    void updateApplyCallback(String formId, Integer result);


    /**
     * 更新订单和订单项信息的入仓信息.
     * 目前使用的地方：1、入仓修改callback中调用  2、新增商品异常处理改变ProdId后调用
     *
     * @param orderId         订单id
     * @param prodIdOld       原产品id
     * @param prodIdNew       新产品id
     * @param orderItemDOList 订单项
     * @param zhongPaoBest    重泡货配置对象，可为null. 为null时后台自己会查
     */
    void updateOrderAndOrderItemWarehouseIn(Long orderId, Long prodIdOld, Long prodIdNew, List<OrderItemDO> orderItemDOList, ZhongPaoBestVO zhongPaoBest);


    /**
     * 退仓申请
     *
     * @param orderWarehouseInRollbackApplyReqVO 退仓申请 vo
     * @param adminId                            提出申请人
     * @param isFromUserClient
     */
    void rollbackApply(OrderWarehouseInRollbackApplyReqVO orderWarehouseInRollbackApplyReqVO, Long adminId, Boolean isFromUserClient);

    /**
     * 退仓回调
     *
     * @param approvalId
     * @param result
     */
    void rollbackApplyCallback(String approvalId, Integer result);


    /**
     * 拨正入仓箱数
     *
     * @param orderId
     * @param orderItemId
     */
    void changeOrderWarehouseInCartonsNumCorrect(Long orderId, Long orderItemId);


    /**
     * 发送入仓短信
     *
     * @param orderDO      订单信息
     * @param isAppend     是否追加
     * @param appendInTime
     */
    void warehouseInSendSms(OrderDO orderDO, boolean isAppend, Date appendInTime);


    /**
     * 完成打包
     *
     * @param finishPackageReqVO 打包对象
     * @return
     */
    void finishPacked(OrderItemFinishPackedReqVO finishPackageReqVO);


    /**
     * 不需要打包
     * @param orderItemId
     */
    void noNeedToPack(Long orderItemId);


    /**
     * 完成备货请求
     *
     * @param orderItemFinishStockedReqVO
     */
    void finishStocked(OrderItemFinishStockedReqVO orderItemFinishStockedReqVO);


    /**
     * 获取打包后的订单首次完成入仓的统计数据
     * 
     * @param orderId
     * @return
     */
    WarehouseInInfoVO getStatisticsFirstFinishedAfterPacked(Long orderId);



    List<OrderWarehouseInWithAttrVO> getOrderWarehouseInCommonAttrList(Long orderId, Long excludeOrderWarehouseInId);



    /**
     * 有订单，但客户类型不正确。故这里通过客户订单来修改客户状态
     */
    void changeCustomerStatusByOrder();

    List<OrderWarehouseInBackItemVO> getOrderWarehouseInListOrderByInTime(Long orderId);


    /**
     * 处理渠道包装超重异常
     *
     * @param orderDO 订单对象
     */
    void processChannelPackagingOverWeightException(OrderDO orderDO);

    void dealMergeOrderWarehouseInAndLocation(List<OrderWarehouseInDO> orderWarehouseInList);


    /**
     * 将退仓的入仓数据设置到品名上。
     *
     * @param orderItemBackVO 品名
     * @param orderWarehouseInDODeletedList 退仓的入仓数据
     * @return
     */
    WarehouseInInfoVO orderItemSetWarehouseInInfoVO(OrderItemBackVO orderItemBackVO, List<OrderWarehouseInDO> orderWarehouseInDODeletedList);
}
