feat(asset): 添加资产生命周期履历功能
- 新增 AmsAssetLifecycleLog 实体类用于记录资产履历信息 - 新增 AmsAssetLifecycleLogMapper 接口和对应 XML 映射文件 - 在 AmsAssetController 中注入 IAssetLifecycleService 并传递履历数据到前端 - 重构 RFID 标签解绑逻辑,将履历记录委托给统一的资产生命周期服务 - 新增 AssetLifecycleBusinessType 常量类定义资产履历业务类型 - 实现 IAssetLifecycleService 接口提供履历查询和记录功能 - 添加资产生命周期履历服务的单元测试 - 移除原来在 RFID 标签映射器中的履历插入方法和相关常量main
parent
2d2a5f1c66
commit
bf8218791d
@ -0,0 +1,36 @@
|
||||
package com.ruoyi.asset.constant;
|
||||
|
||||
/**
|
||||
* 资产履历业务类型
|
||||
*
|
||||
* @author Yangk
|
||||
*/
|
||||
public final class AssetLifecycleBusinessType
|
||||
{
|
||||
/** 资产入库 */
|
||||
public static final String INBOUND = "INBOUND";
|
||||
/** 资产领用 */
|
||||
public static final String RECEIVE = "RECEIVE";
|
||||
/** 资产退库 */
|
||||
public static final String RETURN = "RETURN";
|
||||
/** 资产借用 */
|
||||
public static final String BORROW = "BORROW";
|
||||
/** 借用归还 */
|
||||
public static final String BORROW_RETURN = "BORROW_RETURN";
|
||||
/** 资产调拨 */
|
||||
public static final String TRANSFER = "TRANSFER";
|
||||
/** 资产维修 */
|
||||
public static final String REPAIR = "REPAIR";
|
||||
/** 资产处置/报废 */
|
||||
public static final String DISPOSAL = "DISPOSAL";
|
||||
/** 资产盘点 */
|
||||
public static final String INVENTORY = "INVENTORY";
|
||||
/** RFID标签绑定 */
|
||||
public static final String RFID_BIND = "RFID_BIND";
|
||||
/** RFID标签解绑 */
|
||||
public static final String RFID_UNBIND = "RFID_UNBIND";
|
||||
|
||||
private AssetLifecycleBusinessType()
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,419 @@
|
||||
package com.ruoyi.asset.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 资产履历对象 ams_asset_lifecycle_log
|
||||
*
|
||||
* @author Yangk
|
||||
*/
|
||||
public class AmsAssetLifecycleLog extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 履历ID */
|
||||
private Long logId;
|
||||
|
||||
/** 资产ID */
|
||||
private Long assetId;
|
||||
|
||||
/** 资产编码快照 */
|
||||
private String assetCode;
|
||||
|
||||
/** 资产名称快照 */
|
||||
private String assetName;
|
||||
|
||||
/** 业务类型 */
|
||||
private String businessType;
|
||||
|
||||
/** 来源单据ID */
|
||||
private Long sourceOrderId;
|
||||
|
||||
/** 来源单据号 */
|
||||
private String sourceOrderNo;
|
||||
|
||||
/** 来源明细ID */
|
||||
private Long sourceItemId;
|
||||
|
||||
/** 变更前资产状态 */
|
||||
private String beforeStatus;
|
||||
|
||||
/** 变更后资产状态 */
|
||||
private String afterStatus;
|
||||
|
||||
/** 变更前仓库ID */
|
||||
private Long beforeWarehouseId;
|
||||
|
||||
/** 变更前仓库名称 */
|
||||
private String beforeWarehouseName;
|
||||
|
||||
/** 变更后仓库ID */
|
||||
private Long afterWarehouseId;
|
||||
|
||||
/** 变更后仓库名称 */
|
||||
private String afterWarehouseName;
|
||||
|
||||
/** 变更前位置ID */
|
||||
private Long beforeLocationId;
|
||||
|
||||
/** 变更前位置名称 */
|
||||
private String beforeLocationName;
|
||||
|
||||
/** 变更后位置ID */
|
||||
private Long afterLocationId;
|
||||
|
||||
/** 变更后位置名称 */
|
||||
private String afterLocationName;
|
||||
|
||||
/** 变更前使用人ID */
|
||||
private Long beforeUserId;
|
||||
|
||||
/** 变更前使用人名称 */
|
||||
private String beforeUserName;
|
||||
|
||||
/** 变更后使用人ID */
|
||||
private Long afterUserId;
|
||||
|
||||
/** 变更后使用人名称 */
|
||||
private String afterUserName;
|
||||
|
||||
/** 变更前使用部门ID */
|
||||
private Long beforeDeptId;
|
||||
|
||||
/** 变更前使用部门名称 */
|
||||
private String beforeDeptName;
|
||||
|
||||
/** 变更后使用部门ID */
|
||||
private Long afterDeptId;
|
||||
|
||||
/** 变更后使用部门名称 */
|
||||
private String afterDeptName;
|
||||
|
||||
/** 操作用户ID */
|
||||
private Long operateUserId;
|
||||
|
||||
/** 操作用户名称 */
|
||||
private String operateUserName;
|
||||
|
||||
/** 操作时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date operateTime;
|
||||
|
||||
/** 变更摘要 */
|
||||
private String changeSummary;
|
||||
|
||||
/** 删除标志 */
|
||||
private String delFlag;
|
||||
|
||||
public Long getLogId()
|
||||
{
|
||||
return logId;
|
||||
}
|
||||
|
||||
public void setLogId(Long logId)
|
||||
{
|
||||
this.logId = logId;
|
||||
}
|
||||
|
||||
public Long getAssetId()
|
||||
{
|
||||
return assetId;
|
||||
}
|
||||
|
||||
public void setAssetId(Long assetId)
|
||||
{
|
||||
this.assetId = assetId;
|
||||
}
|
||||
|
||||
public String getAssetCode()
|
||||
{
|
||||
return assetCode;
|
||||
}
|
||||
|
||||
public void setAssetCode(String assetCode)
|
||||
{
|
||||
this.assetCode = assetCode;
|
||||
}
|
||||
|
||||
public String getAssetName()
|
||||
{
|
||||
return assetName;
|
||||
}
|
||||
|
||||
public void setAssetName(String assetName)
|
||||
{
|
||||
this.assetName = assetName;
|
||||
}
|
||||
|
||||
public String getBusinessType()
|
||||
{
|
||||
return businessType;
|
||||
}
|
||||
|
||||
public void setBusinessType(String businessType)
|
||||
{
|
||||
this.businessType = businessType;
|
||||
}
|
||||
|
||||
public Long getSourceOrderId()
|
||||
{
|
||||
return sourceOrderId;
|
||||
}
|
||||
|
||||
public void setSourceOrderId(Long sourceOrderId)
|
||||
{
|
||||
this.sourceOrderId = sourceOrderId;
|
||||
}
|
||||
|
||||
public String getSourceOrderNo()
|
||||
{
|
||||
return sourceOrderNo;
|
||||
}
|
||||
|
||||
public void setSourceOrderNo(String sourceOrderNo)
|
||||
{
|
||||
this.sourceOrderNo = sourceOrderNo;
|
||||
}
|
||||
|
||||
public Long getSourceItemId()
|
||||
{
|
||||
return sourceItemId;
|
||||
}
|
||||
|
||||
public void setSourceItemId(Long sourceItemId)
|
||||
{
|
||||
this.sourceItemId = sourceItemId;
|
||||
}
|
||||
|
||||
public String getBeforeStatus()
|
||||
{
|
||||
return beforeStatus;
|
||||
}
|
||||
|
||||
public void setBeforeStatus(String beforeStatus)
|
||||
{
|
||||
this.beforeStatus = beforeStatus;
|
||||
}
|
||||
|
||||
public String getAfterStatus()
|
||||
{
|
||||
return afterStatus;
|
||||
}
|
||||
|
||||
public void setAfterStatus(String afterStatus)
|
||||
{
|
||||
this.afterStatus = afterStatus;
|
||||
}
|
||||
|
||||
public Long getBeforeWarehouseId()
|
||||
{
|
||||
return beforeWarehouseId;
|
||||
}
|
||||
|
||||
public void setBeforeWarehouseId(Long beforeWarehouseId)
|
||||
{
|
||||
this.beforeWarehouseId = beforeWarehouseId;
|
||||
}
|
||||
|
||||
public String getBeforeWarehouseName()
|
||||
{
|
||||
return beforeWarehouseName;
|
||||
}
|
||||
|
||||
public void setBeforeWarehouseName(String beforeWarehouseName)
|
||||
{
|
||||
this.beforeWarehouseName = beforeWarehouseName;
|
||||
}
|
||||
|
||||
public Long getAfterWarehouseId()
|
||||
{
|
||||
return afterWarehouseId;
|
||||
}
|
||||
|
||||
public void setAfterWarehouseId(Long afterWarehouseId)
|
||||
{
|
||||
this.afterWarehouseId = afterWarehouseId;
|
||||
}
|
||||
|
||||
public String getAfterWarehouseName()
|
||||
{
|
||||
return afterWarehouseName;
|
||||
}
|
||||
|
||||
public void setAfterWarehouseName(String afterWarehouseName)
|
||||
{
|
||||
this.afterWarehouseName = afterWarehouseName;
|
||||
}
|
||||
|
||||
public Long getBeforeLocationId()
|
||||
{
|
||||
return beforeLocationId;
|
||||
}
|
||||
|
||||
public void setBeforeLocationId(Long beforeLocationId)
|
||||
{
|
||||
this.beforeLocationId = beforeLocationId;
|
||||
}
|
||||
|
||||
public String getBeforeLocationName()
|
||||
{
|
||||
return beforeLocationName;
|
||||
}
|
||||
|
||||
public void setBeforeLocationName(String beforeLocationName)
|
||||
{
|
||||
this.beforeLocationName = beforeLocationName;
|
||||
}
|
||||
|
||||
public Long getAfterLocationId()
|
||||
{
|
||||
return afterLocationId;
|
||||
}
|
||||
|
||||
public void setAfterLocationId(Long afterLocationId)
|
||||
{
|
||||
this.afterLocationId = afterLocationId;
|
||||
}
|
||||
|
||||
public String getAfterLocationName()
|
||||
{
|
||||
return afterLocationName;
|
||||
}
|
||||
|
||||
public void setAfterLocationName(String afterLocationName)
|
||||
{
|
||||
this.afterLocationName = afterLocationName;
|
||||
}
|
||||
|
||||
public Long getBeforeUserId()
|
||||
{
|
||||
return beforeUserId;
|
||||
}
|
||||
|
||||
public void setBeforeUserId(Long beforeUserId)
|
||||
{
|
||||
this.beforeUserId = beforeUserId;
|
||||
}
|
||||
|
||||
public String getBeforeUserName()
|
||||
{
|
||||
return beforeUserName;
|
||||
}
|
||||
|
||||
public void setBeforeUserName(String beforeUserName)
|
||||
{
|
||||
this.beforeUserName = beforeUserName;
|
||||
}
|
||||
|
||||
public Long getAfterUserId()
|
||||
{
|
||||
return afterUserId;
|
||||
}
|
||||
|
||||
public void setAfterUserId(Long afterUserId)
|
||||
{
|
||||
this.afterUserId = afterUserId;
|
||||
}
|
||||
|
||||
public String getAfterUserName()
|
||||
{
|
||||
return afterUserName;
|
||||
}
|
||||
|
||||
public void setAfterUserName(String afterUserName)
|
||||
{
|
||||
this.afterUserName = afterUserName;
|
||||
}
|
||||
|
||||
public Long getBeforeDeptId()
|
||||
{
|
||||
return beforeDeptId;
|
||||
}
|
||||
|
||||
public void setBeforeDeptId(Long beforeDeptId)
|
||||
{
|
||||
this.beforeDeptId = beforeDeptId;
|
||||
}
|
||||
|
||||
public String getBeforeDeptName()
|
||||
{
|
||||
return beforeDeptName;
|
||||
}
|
||||
|
||||
public void setBeforeDeptName(String beforeDeptName)
|
||||
{
|
||||
this.beforeDeptName = beforeDeptName;
|
||||
}
|
||||
|
||||
public Long getAfterDeptId()
|
||||
{
|
||||
return afterDeptId;
|
||||
}
|
||||
|
||||
public void setAfterDeptId(Long afterDeptId)
|
||||
{
|
||||
this.afterDeptId = afterDeptId;
|
||||
}
|
||||
|
||||
public String getAfterDeptName()
|
||||
{
|
||||
return afterDeptName;
|
||||
}
|
||||
|
||||
public void setAfterDeptName(String afterDeptName)
|
||||
{
|
||||
this.afterDeptName = afterDeptName;
|
||||
}
|
||||
|
||||
public Long getOperateUserId()
|
||||
{
|
||||
return operateUserId;
|
||||
}
|
||||
|
||||
public void setOperateUserId(Long operateUserId)
|
||||
{
|
||||
this.operateUserId = operateUserId;
|
||||
}
|
||||
|
||||
public String getOperateUserName()
|
||||
{
|
||||
return operateUserName;
|
||||
}
|
||||
|
||||
public void setOperateUserName(String operateUserName)
|
||||
{
|
||||
this.operateUserName = operateUserName;
|
||||
}
|
||||
|
||||
public Date getOperateTime()
|
||||
{
|
||||
return operateTime;
|
||||
}
|
||||
|
||||
public void setOperateTime(Date operateTime)
|
||||
{
|
||||
this.operateTime = operateTime;
|
||||
}
|
||||
|
||||
public String getChangeSummary()
|
||||
{
|
||||
return changeSummary;
|
||||
}
|
||||
|
||||
public void setChangeSummary(String changeSummary)
|
||||
{
|
||||
this.changeSummary = changeSummary;
|
||||
}
|
||||
|
||||
public String getDelFlag()
|
||||
{
|
||||
return delFlag;
|
||||
}
|
||||
|
||||
public void setDelFlag(String delFlag)
|
||||
{
|
||||
this.delFlag = delFlag;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.ruoyi.asset.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.asset.domain.AmsAssetLifecycleLog;
|
||||
|
||||
/**
|
||||
* 资产履历Mapper接口
|
||||
*
|
||||
* @author Yangk
|
||||
*/
|
||||
public interface AmsAssetLifecycleLogMapper
|
||||
{
|
||||
/**
|
||||
* 按资产ID查询履历
|
||||
*
|
||||
* @param assetId 资产ID
|
||||
* @return 资产履历集合
|
||||
*/
|
||||
public List<AmsAssetLifecycleLog> selectAmsAssetLifecycleLogByAssetId(Long assetId);
|
||||
|
||||
/**
|
||||
* 新增资产履历
|
||||
*
|
||||
* @param lifecycleLog 资产履历
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertAmsAssetLifecycleLog(AmsAssetLifecycleLog lifecycleLog);
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.ruoyi.asset.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.asset.domain.AmsAsset;
|
||||
import com.ruoyi.asset.domain.AmsAssetLifecycleLog;
|
||||
|
||||
/**
|
||||
* 资产履历公共服务
|
||||
*
|
||||
* @author Yangk
|
||||
*/
|
||||
public interface IAssetLifecycleService
|
||||
{
|
||||
/**
|
||||
* 按资产ID查询履历
|
||||
*
|
||||
* @param assetId 资产ID
|
||||
* @return 资产履历集合
|
||||
*/
|
||||
public List<AmsAssetLifecycleLog> selectByAssetId(Long assetId);
|
||||
|
||||
/**
|
||||
* 记录资产业务变化履历
|
||||
*
|
||||
* @param beforeAsset 变更前资产快照
|
||||
* @param afterAsset 变更后资产快照
|
||||
* @param lifecycleLog 业务来源、操作人和变更摘要
|
||||
* @return 结果
|
||||
*/
|
||||
public int recordLifecycle(AmsAsset beforeAsset, AmsAsset afterAsset, AmsAssetLifecycleLog lifecycleLog);
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.asset.mapper.AmsAssetLifecycleLogMapper">
|
||||
|
||||
<resultMap type="AmsAssetLifecycleLog" id="AmsAssetLifecycleLogResult">
|
||||
<result property="logId" column="log_id"/>
|
||||
<result property="assetId" column="asset_id"/>
|
||||
<result property="assetCode" column="asset_code"/>
|
||||
<result property="assetName" column="asset_name"/>
|
||||
<result property="businessType" column="business_type"/>
|
||||
<result property="sourceOrderId" column="source_order_id"/>
|
||||
<result property="sourceOrderNo" column="source_order_no"/>
|
||||
<result property="sourceItemId" column="source_item_id"/>
|
||||
<result property="beforeStatus" column="before_status"/>
|
||||
<result property="afterStatus" column="after_status"/>
|
||||
<result property="beforeWarehouseId" column="before_warehouse_id"/>
|
||||
<result property="beforeWarehouseName" column="before_warehouse_name"/>
|
||||
<result property="afterWarehouseId" column="after_warehouse_id"/>
|
||||
<result property="afterWarehouseName" column="after_warehouse_name"/>
|
||||
<result property="beforeLocationId" column="before_location_id"/>
|
||||
<result property="beforeLocationName" column="before_location_name"/>
|
||||
<result property="afterLocationId" column="after_location_id"/>
|
||||
<result property="afterLocationName" column="after_location_name"/>
|
||||
<result property="beforeUserId" column="before_user_id"/>
|
||||
<result property="beforeUserName" column="before_user_name"/>
|
||||
<result property="afterUserId" column="after_user_id"/>
|
||||
<result property="afterUserName" column="after_user_name"/>
|
||||
<result property="beforeDeptId" column="before_dept_id"/>
|
||||
<result property="beforeDeptName" column="before_dept_name"/>
|
||||
<result property="afterDeptId" column="after_dept_id"/>
|
||||
<result property="afterDeptName" column="after_dept_name"/>
|
||||
<result property="operateUserId" column="operate_user_id"/>
|
||||
<result property="operateUserName" column="operate_user_name"/>
|
||||
<result property="operateTime" column="operate_time"/>
|
||||
<result property="changeSummary" column="change_summary"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectAmsAssetLifecycleLogVo">
|
||||
select log_id, asset_id, asset_code, asset_name, business_type,
|
||||
source_order_id, source_order_no, source_item_id,
|
||||
before_status, after_status,
|
||||
before_warehouse_id, before_warehouse_name, after_warehouse_id, after_warehouse_name,
|
||||
before_location_id, before_location_name, after_location_id, after_location_name,
|
||||
before_user_id, before_user_name, after_user_id, after_user_name,
|
||||
before_dept_id, before_dept_name, after_dept_id, after_dept_name,
|
||||
operate_user_id, operate_user_name, operate_time, change_summary,
|
||||
create_by, create_time, update_by, update_time, remark, del_flag
|
||||
from ams_asset_lifecycle_log
|
||||
</sql>
|
||||
|
||||
<select id="selectAmsAssetLifecycleLogByAssetId" parameterType="Long" resultMap="AmsAssetLifecycleLogResult">
|
||||
<include refid="selectAmsAssetLifecycleLogVo"/>
|
||||
where asset_id = #{assetId} and del_flag = '0'
|
||||
order by operate_time desc, log_id desc
|
||||
</select>
|
||||
|
||||
<insert id="insertAmsAssetLifecycleLog" parameterType="AmsAssetLifecycleLog"
|
||||
useGeneratedKeys="true" keyProperty="logId">
|
||||
insert into ams_asset_lifecycle_log
|
||||
(
|
||||
asset_id, asset_code, asset_name, business_type,
|
||||
source_order_id, source_order_no, source_item_id,
|
||||
before_status, after_status,
|
||||
before_warehouse_id, before_warehouse_name, after_warehouse_id, after_warehouse_name,
|
||||
before_location_id, before_location_name, after_location_id, after_location_name,
|
||||
before_user_id, before_user_name, after_user_id, after_user_name,
|
||||
before_dept_id, before_dept_name, after_dept_id, after_dept_name,
|
||||
operate_user_id, operate_user_name, operate_time, change_summary,
|
||||
create_by, create_time, remark, del_flag
|
||||
)
|
||||
values
|
||||
(
|
||||
#{assetId}, #{assetCode}, #{assetName}, #{businessType},
|
||||
#{sourceOrderId}, #{sourceOrderNo}, #{sourceItemId},
|
||||
#{beforeStatus}, #{afterStatus},
|
||||
#{beforeWarehouseId}, #{beforeWarehouseName}, #{afterWarehouseId}, #{afterWarehouseName},
|
||||
#{beforeLocationId}, #{beforeLocationName}, #{afterLocationId}, #{afterLocationName},
|
||||
#{beforeUserId}, #{beforeUserName}, #{afterUserId}, #{afterUserName},
|
||||
#{beforeDeptId}, #{beforeDeptName}, #{afterDeptId}, #{afterDeptName},
|
||||
#{operateUserId}, #{operateUserName}, #{operateTime}, #{changeSummary},
|
||||
#{createBy}, #{createTime}, #{remark}, #{delFlag}
|
||||
)
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
@ -0,0 +1,103 @@
|
||||
package com.ruoyi.asset.service.impl;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.ruoyi.asset.domain.AmsWarehouse;
|
||||
import com.ruoyi.asset.mapper.AmsWarehouseMapper;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AmsWarehouseServiceImplTest
|
||||
{
|
||||
@Mock
|
||||
private AmsWarehouseMapper amsWarehouseMapper;
|
||||
|
||||
@InjectMocks
|
||||
private AmsWarehouseServiceImpl service;
|
||||
|
||||
@Test
|
||||
void insertAmsWarehouseShouldSetAssetDefaults()
|
||||
{
|
||||
AmsWarehouse warehouse = new AmsWarehouse();
|
||||
warehouse.setWarehouseCode("WH001");
|
||||
warehouse.setWarehouseName("主仓");
|
||||
when(amsWarehouseMapper.insertAmsWarehouse(any(AmsWarehouse.class))).thenReturn(1);
|
||||
|
||||
int rows = service.insertAmsWarehouse(warehouse);
|
||||
|
||||
ArgumentCaptor<AmsWarehouse> captor = ArgumentCaptor.forClass(AmsWarehouse.class);
|
||||
verify(amsWarehouseMapper).insertAmsWarehouse(captor.capture());
|
||||
assertEquals(1, rows);
|
||||
assertEquals("Y", captor.getValue().getEnabled());
|
||||
assertEquals("0", captor.getValue().getDelFlag());
|
||||
assertNotNull(captor.getValue().getCreateTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteAmsWarehouseByWarehouseIdsShouldRejectReferencedWarehouse()
|
||||
{
|
||||
AmsWarehouse warehouse = new AmsWarehouse();
|
||||
warehouse.setWarehouseId(10L);
|
||||
warehouse.setWarehouseName("主仓");
|
||||
when(amsWarehouseMapper.selectAmsWarehouseByWarehouseId(10L)).thenReturn(warehouse);
|
||||
when(amsWarehouseMapper.countWarehouseReferences(10L)).thenReturn(1);
|
||||
|
||||
ServiceException exception = assertThrows(ServiceException.class,
|
||||
() -> service.deleteAmsWarehouseByWarehouseIds("10"));
|
||||
|
||||
assertTrue(exception.getMessage().contains("主仓"));
|
||||
assertTrue(exception.getMessage().contains("不允许删除"));
|
||||
verify(amsWarehouseMapper, never()).deleteAmsWarehouseByWarehouseIds(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteAmsWarehouseByWarehouseIdShouldRejectReferencedWarehouse()
|
||||
{
|
||||
AmsWarehouse warehouse = new AmsWarehouse();
|
||||
warehouse.setWarehouseId(10L);
|
||||
warehouse.setWarehouseName("主仓");
|
||||
when(amsWarehouseMapper.selectAmsWarehouseByWarehouseId(10L)).thenReturn(warehouse);
|
||||
when(amsWarehouseMapper.countWarehouseReferences(10L)).thenReturn(1);
|
||||
|
||||
ServiceException exception = assertThrows(ServiceException.class,
|
||||
() -> service.deleteAmsWarehouseByWarehouseId(10L));
|
||||
|
||||
assertTrue(exception.getMessage().contains("主仓"));
|
||||
assertTrue(exception.getMessage().contains("不允许删除"));
|
||||
verify(amsWarehouseMapper, never()).deleteAmsWarehouseByWarehouseId(10L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkWarehouseCodeUniqueShouldIgnoreCurrentWarehouse()
|
||||
{
|
||||
AmsWarehouse existing = new AmsWarehouse();
|
||||
existing.setWarehouseId(10L);
|
||||
existing.setWarehouseCode("WH001");
|
||||
when(amsWarehouseMapper.checkWarehouseCodeUnique("WH001")).thenReturn(existing);
|
||||
|
||||
AmsWarehouse current = new AmsWarehouse();
|
||||
current.setWarehouseId(10L);
|
||||
current.setWarehouseCode("WH001");
|
||||
|
||||
AmsWarehouse other = new AmsWarehouse();
|
||||
other.setWarehouseId(11L);
|
||||
other.setWarehouseCode("WH001");
|
||||
|
||||
assertTrue(service.checkWarehouseCodeUnique(current));
|
||||
assertFalse(service.checkWarehouseCodeUnique(other));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,125 @@
|
||||
package com.ruoyi.asset.service.impl;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.asset.constant.AssetLifecycleBusinessType;
|
||||
import com.ruoyi.asset.domain.AmsAsset;
|
||||
import com.ruoyi.asset.domain.AmsAssetLifecycleLog;
|
||||
import com.ruoyi.asset.mapper.AmsAssetLifecycleLogMapper;
|
||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.system.service.ISysDictDataService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AssetLifecycleServiceImplTest
|
||||
{
|
||||
@Mock
|
||||
private AmsAssetLifecycleLogMapper lifecycleLogMapper;
|
||||
|
||||
@Mock
|
||||
private ISysDictDataService sysDictDataService;
|
||||
|
||||
@InjectMocks
|
||||
private AssetLifecycleServiceImpl service;
|
||||
|
||||
@Test
|
||||
void recordLifecycleShouldFillSnapshotsAndDefaults()
|
||||
{
|
||||
AmsAsset beforeAsset = buildAsset(10L, "IN_STOCK", 1L, "一号仓", 11L, "A区", null, null, null, null);
|
||||
AmsAsset afterAsset = buildAsset(10L, "IN_USE", 2L, "二号仓", 22L, "B区", 3L, "张三", 4L, "生产部");
|
||||
AmsAssetLifecycleLog request = new AmsAssetLifecycleLog();
|
||||
request.setBusinessType(" " + AssetLifecycleBusinessType.RECEIVE + " ");
|
||||
request.setOperateUserId(100L);
|
||||
request.setOperateUserName(" 管理员 ");
|
||||
request.setCreateBy(" admin ");
|
||||
request.setChangeSummary(" 领用确认 ");
|
||||
|
||||
SysDictData businessType = new SysDictData();
|
||||
businessType.setDictValue(AssetLifecycleBusinessType.RECEIVE);
|
||||
when(sysDictDataService.selectDictDataList(any(SysDictData.class))).thenReturn(List.of(businessType));
|
||||
when(lifecycleLogMapper.insertAmsAssetLifecycleLog(any(AmsAssetLifecycleLog.class))).thenReturn(1);
|
||||
|
||||
int rows = service.recordLifecycle(beforeAsset, afterAsset, request);
|
||||
|
||||
ArgumentCaptor<AmsAssetLifecycleLog> captor = ArgumentCaptor.forClass(AmsAssetLifecycleLog.class);
|
||||
verify(lifecycleLogMapper).insertAmsAssetLifecycleLog(captor.capture());
|
||||
AmsAssetLifecycleLog actual = captor.getValue();
|
||||
assertEquals(1, rows);
|
||||
assertEquals(10L, actual.getAssetId());
|
||||
assertEquals("ASSET-001", actual.getAssetCode());
|
||||
assertEquals(AssetLifecycleBusinessType.RECEIVE, actual.getBusinessType());
|
||||
assertEquals("IN_STOCK", actual.getBeforeStatus());
|
||||
assertEquals("IN_USE", actual.getAfterStatus());
|
||||
assertEquals("一号仓", actual.getBeforeWarehouseName());
|
||||
assertEquals("二号仓", actual.getAfterWarehouseName());
|
||||
assertEquals("管理员", actual.getOperateUserName());
|
||||
assertEquals("领用确认", actual.getChangeSummary());
|
||||
assertEquals("admin", actual.getCreateBy());
|
||||
assertEquals("0", actual.getDelFlag());
|
||||
assertNotNull(actual.getOperateTime());
|
||||
assertNotNull(actual.getCreateTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
void recordLifecycleShouldRejectDifferentAssets()
|
||||
{
|
||||
AmsAsset beforeAsset = buildAsset(10L, "IN_STOCK", null, null, null, null, null, null, null, null);
|
||||
AmsAsset afterAsset = buildAsset(11L, "IN_USE", null, null, null, null, null, null, null, null);
|
||||
AmsAssetLifecycleLog request = new AmsAssetLifecycleLog();
|
||||
request.setBusinessType(AssetLifecycleBusinessType.RECEIVE);
|
||||
|
||||
assertThrows(ServiceException.class, () -> service.recordLifecycle(beforeAsset, afterAsset, request));
|
||||
|
||||
verify(sysDictDataService, never()).selectDictDataList(any(SysDictData.class));
|
||||
verify(lifecycleLogMapper, never()).insertAmsAssetLifecycleLog(any(AmsAssetLifecycleLog.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void recordLifecycleShouldRejectUnknownBusinessType()
|
||||
{
|
||||
AmsAsset asset = buildAsset(10L, "IN_STOCK", null, null, null, null, null, null, null, null);
|
||||
AmsAssetLifecycleLog request = new AmsAssetLifecycleLog();
|
||||
request.setBusinessType("UNKNOWN");
|
||||
SysDictData otherBusinessType = new SysDictData();
|
||||
otherBusinessType.setDictValue(AssetLifecycleBusinessType.INBOUND);
|
||||
when(sysDictDataService.selectDictDataList(any(SysDictData.class)))
|
||||
.thenReturn(List.of(otherBusinessType));
|
||||
|
||||
assertThrows(ServiceException.class, () -> service.recordLifecycle(asset, asset, request));
|
||||
|
||||
verify(lifecycleLogMapper, never()).insertAmsAssetLifecycleLog(any(AmsAssetLifecycleLog.class));
|
||||
}
|
||||
|
||||
private AmsAsset buildAsset(Long assetId, String assetStatus,
|
||||
Long warehouseId, String warehouseName, Long locationId, String locationName,
|
||||
Long userId, String userName, Long deptId, String deptName)
|
||||
{
|
||||
AmsAsset asset = new AmsAsset();
|
||||
asset.setAssetId(assetId);
|
||||
asset.setAssetCode("ASSET-001");
|
||||
asset.setAssetName("测试资产");
|
||||
asset.setAssetStatus(assetStatus);
|
||||
asset.setWarehouseId(warehouseId);
|
||||
asset.setWarehouseName(warehouseName);
|
||||
asset.setLocationId(locationId);
|
||||
asset.setLocationName(locationName);
|
||||
asset.setUseUserId(userId);
|
||||
asset.setUseUserName(userName);
|
||||
asset.setUseDeptId(deptId);
|
||||
asset.setUseDeptName(deptName);
|
||||
return asset;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue