package com.ruoyi.asset.service;

import java.util.List;
import com.ruoyi.asset.domain.AmsAsset;
import com.ruoyi.asset.domain.AmsReceiveOrder;

/**
 * 资产领用管理服务接口
 * 
 * 定义了资产领用单的生命周期控制接口，包含：
 * 1. 草稿创建、编辑、逻辑删除；
 * 2. 提交待确认（冻结仓位与防重检验）；
 * 3. 审批确认（串行化死锁预防加锁、资产状态扭转、履历生成）；
 * 4. 审批驳回（单据回退、解冻资产可用状态）。
 *
 * @author Yangk
 */
public interface IAmsReceiveOrderService
{
    /**
     * 根据主键查询资产领用单详情，包含联查出的子表明细列表。
     */
    public AmsReceiveOrder selectAmsReceiveOrderByOrderId(Long orderId);

    /**
     * 根据条件检索领用单列表，用于主表分页和检索。
     */
    public List<AmsReceiveOrder> selectAmsReceiveOrderList(AmsReceiveOrder amsReceiveOrder);

    /**
     * 分页查询当前可加入该领用单的在库资产。
     * 业务意图：支持新增或编辑时，检索尚未被其他活跃领用单（DRAFT / PENDING_CONFIRM）占用的在库资产。
     */
    public List<AmsAsset> selectAvailableReceiveAssetList(AmsAsset amsAsset, Long currentOrderId);

    /**
     * 创建资产领用单草稿。
     * 业务意图：校验申请人与申请部门的一致性，自动生成LY开头的编码，将状态置为草稿 DRAFT，回填领用前仓位快照，级联保存子表。
     */
    public int insertAmsReceiveOrder(AmsReceiveOrder amsReceiveOrder, Long applicantId,
            String applicantName, Long applyDeptId);

    /**
     * 修改资产领用草稿单。
     * 业务意图：仅限草稿状态，对资产重新校验后级联更新明细项（采用“先物理删除旧明细后新增”的Ruoyi典型策略）。
     */
    public int updateAmsReceiveOrder(AmsReceiveOrder amsReceiveOrder);

    /**
     * 提交资产领用单。
     * 业务意图：将状态置为 PENDING_CONFIRM (待确认)，期间会重新以排他锁模式（FOR UPDATE）锁定相关资产，并强制比对仓位快照是否已被篡改（防并发）。
     */
    public int submitReceive(Long orderId, String operateLoginName);

    /**
     * 确认资产领用。
     * 业务意图：将单据状态置为 COMPLETED (已完成)。
     * 在加锁保护下，逐一调用底层 `assetStatusTransitionService` 将资产状态转移为在用，清空当前仓位、更新使用归属，并生成资产履历。
     */
    public int confirmReceive(Long orderId, Long operateUserId, String operateUserName, String operateLoginName);

    /**
     * 驳回资产领用申请。
     * 业务意图：记录驳回原因并将状态重置为 REJECTED (已驳回)，此时资产解锁，允许被其他单据领用或调拨。
     */
    public int rejectReceive(Long orderId, String rejectReason, String operateLoginName);

    /**
     * 批量逻辑删除领用单（仅限草稿状态）。
     */
    public int deleteAmsReceiveOrderByOrderIds(String orderIds);

    /**
     * 逻辑删除指定领用单（仅限草稿状态）。
     */
    public int deleteAmsReceiveOrderByOrderId(Long orderId);
}
