feat(asset): 添加资产入库管理功能
- 新增入库单页面实现资产入库流程 - 添加入库订单实体类及明细项目实体类 - 实现入库管理控制器提供完整的CRUD操作 - 创建入库订单数据访问层及映射文件 - 开发入库服务业务逻辑处理 - 集成仓库、资产位置和资产数据联动功能 - 实现入库单状态管理和确认入库功能 - 添加入库单导出和权限控制功能main
parent
f79d622544
commit
d67da452a2
@ -0,0 +1,19 @@
|
|||||||
|
package com.ruoyi.asset.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 入库单状态
|
||||||
|
*
|
||||||
|
* @author Yangk
|
||||||
|
*/
|
||||||
|
public final class InboundOrderStatus
|
||||||
|
{
|
||||||
|
/** 草稿 */
|
||||||
|
public static final String DRAFT = "DRAFT";
|
||||||
|
|
||||||
|
/** 已入库 */
|
||||||
|
public static final String INBOUND_DONE = "INBOUND_DONE";
|
||||||
|
|
||||||
|
private InboundOrderStatus()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,196 @@
|
|||||||
|
package com.ruoyi.asset.controller;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.asset.domain.AmsInboundOrder;
|
||||||
|
import com.ruoyi.asset.domain.AmsAsset;
|
||||||
|
import com.ruoyi.asset.domain.AmsAssetLocation;
|
||||||
|
import com.ruoyi.asset.domain.AmsWarehouse;
|
||||||
|
import com.ruoyi.asset.constant.AssetStatus;
|
||||||
|
import com.ruoyi.asset.service.IAmsAssetLocationService;
|
||||||
|
import com.ruoyi.asset.service.IAmsAssetService;
|
||||||
|
import com.ruoyi.asset.service.IAmsInboundOrderService;
|
||||||
|
import com.ruoyi.asset.service.IAmsWarehouseService;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 入库管理Controller
|
||||||
|
*
|
||||||
|
* @author Yangk
|
||||||
|
* @date 2026-06-10
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/asset/inbound")
|
||||||
|
public class AmsInboundOrderController extends BaseController
|
||||||
|
{
|
||||||
|
private static final String ENABLED_YES = "Y";
|
||||||
|
|
||||||
|
private String prefix = "asset/inbound";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAmsInboundOrderService amsInboundOrderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAmsWarehouseService amsWarehouseService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAmsAssetLocationService amsAssetLocationService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAmsAssetService amsAssetService;
|
||||||
|
|
||||||
|
@RequiresPermissions("asset:inbound:view")
|
||||||
|
@GetMapping()
|
||||||
|
public String inbound(ModelMap mmap)
|
||||||
|
{
|
||||||
|
mmap.put("warehouseList", selectEnabledWarehouseList());
|
||||||
|
return prefix + "/inbound";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询入库管理列表
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("asset:inbound:list")
|
||||||
|
@PostMapping("/list")
|
||||||
|
@ResponseBody
|
||||||
|
public TableDataInfo list(AmsInboundOrder amsInboundOrder)
|
||||||
|
{
|
||||||
|
startPage();
|
||||||
|
List<AmsInboundOrder> list = amsInboundOrderService.selectAmsInboundOrderList(amsInboundOrder);
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出入库管理列表
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("asset:inbound:export")
|
||||||
|
@Log(title = "入库管理", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/export")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult export(AmsInboundOrder amsInboundOrder)
|
||||||
|
{
|
||||||
|
List<AmsInboundOrder> list = amsInboundOrderService.selectAmsInboundOrderList(amsInboundOrder);
|
||||||
|
ExcelUtil<AmsInboundOrder> util = new ExcelUtil<AmsInboundOrder>(AmsInboundOrder.class);
|
||||||
|
return util.exportExcel(list, "入库管理数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看入库管理详情
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("asset:inbound:view")
|
||||||
|
@GetMapping("/view/{orderId}")
|
||||||
|
public String view(@PathVariable("orderId") Long orderId, ModelMap mmap)
|
||||||
|
{
|
||||||
|
AmsInboundOrder amsInboundOrder = amsInboundOrderService.selectAmsInboundOrderByOrderId(orderId);
|
||||||
|
mmap.put("amsInboundOrder", amsInboundOrder);
|
||||||
|
return prefix + "/view";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增入库管理
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("asset:inbound:add")
|
||||||
|
@GetMapping("/add")
|
||||||
|
public String add(ModelMap mmap)
|
||||||
|
{
|
||||||
|
putInboundOptions(mmap);
|
||||||
|
return prefix + "/add";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增保存入库管理
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("asset:inbound:add")
|
||||||
|
@Log(title = "入库管理", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping("/add")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult addSave(AmsInboundOrder amsInboundOrder)
|
||||||
|
{
|
||||||
|
amsInboundOrder.setCreateBy(getLoginName());
|
||||||
|
return toAjax(amsInboundOrderService.insertAmsInboundOrder(amsInboundOrder));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改入库管理
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("asset:inbound:edit")
|
||||||
|
@GetMapping("/edit/{orderId}")
|
||||||
|
public String edit(@PathVariable("orderId") Long orderId, ModelMap mmap)
|
||||||
|
{
|
||||||
|
AmsInboundOrder amsInboundOrder = amsInboundOrderService.selectAmsInboundOrderByOrderId(orderId);
|
||||||
|
mmap.put("amsInboundOrder", amsInboundOrder);
|
||||||
|
putInboundOptions(mmap);
|
||||||
|
return prefix + "/edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改保存入库管理
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("asset:inbound:edit")
|
||||||
|
@Log(title = "入库管理", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/edit")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult editSave(AmsInboundOrder amsInboundOrder)
|
||||||
|
{
|
||||||
|
amsInboundOrder.setUpdateBy(getLoginName());
|
||||||
|
return toAjax(amsInboundOrderService.updateAmsInboundOrder(amsInboundOrder));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认入库
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("asset:inbound:confirm")
|
||||||
|
@Log(title = "入库管理", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/confirm/{orderId}")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult confirm(@PathVariable("orderId") Long orderId)
|
||||||
|
{
|
||||||
|
return toAjax(amsInboundOrderService.confirmInbound(orderId, getUserId(),
|
||||||
|
getSysUser().getUserName(), getLoginName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除入库管理
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("asset:inbound:remove")
|
||||||
|
@Log(title = "入库管理", businessType = BusinessType.DELETE)
|
||||||
|
@PostMapping( "/remove")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult remove(String ids)
|
||||||
|
{
|
||||||
|
return toAjax(amsInboundOrderService.deleteAmsInboundOrderByOrderIds(ids));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putInboundOptions(ModelMap mmap)
|
||||||
|
{
|
||||||
|
mmap.put("warehouseList", selectEnabledWarehouseList());
|
||||||
|
|
||||||
|
AmsAssetLocation location = new AmsAssetLocation();
|
||||||
|
location.setEnabled(ENABLED_YES);
|
||||||
|
mmap.put("locationList", amsAssetLocationService.selectAmsAssetLocationList(location));
|
||||||
|
|
||||||
|
AmsAsset asset = new AmsAsset();
|
||||||
|
asset.setAssetStatus(AssetStatus.IN_STOCK);
|
||||||
|
mmap.put("assetList", amsAssetService.selectAmsAssetList(asset));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AmsWarehouse> selectEnabledWarehouseList()
|
||||||
|
{
|
||||||
|
AmsWarehouse warehouse = new AmsWarehouse();
|
||||||
|
warehouse.setEnabled(ENABLED_YES);
|
||||||
|
return amsWarehouseService.selectAmsWarehouseList(warehouse);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
package com.ruoyi.asset.mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.ruoyi.asset.domain.AmsInboundOrder;
|
||||||
|
import com.ruoyi.asset.domain.AmsInboundOrderItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 入库管理Mapper接口
|
||||||
|
*
|
||||||
|
* @author Yangk
|
||||||
|
* @date 2026-06-10
|
||||||
|
*/
|
||||||
|
public interface AmsInboundOrderMapper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 查询入库管理
|
||||||
|
*
|
||||||
|
* @param orderId 入库管理主键
|
||||||
|
* @return 入库管理
|
||||||
|
*/
|
||||||
|
public AmsInboundOrder selectAmsInboundOrderByOrderId(Long orderId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 锁定并查询入库单
|
||||||
|
*
|
||||||
|
* @param orderId 入库单ID
|
||||||
|
* @return 入库单
|
||||||
|
*/
|
||||||
|
public AmsInboundOrder selectAmsInboundOrderByOrderIdForUpdate(Long orderId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询入库管理列表
|
||||||
|
*
|
||||||
|
* @param amsInboundOrder 入库管理
|
||||||
|
* @return 入库管理集合
|
||||||
|
*/
|
||||||
|
public List<AmsInboundOrder> selectAmsInboundOrderList(AmsInboundOrder amsInboundOrder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增入库管理
|
||||||
|
*
|
||||||
|
* @param amsInboundOrder 入库管理
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertAmsInboundOrder(AmsInboundOrder amsInboundOrder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改入库管理
|
||||||
|
*
|
||||||
|
* @param amsInboundOrder 入库管理
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateAmsInboundOrder(AmsInboundOrder amsInboundOrder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认入库并写入操作人信息
|
||||||
|
*
|
||||||
|
* @param amsInboundOrder 入库单
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int confirmAmsInboundOrder(AmsInboundOrder amsInboundOrder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除入库管理
|
||||||
|
*
|
||||||
|
* @param orderId 入库管理主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteAmsInboundOrderByOrderId(Long orderId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除入库管理
|
||||||
|
*
|
||||||
|
* @param orderIds 需要删除的数据主键集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteAmsInboundOrderByOrderIds(String[] orderIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除入库单明细
|
||||||
|
*
|
||||||
|
* @param orderIds 需要删除的数据主键集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteAmsInboundOrderItemByOrderIds(String[] orderIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量新增入库单明细
|
||||||
|
*
|
||||||
|
* @param amsInboundOrderItemList 入库单明细列表
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int batchAmsInboundOrderItem(List<AmsInboundOrderItem> amsInboundOrderItemList);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过入库管理主键删除入库单明细信息
|
||||||
|
*
|
||||||
|
* @param orderId 入库管理ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteAmsInboundOrderItemByOrderId(Long orderId);
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
package com.ruoyi.asset.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.ruoyi.asset.domain.AmsInboundOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 入库管理Service接口
|
||||||
|
*
|
||||||
|
* @author Yangk
|
||||||
|
* @date 2026-06-10
|
||||||
|
*/
|
||||||
|
public interface IAmsInboundOrderService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 查询入库管理
|
||||||
|
*
|
||||||
|
* @param orderId 入库管理主键
|
||||||
|
* @return 入库管理
|
||||||
|
*/
|
||||||
|
public AmsInboundOrder selectAmsInboundOrderByOrderId(Long orderId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询入库管理列表
|
||||||
|
*
|
||||||
|
* @param amsInboundOrder 入库管理
|
||||||
|
* @return 入库管理集合
|
||||||
|
*/
|
||||||
|
public List<AmsInboundOrder> selectAmsInboundOrderList(AmsInboundOrder amsInboundOrder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增入库管理
|
||||||
|
*
|
||||||
|
* @param amsInboundOrder 入库管理
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int insertAmsInboundOrder(AmsInboundOrder amsInboundOrder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改入库管理
|
||||||
|
*
|
||||||
|
* @param amsInboundOrder 入库管理
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateAmsInboundOrder(AmsInboundOrder amsInboundOrder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认入库
|
||||||
|
*
|
||||||
|
* @param orderId 入库单ID
|
||||||
|
* @param operateUserId 操作用户ID
|
||||||
|
* @param operateUserName 操作用户名称
|
||||||
|
* @param operateLoginName 操作登录账号
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int confirmInbound(Long orderId, Long operateUserId, String operateUserName, String operateLoginName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除入库管理
|
||||||
|
*
|
||||||
|
* @param orderIds 需要删除的入库管理主键集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteAmsInboundOrderByOrderIds(String orderIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除入库管理信息
|
||||||
|
*
|
||||||
|
* @param orderId 入库管理主键
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteAmsInboundOrderByOrderId(Long orderId);
|
||||||
|
}
|
||||||
@ -0,0 +1,188 @@
|
|||||||
|
<?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.AmsInboundOrderMapper">
|
||||||
|
|
||||||
|
<resultMap type="AmsInboundOrder" id="AmsInboundOrderResult">
|
||||||
|
<result property="orderId" column="order_id" />
|
||||||
|
<result property="inboundNo" column="inbound_no" />
|
||||||
|
<result property="warehouseId" column="warehouse_id" />
|
||||||
|
<result property="warehouseCode" column="warehouse_code" />
|
||||||
|
<result property="warehouseName" column="warehouse_name" />
|
||||||
|
<result property="inboundUserId" column="inbound_user_id" />
|
||||||
|
<result property="inboundUserName" column="inbound_user_name" />
|
||||||
|
<result property="inboundTime" column="inbound_time" />
|
||||||
|
<result property="orderStatus" column="order_status" />
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<resultMap id="AmsInboundOrderItemCollectionResult" type="AmsInboundOrder" extends="AmsInboundOrderResult">
|
||||||
|
<collection property="amsInboundOrderItemList" ofType="AmsInboundOrderItem"
|
||||||
|
column="order_id" select="selectAmsInboundOrderItemList" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<resultMap type="AmsInboundOrderItem" id="AmsInboundOrderItemResult">
|
||||||
|
<result property="itemId" column="item_id" />
|
||||||
|
<result property="orderId" column="order_id" />
|
||||||
|
<result property="inboundNo" column="inbound_no" />
|
||||||
|
<result property="assetId" column="asset_id" />
|
||||||
|
<result property="assetCode" column="asset_code" />
|
||||||
|
<result property="assetName" column="asset_name" />
|
||||||
|
<result property="categoryId" column="category_id" />
|
||||||
|
<result property="categoryCode" column="category_code" />
|
||||||
|
<result property="categoryName" column="category_name" />
|
||||||
|
<result property="specModel" column="spec_model" />
|
||||||
|
<result property="brand" column="brand" />
|
||||||
|
<result property="locationId" column="location_id" />
|
||||||
|
<result property="locationCode" column="location_code" />
|
||||||
|
<result property="locationName" column="location_name" />
|
||||||
|
<result property="inboundQuantity" column="inbound_quantity" />
|
||||||
|
<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="selectAmsInboundOrderVo">
|
||||||
|
select order_id, inbound_no, warehouse_id, warehouse_code, warehouse_name,
|
||||||
|
inbound_user_id, inbound_user_name, inbound_time, order_status,
|
||||||
|
create_by, create_time, update_by, update_time, remark, del_flag
|
||||||
|
from ams_inbound_order
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectAmsInboundOrderList" parameterType="AmsInboundOrder" resultMap="AmsInboundOrderResult">
|
||||||
|
<include refid="selectAmsInboundOrderVo"/>
|
||||||
|
<where>
|
||||||
|
del_flag = '0'
|
||||||
|
<if test="inboundNo != null and inboundNo != ''">and inbound_no = #{inboundNo}</if>
|
||||||
|
<if test="warehouseId != null">and warehouse_id = #{warehouseId}</if>
|
||||||
|
<if test="inboundUserName != null and inboundUserName != ''">
|
||||||
|
and inbound_user_name like concat('%', #{inboundUserName}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="params.beginInboundTime != null and params.beginInboundTime != ''">
|
||||||
|
and inbound_time >= #{params.beginInboundTime}
|
||||||
|
</if>
|
||||||
|
<if test="params.endInboundTime != null and params.endInboundTime != ''">
|
||||||
|
and inbound_time < date_add(#{params.endInboundTime}, interval 1 day)
|
||||||
|
</if>
|
||||||
|
<if test="orderStatus != null and orderStatus != ''">and order_status = #{orderStatus}</if>
|
||||||
|
<if test="assetCode != null and assetCode != ''">
|
||||||
|
and exists (
|
||||||
|
select 1 from ams_inbound_order_item item
|
||||||
|
where item.order_id = ams_inbound_order.order_id
|
||||||
|
and item.del_flag = '0'
|
||||||
|
and item.asset_code like concat(#{assetCode}, '%')
|
||||||
|
)
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
order by create_time desc, order_id desc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAmsInboundOrderByOrderId" parameterType="Long" resultMap="AmsInboundOrderItemCollectionResult">
|
||||||
|
<include refid="selectAmsInboundOrderVo"/>
|
||||||
|
where order_id = #{orderId} and del_flag = '0'
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAmsInboundOrderByOrderIdForUpdate" parameterType="Long"
|
||||||
|
resultMap="AmsInboundOrderItemCollectionResult">
|
||||||
|
<include refid="selectAmsInboundOrderVo"/>
|
||||||
|
where order_id = #{orderId} and del_flag = '0'
|
||||||
|
for update
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAmsInboundOrderItemList" resultMap="AmsInboundOrderItemResult">
|
||||||
|
select item_id, order_id, inbound_no, asset_id, asset_code, asset_name, category_id,
|
||||||
|
category_code, category_name, spec_model, brand, location_id, location_code,
|
||||||
|
location_name, inbound_quantity, create_by, create_time, update_by, update_time,
|
||||||
|
remark, del_flag
|
||||||
|
from ams_inbound_order_item
|
||||||
|
where order_id = #{order_id} and del_flag = '0'
|
||||||
|
order by item_id
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertAmsInboundOrder" parameterType="AmsInboundOrder" useGeneratedKeys="true" keyProperty="orderId">
|
||||||
|
insert into ams_inbound_order (
|
||||||
|
inbound_no, warehouse_id, warehouse_code, warehouse_name, order_status,
|
||||||
|
create_by, create_time, remark, del_flag
|
||||||
|
) values (
|
||||||
|
#{inboundNo}, #{warehouseId}, #{warehouseCode}, #{warehouseName}, #{orderStatus},
|
||||||
|
#{createBy}, #{createTime}, #{remark}, #{delFlag}
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateAmsInboundOrder" parameterType="AmsInboundOrder">
|
||||||
|
update ams_inbound_order
|
||||||
|
set warehouse_id = #{warehouseId},
|
||||||
|
warehouse_code = #{warehouseCode},
|
||||||
|
warehouse_name = #{warehouseName},
|
||||||
|
update_by = #{updateBy},
|
||||||
|
update_time = #{updateTime},
|
||||||
|
remark = #{remark}
|
||||||
|
where order_id = #{orderId} and del_flag = '0' and order_status = 'DRAFT'
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="confirmAmsInboundOrder" parameterType="AmsInboundOrder">
|
||||||
|
update ams_inbound_order
|
||||||
|
set order_status = #{orderStatus},
|
||||||
|
inbound_user_id = #{inboundUserId},
|
||||||
|
inbound_user_name = #{inboundUserName},
|
||||||
|
inbound_time = #{inboundTime},
|
||||||
|
update_by = #{updateBy},
|
||||||
|
update_time = #{updateTime}
|
||||||
|
where order_id = #{orderId} and del_flag = '0' and order_status = 'DRAFT'
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="deleteAmsInboundOrderByOrderId" parameterType="Long">
|
||||||
|
update ams_inbound_order
|
||||||
|
set del_flag = '1'
|
||||||
|
where order_id = #{orderId} and del_flag = '0' and order_status = 'DRAFT'
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="deleteAmsInboundOrderByOrderIds" parameterType="String">
|
||||||
|
update ams_inbound_order set del_flag = '1' where order_id in
|
||||||
|
<foreach item="orderId" collection="array" open="(" separator="," close=")">
|
||||||
|
#{orderId}
|
||||||
|
</foreach>
|
||||||
|
and del_flag = '0' and order_status = 'DRAFT'
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="deleteAmsInboundOrderItemByOrderIds" parameterType="String">
|
||||||
|
update ams_inbound_order_item set del_flag = '1' where order_id in
|
||||||
|
<foreach item="orderId" collection="array" open="(" separator="," close=")">
|
||||||
|
#{orderId}
|
||||||
|
</foreach>
|
||||||
|
and del_flag = '0'
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="deleteAmsInboundOrderItemByOrderId" parameterType="Long">
|
||||||
|
update ams_inbound_order_item
|
||||||
|
set del_flag = '1'
|
||||||
|
where order_id = #{orderId} and del_flag = '0'
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<insert id="batchAmsInboundOrderItem">
|
||||||
|
insert into ams_inbound_order_item (
|
||||||
|
order_id, inbound_no, asset_id, asset_code, asset_name, category_id, category_code,
|
||||||
|
category_name, spec_model, brand, location_id, location_code, location_name,
|
||||||
|
inbound_quantity, create_by, create_time, remark, del_flag
|
||||||
|
) values
|
||||||
|
<foreach item="item" collection="list" separator=",">
|
||||||
|
(
|
||||||
|
#{item.orderId}, #{item.inboundNo}, #{item.assetId}, #{item.assetCode},
|
||||||
|
#{item.assetName}, #{item.categoryId}, #{item.categoryCode}, #{item.categoryName},
|
||||||
|
#{item.specModel}, #{item.brand}, #{item.locationId}, #{item.locationCode},
|
||||||
|
#{item.locationName}, #{item.inboundQuantity}, #{item.createBy}, #{item.createTime},
|
||||||
|
#{item.remark}, #{item.delFlag}
|
||||||
|
)
|
||||||
|
</foreach>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,211 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<th:block th:include="include :: header('新增入库单')" />
|
||||||
|
<style type="text/css">
|
||||||
|
table label.error { position: inherit; }
|
||||||
|
select + label.error { z-index: 1; right: 40px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="white-bg">
|
||||||
|
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||||
|
<form class="form-horizontal m" id="form-inbound-add">
|
||||||
|
<h4 class="form-header h4">基本信息</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-4 control-label is-required">入库仓库:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select id="warehouseId" name="warehouseId" class="form-control" required>
|
||||||
|
<option value="">请选择入库仓库</option>
|
||||||
|
<option th:each="warehouse : ${warehouseList}"
|
||||||
|
th:value="${warehouse.warehouseId}"
|
||||||
|
th:text="${warehouse.warehouseCode + ' - ' + warehouse.warehouseName}"></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-4 control-label">备注:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<textarea name="remark" maxlength="500" class="form-control" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 class="form-header h4">入库明细</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<button type="button" class="btn btn-white btn-sm" onclick="addRow()">
|
||||||
|
<i class="fa fa-plus"> 增加</i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-white btn-sm" onclick="sub.delRow()">
|
||||||
|
<i class="fa fa-minus"> 删除</i>
|
||||||
|
</button>
|
||||||
|
<div class="col-sm-12 select-table table-striped">
|
||||||
|
<table id="bootstrap-table"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<th:block th:include="include :: footer" />
|
||||||
|
<script th:inline="javascript">
|
||||||
|
var prefix = ctx + "asset/inbound";
|
||||||
|
var assetList = [[${assetList}]];
|
||||||
|
var locationList = [[${locationList}]];
|
||||||
|
|
||||||
|
$("#form-inbound-add").validate({
|
||||||
|
focusCleanup: true
|
||||||
|
});
|
||||||
|
|
||||||
|
function submitHandler() {
|
||||||
|
if ($("#bootstrap-table").bootstrapTable('getData').length === 0) {
|
||||||
|
$.modal.alertWarning("请至少添加一条入库明细");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($.validate.form()) {
|
||||||
|
$.operate.save(prefix + "/add", $('#form-inbound-add').serialize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
initDetailTable([]);
|
||||||
|
$("#warehouseId").change(function() {
|
||||||
|
if ($("#bootstrap-table").bootstrapTable('getData').length > 0) {
|
||||||
|
$("#bootstrap-table").bootstrapTable('removeAll');
|
||||||
|
$.modal.alertWarning("入库仓库已变更,请重新添加入库明细");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function initDetailTable(data) {
|
||||||
|
var options = {
|
||||||
|
data: data,
|
||||||
|
pagination: false,
|
||||||
|
showSearch: false,
|
||||||
|
showRefresh: false,
|
||||||
|
showToggle: false,
|
||||||
|
showColumns: false,
|
||||||
|
sidePagination: "client",
|
||||||
|
columns: [{
|
||||||
|
checkbox: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'index',
|
||||||
|
align: 'center',
|
||||||
|
title: "序号",
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
return $.table.serialNumber(index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'assetId',
|
||||||
|
title: '资产',
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
return buildAssetSelect(value, index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'locationId',
|
||||||
|
title: '入库位置',
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
return buildLocationSelect(value, index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'inboundQuantity',
|
||||||
|
align: 'center',
|
||||||
|
title: '数量',
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
return '<input class="form-control" type="text" readonly name="amsInboundOrderItemList['
|
||||||
|
+ index + '].inboundQuantity" value="1">';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'remark',
|
||||||
|
title: '明细备注',
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
return buildInput("amsInboundOrderItemList[" + index + "].remark", value, 500);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
align: 'center',
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
var rowIndex = $.common.isNotEmpty(row.index) ? row.index : $.table.serialNumber(index);
|
||||||
|
return '<a class="btn btn-danger btn-xs" href="javascript:void(0)" onclick="sub.delRowByIndex(\''
|
||||||
|
+ rowIndex + '\')"><i class="fa fa-remove"></i>删除</a>';
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
$.table.init(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addRow() {
|
||||||
|
if ($.common.isEmpty($("#warehouseId").val())) {
|
||||||
|
$.modal.alertWarning("请先选择入库仓库");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var count = $("#bootstrap-table").bootstrapTable('getData').length;
|
||||||
|
sub.addRow({
|
||||||
|
index: $.table.serialNumber(count),
|
||||||
|
assetId: "",
|
||||||
|
locationId: "",
|
||||||
|
inboundQuantity: 1,
|
||||||
|
remark: ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildAssetSelect(value, index) {
|
||||||
|
var select = $("<select>").addClass("form-control").attr({
|
||||||
|
name: "amsInboundOrderItemList[" + index + "].assetId",
|
||||||
|
required: true
|
||||||
|
});
|
||||||
|
select.append($("<option>").val("").text("请选择资产"));
|
||||||
|
$.each(assetList, function(i, asset) {
|
||||||
|
var label = asset.assetCode + " - " + asset.assetName;
|
||||||
|
if ($.common.isNotEmpty(asset.categoryName)) {
|
||||||
|
label += " - " + asset.categoryName;
|
||||||
|
}
|
||||||
|
var option = $("<option>").val(asset.assetId).text(label);
|
||||||
|
if (String(asset.assetId) === String(value)) {
|
||||||
|
option.attr("selected", "selected");
|
||||||
|
}
|
||||||
|
select.append(option);
|
||||||
|
});
|
||||||
|
return select.prop("outerHTML");
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildLocationSelect(value, index) {
|
||||||
|
var warehouseId = $("#warehouseId").val();
|
||||||
|
var select = $("<select>").addClass("form-control").attr({
|
||||||
|
name: "amsInboundOrderItemList[" + index + "].locationId",
|
||||||
|
required: true
|
||||||
|
});
|
||||||
|
select.append($("<option>").val("").text("请选择入库位置"));
|
||||||
|
$.each(locationList, function(i, location) {
|
||||||
|
if (String(location.warehouseId) === String(warehouseId)) {
|
||||||
|
var label = location.locationCode + " - " + location.locationName;
|
||||||
|
var option = $("<option>").val(location.locationId).text(label);
|
||||||
|
if (String(location.locationId) === String(value)) {
|
||||||
|
option.attr("selected", "selected");
|
||||||
|
}
|
||||||
|
select.append(option);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return select.prop("outerHTML");
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildInput(name, value, maxLength) {
|
||||||
|
return $("<input>").addClass("form-control").attr({
|
||||||
|
type: "text",
|
||||||
|
name: name,
|
||||||
|
maxlength: maxLength
|
||||||
|
}).val(value || "").prop("outerHTML");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,224 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<th:block th:include="include :: header('修改入库单')" />
|
||||||
|
<style type="text/css">
|
||||||
|
table label.error { position: inherit; }
|
||||||
|
select + label.error { z-index: 1; right: 40px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="white-bg">
|
||||||
|
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||||
|
<form class="form-horizontal m" id="form-inbound-edit" th:object="${amsInboundOrder}">
|
||||||
|
<input name="orderId" th:field="*{orderId}" type="hidden">
|
||||||
|
<h4 class="form-header h4">基本信息</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-4 control-label">入库单号:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input th:value="*{inboundNo}" class="form-control" type="text" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-4 control-label is-required">入库仓库:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select id="warehouseId" name="warehouseId" class="form-control" required>
|
||||||
|
<option value="">请选择入库仓库</option>
|
||||||
|
<option th:each="warehouse : ${warehouseList}"
|
||||||
|
th:value="${warehouse.warehouseId}"
|
||||||
|
th:text="${warehouse.warehouseCode + ' - ' + warehouse.warehouseName}"
|
||||||
|
th:selected="${warehouse.warehouseId == amsInboundOrder.warehouseId}"></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-2 control-label">备注:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<textarea name="remark" maxlength="500" class="form-control" rows="3">[[*{remark}]]</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 class="form-header h4">入库明细</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<button type="button" class="btn btn-white btn-sm" onclick="addRow()">
|
||||||
|
<i class="fa fa-plus"> 增加</i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-white btn-sm" onclick="sub.delRow()">
|
||||||
|
<i class="fa fa-minus"> 删除</i>
|
||||||
|
</button>
|
||||||
|
<div class="col-sm-12 select-table table-striped">
|
||||||
|
<table id="bootstrap-table"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<th:block th:include="include :: footer" />
|
||||||
|
<script th:inline="javascript">
|
||||||
|
var prefix = ctx + "asset/inbound";
|
||||||
|
var assetList = [[${assetList}]];
|
||||||
|
var locationList = [[${locationList}]];
|
||||||
|
var detailList = [[${amsInboundOrder.amsInboundOrderItemList}]];
|
||||||
|
|
||||||
|
$("#form-inbound-edit").validate({
|
||||||
|
focusCleanup: true
|
||||||
|
});
|
||||||
|
|
||||||
|
function submitHandler() {
|
||||||
|
if ($("#bootstrap-table").bootstrapTable('getData').length === 0) {
|
||||||
|
$.modal.alertWarning("请至少保留一条入库明细");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($.validate.form()) {
|
||||||
|
$.operate.save(prefix + "/edit", $('#form-inbound-edit').serialize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
initDetailTable(detailList);
|
||||||
|
$("#warehouseId").change(function() {
|
||||||
|
if ($("#bootstrap-table").bootstrapTable('getData').length > 0) {
|
||||||
|
$("#bootstrap-table").bootstrapTable('removeAll');
|
||||||
|
$.modal.alertWarning("入库仓库已变更,请重新添加入库明细");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function initDetailTable(data) {
|
||||||
|
var options = {
|
||||||
|
data: data,
|
||||||
|
pagination: false,
|
||||||
|
showSearch: false,
|
||||||
|
showRefresh: false,
|
||||||
|
showToggle: false,
|
||||||
|
showColumns: false,
|
||||||
|
sidePagination: "client",
|
||||||
|
columns: [{
|
||||||
|
checkbox: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'index',
|
||||||
|
align: 'center',
|
||||||
|
title: "序号",
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
return $.table.serialNumber(index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'assetId',
|
||||||
|
title: '资产',
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
return buildAssetSelect(value, index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'locationId',
|
||||||
|
title: '入库位置',
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
return buildLocationSelect(value, index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'inboundQuantity',
|
||||||
|
align: 'center',
|
||||||
|
title: '数量',
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
return '<input class="form-control" type="text" readonly name="amsInboundOrderItemList['
|
||||||
|
+ index + '].inboundQuantity" value="1">';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'remark',
|
||||||
|
title: '明细备注',
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
return buildInput("amsInboundOrderItemList[" + index + "].remark", value, 500);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
align: 'center',
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
var rowIndex = $.common.isNotEmpty(row.index) ? row.index : $.table.serialNumber(index);
|
||||||
|
return '<a class="btn btn-danger btn-xs" href="javascript:void(0)" onclick="sub.delRowByIndex(\''
|
||||||
|
+ rowIndex + '\')"><i class="fa fa-remove"></i>删除</a>';
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
$.table.init(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addRow() {
|
||||||
|
if ($.common.isEmpty($("#warehouseId").val())) {
|
||||||
|
$.modal.alertWarning("请先选择入库仓库");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var count = $("#bootstrap-table").bootstrapTable('getData').length;
|
||||||
|
sub.addRow({
|
||||||
|
index: $.table.serialNumber(count),
|
||||||
|
assetId: "",
|
||||||
|
locationId: "",
|
||||||
|
inboundQuantity: 1,
|
||||||
|
remark: ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildAssetSelect(value, index) {
|
||||||
|
var select = $("<select>").addClass("form-control").attr({
|
||||||
|
name: "amsInboundOrderItemList[" + index + "].assetId",
|
||||||
|
required: true
|
||||||
|
});
|
||||||
|
select.append($("<option>").val("").text("请选择资产"));
|
||||||
|
$.each(assetList, function(i, asset) {
|
||||||
|
var label = asset.assetCode + " - " + asset.assetName;
|
||||||
|
if ($.common.isNotEmpty(asset.categoryName)) {
|
||||||
|
label += " - " + asset.categoryName;
|
||||||
|
}
|
||||||
|
var option = $("<option>").val(asset.assetId).text(label);
|
||||||
|
if (String(asset.assetId) === String(value)) {
|
||||||
|
option.attr("selected", "selected");
|
||||||
|
}
|
||||||
|
select.append(option);
|
||||||
|
});
|
||||||
|
return select.prop("outerHTML");
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildLocationSelect(value, index) {
|
||||||
|
var warehouseId = $("#warehouseId").val();
|
||||||
|
var select = $("<select>").addClass("form-control").attr({
|
||||||
|
name: "amsInboundOrderItemList[" + index + "].locationId",
|
||||||
|
required: true
|
||||||
|
});
|
||||||
|
select.append($("<option>").val("").text("请选择入库位置"));
|
||||||
|
$.each(locationList, function(i, location) {
|
||||||
|
if (String(location.warehouseId) === String(warehouseId)) {
|
||||||
|
var label = location.locationCode + " - " + location.locationName;
|
||||||
|
var option = $("<option>").val(location.locationId).text(label);
|
||||||
|
if (String(location.locationId) === String(value)) {
|
||||||
|
option.attr("selected", "selected");
|
||||||
|
}
|
||||||
|
select.append(option);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return select.prop("outerHTML");
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildInput(name, value, maxLength) {
|
||||||
|
return $("<input>").addClass("form-control").attr({
|
||||||
|
type: "text",
|
||||||
|
name: name,
|
||||||
|
maxlength: maxLength
|
||||||
|
}).val(value || "").prop("outerHTML");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,152 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
|
||||||
|
<head>
|
||||||
|
<th:block th:include="include :: header('入库管理列表')" />
|
||||||
|
<th:block th:include="include :: datetimepicker-css" />
|
||||||
|
</head>
|
||||||
|
<body class="gray-bg">
|
||||||
|
<div class="container-div">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 search-collapse">
|
||||||
|
<form id="formId">
|
||||||
|
<div class="select-list">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<label>入库单号:</label>
|
||||||
|
<input type="text" name="inboundNo"/>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>入库仓库:</label>
|
||||||
|
<select name="warehouseId">
|
||||||
|
<option value="">所有</option>
|
||||||
|
<option th:each="warehouse : ${warehouseList}"
|
||||||
|
th:value="${warehouse.warehouseId}"
|
||||||
|
th:text="${warehouse.warehouseCode + ' - ' + warehouse.warehouseName}"></option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>入库人:</label>
|
||||||
|
<input type="text" name="inboundUserName"/>
|
||||||
|
</li>
|
||||||
|
<li class="select-time">
|
||||||
|
<label>入库时间:</label>
|
||||||
|
<input type="text" class="time-input" id="startTime" placeholder="开始时间"
|
||||||
|
name="params[beginInboundTime]"/>
|
||||||
|
<span>-</span>
|
||||||
|
<input type="text" class="time-input" id="endTime" placeholder="结束时间"
|
||||||
|
name="params[endInboundTime]"/>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>单据状态:</label>
|
||||||
|
<select name="orderStatus" th:with="type=${@dict.getType('ams_inbound_status')}">
|
||||||
|
<option value="">所有</option>
|
||||||
|
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
|
||||||
|
th:value="${dict.dictValue}"></option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>资产编码:</label>
|
||||||
|
<input type="text" name="assetCode"/>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()">
|
||||||
|
<i class="fa fa-search"></i> 搜索
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()">
|
||||||
|
<i class="fa fa-refresh"></i> 重置
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group-sm" id="toolbar" role="group">
|
||||||
|
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="asset:inbound:add">
|
||||||
|
<i class="fa fa-plus"></i> 添加
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="asset:inbound:export">
|
||||||
|
<i class="fa fa-download"></i> 导出
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 select-table table-striped">
|
||||||
|
<table id="bootstrap-table"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<th:block th:include="include :: footer" />
|
||||||
|
<th:block th:include="include :: datetimepicker-js" />
|
||||||
|
<script th:inline="javascript">
|
||||||
|
var editFlag = [[${@permission.hasPermi('asset:inbound:edit')}]];
|
||||||
|
var removeFlag = [[${@permission.hasPermi('asset:inbound:remove')}]];
|
||||||
|
var confirmFlag = [[${@permission.hasPermi('asset:inbound:confirm')}]];
|
||||||
|
var orderStatusDatas = [[${@dict.getType('ams_inbound_status')}]];
|
||||||
|
var prefix = ctx + "asset/inbound";
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
var options = {
|
||||||
|
url: prefix + "/list",
|
||||||
|
viewUrl: prefix + "/view/{id}",
|
||||||
|
createUrl: prefix + "/add",
|
||||||
|
updateUrl: prefix + "/edit/{id}",
|
||||||
|
removeUrl: prefix + "/remove",
|
||||||
|
exportUrl: prefix + "/export",
|
||||||
|
modalName: "入库单",
|
||||||
|
columns: [{
|
||||||
|
field: 'orderId',
|
||||||
|
title: '单据ID',
|
||||||
|
visible: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'inboundNo',
|
||||||
|
title: '入库单号'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'warehouseName',
|
||||||
|
title: '入库仓库'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'inboundUserName',
|
||||||
|
title: '入库人'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'inboundTime',
|
||||||
|
title: '入库时间'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'orderStatus',
|
||||||
|
title: '单据状态',
|
||||||
|
formatter: function(value) {
|
||||||
|
return $.table.selectDictLabel(orderStatusDatas, value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'remark',
|
||||||
|
title: '备注'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
align: 'center',
|
||||||
|
formatter: function(value, row) {
|
||||||
|
var actions = [];
|
||||||
|
actions.push('<a class="btn btn-info btn-xs" href="javascript:void(0)" onclick="$.operate.view(\'' + row.orderId + '\')"><i class="fa fa-eye"></i>查看</a> ');
|
||||||
|
if (row.orderStatus === "DRAFT") {
|
||||||
|
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.orderId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
|
||||||
|
actions.push('<a class="btn btn-primary btn-xs ' + confirmFlag + '" href="javascript:void(0)" onclick="confirmInbound(\'' + row.orderId + '\')"><i class="fa fa-check"></i>确认入库</a> ');
|
||||||
|
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.orderId + '\')"><i class="fa fa-remove"></i>删除</a>');
|
||||||
|
}
|
||||||
|
return actions.join('');
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
$.table.init(options);
|
||||||
|
});
|
||||||
|
|
||||||
|
function confirmInbound(orderId) {
|
||||||
|
$.modal.confirm("确认入库后将更新资产仓库与位置,且单据不可再修改。是否继续?", function() {
|
||||||
|
$.operate.post(prefix + "/confirm/" + orderId, {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<th:block th:include="include :: header('入库单详情')" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="main-content">
|
||||||
|
<form class="form-horizontal" th:object="${amsInboundOrder}">
|
||||||
|
<h4 class="form-header h4">基本信息</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-4 control-label">入库单号:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<p class="form-control-plaintext" th:text="*{inboundNo}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-4 control-label">入库仓库:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<p class="form-control-plaintext" th:text="*{warehouseCode + ' - ' + warehouseName}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-4 control-label">单据状态:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<p class="form-control-plaintext" th:text="*{@dict.getLabel('ams_inbound_status', orderStatus)}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-4 control-label">入库人:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<p class="form-control-plaintext" th:text="*{inboundUserName}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-4 control-label">入库时间:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<p class="form-control-plaintext"
|
||||||
|
th:text="*{inboundTime == null ? '' : #dates.format(inboundTime, 'yyyy-MM-dd HH:mm:ss')}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-4 control-label">备注:</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<p class="form-control-plaintext" th:text="*{remark}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 class="form-header h4">入库明细</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 select-table table-striped">
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>序号</th>
|
||||||
|
<th>资产编码</th>
|
||||||
|
<th>资产名称</th>
|
||||||
|
<th>资产类别</th>
|
||||||
|
<th>规格型号</th>
|
||||||
|
<th>品牌</th>
|
||||||
|
<th>入库位置</th>
|
||||||
|
<th>数量</th>
|
||||||
|
<th>备注</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="item, stat : *{amsInboundOrderItemList}">
|
||||||
|
<td th:text="${stat.count}"></td>
|
||||||
|
<td th:text="${item.assetCode}"></td>
|
||||||
|
<td th:text="${item.assetName}"></td>
|
||||||
|
<td th:text="${item.categoryName}"></td>
|
||||||
|
<td th:text="${item.specModel}"></td>
|
||||||
|
<td th:text="${item.brand}"></td>
|
||||||
|
<td th:text="${item.locationCode + ' - ' + item.locationName}"></td>
|
||||||
|
<td th:text="${item.inboundQuantity}"></td>
|
||||||
|
<td th:text="${item.remark}"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<th:block th:include="include :: footer" />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,205 @@
|
|||||||
|
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.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyList;
|
||||||
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import com.ruoyi.asset.constant.AssetStatus;
|
||||||
|
import com.ruoyi.asset.constant.InboundOrderStatus;
|
||||||
|
import com.ruoyi.asset.domain.AmsAsset;
|
||||||
|
import com.ruoyi.asset.domain.AmsAssetLocation;
|
||||||
|
import com.ruoyi.asset.domain.AmsInboundOrder;
|
||||||
|
import com.ruoyi.asset.domain.AmsInboundOrderItem;
|
||||||
|
import com.ruoyi.asset.domain.AmsWarehouse;
|
||||||
|
import com.ruoyi.asset.domain.AssetTransitionContext;
|
||||||
|
import com.ruoyi.asset.mapper.AmsInboundOrderMapper;
|
||||||
|
import com.ruoyi.asset.service.IAmsAssetLocationService;
|
||||||
|
import com.ruoyi.asset.service.IAmsAssetService;
|
||||||
|
import com.ruoyi.asset.service.IAmsWarehouseService;
|
||||||
|
import com.ruoyi.asset.service.IAssetStatusTransitionService;
|
||||||
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import com.ruoyi.system.service.ISysCodeRuleService;
|
||||||
|
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 AmsInboundOrderServiceImplTest
|
||||||
|
{
|
||||||
|
@Mock
|
||||||
|
private AmsInboundOrderMapper amsInboundOrderMapper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ISysCodeRuleService sysCodeRuleService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private IAmsWarehouseService amsWarehouseService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private IAmsAssetLocationService amsAssetLocationService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private IAmsAssetService amsAssetService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private IAssetStatusTransitionService assetStatusTransitionService;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private AmsInboundOrderServiceImpl service;
|
||||||
|
|
||||||
|
/** 新增草稿时由服务层生成单号,并从主数据回填所有快照。 */
|
||||||
|
@Test
|
||||||
|
void insertShouldGenerateCodeAndFillSnapshots()
|
||||||
|
{
|
||||||
|
AmsInboundOrder order = buildDraftRequest();
|
||||||
|
when(sysCodeRuleService.nextCode("INBOUND_ORDER")).thenReturn("RK202606100001");
|
||||||
|
stubMasterData();
|
||||||
|
doAnswer(invocation -> {
|
||||||
|
AmsInboundOrder inserted = invocation.getArgument(0);
|
||||||
|
inserted.setOrderId(100L);
|
||||||
|
return 1;
|
||||||
|
}).when(amsInboundOrderMapper).insertAmsInboundOrder(any(AmsInboundOrder.class));
|
||||||
|
when(amsInboundOrderMapper.batchAmsInboundOrderItem(anyList()))
|
||||||
|
.thenAnswer(invocation -> ((List<?>) invocation.getArgument(0)).size());
|
||||||
|
|
||||||
|
int rows = service.insertAmsInboundOrder(order);
|
||||||
|
|
||||||
|
assertEquals(1, rows);
|
||||||
|
assertEquals(100L, order.getOrderId());
|
||||||
|
assertEquals("RK202606100001", order.getInboundNo());
|
||||||
|
assertEquals(InboundOrderStatus.DRAFT, order.getOrderStatus());
|
||||||
|
assertEquals("WH-002", order.getWarehouseCode());
|
||||||
|
assertEquals("二号仓", order.getWarehouseName());
|
||||||
|
AmsInboundOrderItem item = order.getAmsInboundOrderItemList().get(0);
|
||||||
|
assertEquals(100L, item.getOrderId());
|
||||||
|
assertEquals("ASSET-001", item.getAssetCode());
|
||||||
|
assertEquals("测试资产", item.getAssetName());
|
||||||
|
assertEquals("LOC-020", item.getLocationCode());
|
||||||
|
assertEquals(1, item.getInboundQuantity());
|
||||||
|
assertEquals("0", item.getDelFlag());
|
||||||
|
assertNotNull(item.getCreateTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 已完成入库单必须拒绝修改,避免绕过页面直接篡改单据。 */
|
||||||
|
@Test
|
||||||
|
void updateShouldRejectCompletedOrder()
|
||||||
|
{
|
||||||
|
AmsInboundOrder completed = new AmsInboundOrder();
|
||||||
|
completed.setOrderId(100L);
|
||||||
|
completed.setOrderStatus(InboundOrderStatus.INBOUND_DONE);
|
||||||
|
when(amsInboundOrderMapper.selectAmsInboundOrderByOrderIdForUpdate(100L)).thenReturn(completed);
|
||||||
|
|
||||||
|
AmsInboundOrder request = new AmsInboundOrder();
|
||||||
|
request.setOrderId(100L);
|
||||||
|
ServiceException exception = assertThrows(ServiceException.class,
|
||||||
|
() -> service.updateAmsInboundOrder(request));
|
||||||
|
|
||||||
|
assertTrue(exception.getMessage().contains("仅草稿"));
|
||||||
|
verify(amsInboundOrderMapper, never()).updateAmsInboundOrder(any(AmsInboundOrder.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 确认入库必须逐条调用公共状态流转服务,并完成单据确认信息。 */
|
||||||
|
@Test
|
||||||
|
void confirmShouldDelegateTransitionAndCompleteOrder()
|
||||||
|
{
|
||||||
|
AmsInboundOrder order = new AmsInboundOrder();
|
||||||
|
order.setOrderId(100L);
|
||||||
|
order.setInboundNo("RK202606100001");
|
||||||
|
order.setWarehouseId(2L);
|
||||||
|
order.setOrderStatus(InboundOrderStatus.DRAFT);
|
||||||
|
AmsInboundOrderItem item = new AmsInboundOrderItem();
|
||||||
|
item.setItemId(101L);
|
||||||
|
item.setAssetId(1L);
|
||||||
|
item.setLocationId(20L);
|
||||||
|
order.setAmsInboundOrderItemList(Collections.singletonList(item));
|
||||||
|
when(amsInboundOrderMapper.selectAmsInboundOrderByOrderIdForUpdate(100L)).thenReturn(order);
|
||||||
|
when(amsInboundOrderMapper.confirmAmsInboundOrder(any(AmsInboundOrder.class))).thenReturn(1);
|
||||||
|
|
||||||
|
int rows = service.confirmInbound(100L, 1L, "管理员", "admin");
|
||||||
|
|
||||||
|
assertEquals(1, rows);
|
||||||
|
ArgumentCaptor<AssetTransitionContext> contextCaptor = ArgumentCaptor.forClass(AssetTransitionContext.class);
|
||||||
|
verify(assetStatusTransitionService).confirmInbound(
|
||||||
|
org.mockito.ArgumentMatchers.eq(1L),
|
||||||
|
org.mockito.ArgumentMatchers.eq(2L),
|
||||||
|
org.mockito.ArgumentMatchers.eq(20L),
|
||||||
|
contextCaptor.capture());
|
||||||
|
assertEquals(100L, contextCaptor.getValue().getSourceOrderId());
|
||||||
|
assertEquals(101L, contextCaptor.getValue().getSourceItemId());
|
||||||
|
assertEquals("admin", contextCaptor.getValue().getOperateLoginName());
|
||||||
|
assertEquals(InboundOrderStatus.INBOUND_DONE, order.getOrderStatus());
|
||||||
|
assertEquals(1L, order.getInboundUserId());
|
||||||
|
assertEquals("管理员", order.getInboundUserName());
|
||||||
|
assertNotNull(order.getInboundTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 已完成入库单必须拒绝删除。 */
|
||||||
|
@Test
|
||||||
|
void deleteShouldRejectCompletedOrder()
|
||||||
|
{
|
||||||
|
AmsInboundOrder completed = new AmsInboundOrder();
|
||||||
|
completed.setOrderId(100L);
|
||||||
|
completed.setOrderStatus(InboundOrderStatus.INBOUND_DONE);
|
||||||
|
when(amsInboundOrderMapper.selectAmsInboundOrderByOrderIdForUpdate(100L)).thenReturn(completed);
|
||||||
|
|
||||||
|
ServiceException exception = assertThrows(ServiceException.class,
|
||||||
|
() -> service.deleteAmsInboundOrderByOrderId(100L));
|
||||||
|
|
||||||
|
assertTrue(exception.getMessage().contains("仅草稿"));
|
||||||
|
verify(amsInboundOrderMapper, never()).deleteAmsInboundOrderByOrderId(100L);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AmsInboundOrder buildDraftRequest()
|
||||||
|
{
|
||||||
|
AmsInboundOrder order = new AmsInboundOrder();
|
||||||
|
order.setWarehouseId(2L);
|
||||||
|
order.setCreateBy("admin");
|
||||||
|
AmsInboundOrderItem item = new AmsInboundOrderItem();
|
||||||
|
item.setAssetId(1L);
|
||||||
|
item.setLocationId(20L);
|
||||||
|
order.setAmsInboundOrderItemList(Collections.singletonList(item));
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stubMasterData()
|
||||||
|
{
|
||||||
|
AmsWarehouse warehouse = new AmsWarehouse();
|
||||||
|
warehouse.setWarehouseId(2L);
|
||||||
|
warehouse.setWarehouseCode("WH-002");
|
||||||
|
warehouse.setWarehouseName("二号仓");
|
||||||
|
warehouse.setEnabled("Y");
|
||||||
|
when(amsWarehouseService.selectAmsWarehouseByWarehouseId(2L)).thenReturn(warehouse);
|
||||||
|
|
||||||
|
AmsAsset asset = new AmsAsset();
|
||||||
|
asset.setAssetId(1L);
|
||||||
|
asset.setAssetCode("ASSET-001");
|
||||||
|
asset.setAssetName("测试资产");
|
||||||
|
asset.setCategoryId(3L);
|
||||||
|
asset.setCategoryCode("CAT-003");
|
||||||
|
asset.setCategoryName("测试类别");
|
||||||
|
asset.setSpecModel("SPEC-001");
|
||||||
|
asset.setBrand("测试品牌");
|
||||||
|
asset.setAssetStatus(AssetStatus.IN_STOCK);
|
||||||
|
when(amsAssetService.selectAmsAssetByAssetId(1L)).thenReturn(asset);
|
||||||
|
|
||||||
|
AmsAssetLocation location = new AmsAssetLocation();
|
||||||
|
location.setLocationId(20L);
|
||||||
|
location.setWarehouseId(2L);
|
||||||
|
location.setLocationCode("LOC-020");
|
||||||
|
location.setLocationName("二号仓A区");
|
||||||
|
location.setEnabled("Y");
|
||||||
|
when(amsAssetLocationService.selectAmsAssetLocationByLocationId(20L)).thenReturn(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue