feat(stock): 新增入库记录修改功能并优化库存管理
- 添加入库记录修改接口支持
- 在导出数据中增加批号和仓库名称字段
- 修复入库记录导出时类型判断逻辑错误
- 优化库存盘点计划详情查询,增加仓库信息关联
- 完善库存查询SQL,支持按批次和仓库分组统计
- 修复出库记录导出数据结构问题
- 优化不合格品库存转移逻辑,完善仓库信息传递
| | |
| | | return AjaxResult.success(stockInRecordService.batchDeletePending(ids)); |
| | | } |
| | | |
| | | @PutMapping("{id}") |
| | | @Operation(summary = "修改入库记录") |
| | | public AjaxResult update(@PathVariable Long id, @RequestBody StockInRecordDto stockInRecordDto){ |
| | | return AjaxResult.success(stockInRecordService.update(id,stockInRecordDto)); |
| | | } |
| | | |
| | | |
| | | |
| | | @PostMapping("/exportStockInRecord") |
| | | @Operation(summary = "导出入库记录") |
| | | public void exportStockInRecord(HttpServletResponse response, StockInRecordDto stockInRecordDto) { |
| | |
| | | private String model; |
| | | @Excel(name = "单位") |
| | | private String unit; |
| | | @Excel(name = "批号") |
| | | private String batchNo; |
| | | @Excel(name = "仓库名称") |
| | | private String warehouseName; |
| | | @Excel(name = "入库来源") |
| | | private String recordType; |
| | | @Excel(name = "入库数量") |
| | | private String stockInNum; |
| | | @Excel(name = "入库时间") |
| | | @Excel(name = "入库时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime createTime; |
| | |
| | | private String model; |
| | | @Excel(name = "单位") |
| | | private String unit; |
| | | @Excel(name = "批号") |
| | | private String batchNo; |
| | | @Excel(name = "仓库名称") |
| | | private String warehouseName; |
| | | @Excel(name = "出库来源") |
| | | private String recordType; |
| | | @Excel(name = "出库数量") |
| | | private String stockInNum; |
| | | @Excel(name = "出库时间") |
| | | private String stockOutNum; |
| | | @Excel(name = "出库时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime createTime; |
| | |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private LocalDateTime updateTime; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | @TableField(exist = false) |
| | | private String warehouseName; |
| | | private Long deptId; |
| | | } |
| | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | |
| | | private Long warehouseInfoId; |
| | | |
| | | } |
| | |
| | | public void exportStockInRecord(HttpServletResponse response, StockInRecordDto stockInRecordDto) { |
| | | List<StockInRecordExportData> list = stockInRecordMapper.listStockInRecordExportData(stockInRecordDto); |
| | | for (StockInRecordExportData stockInRecordExportData : list) { |
| | | if (stockInRecordExportData.getType().equals("0")) { |
| | | if (!stockInRecordExportData.getType().equals("0")) { |
| | | stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockOutQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue()); |
| | | }else { |
| | | stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockInQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue()); |
| | |
| | | import com.ruoyi.stock.mapper.StockInventoryCheckItemMapper; |
| | | import com.ruoyi.stock.mapper.StockInventoryCheckPlanMapper; |
| | | import com.ruoyi.stock.mapper.StockInventoryCheckProductMapper; |
| | | import com.ruoyi.stock.mapper.WarehouseInfoMapper; |
| | | import com.ruoyi.stock.pojo.*; |
| | | import com.ruoyi.stock.service.*; |
| | | import lombok.RequiredArgsConstructor; |
| | |
| | | private final StockUtils stockUtils; |
| | | private final StockInRecordService stockInRecordService; |
| | | private final StockOutRecordService stockOutRecordService; |
| | | private final WarehouseInfoMapper warehouseInfoMapper; |
| | | |
| | | @Override |
| | | public IPage<StockInventoryCheckPlanDto> listPage(Page page, StockInventoryCheckPlanDto stockInventoryCheckPlanDto) { |
| | |
| | | |
| | | @Override |
| | | public StockInventoryCheckPlanDto detail(Long id) { |
| | | //查询仓库 |
| | | List<WarehouseInfo> warehouseInfos = warehouseInfoMapper.selectList(null); |
| | | |
| | | StockInventoryCheckPlan byId = this.getById(id); |
| | | if (byId == null) { |
| | | return null; |
| | |
| | | List<StockInventoryCheckItem> checkItems = stockInventoryCheckItemMapper.selectList( |
| | | new LambdaQueryWrapper<StockInventoryCheckItem>() |
| | | .eq(StockInventoryCheckItem::getMainId, checkMain.getId())); |
| | | checkItems.stream().forEach(item -> { |
| | | item.setWarehouseName(warehouseInfos.stream().filter(warehouseInfo -> warehouseInfo.getId().equals(item.getWarehouseInfoId())).findFirst().get().getWarehouseName()); |
| | | }); |
| | | stockInventoryCheckPlanDto.setCheckItems(checkItems); |
| | | } |
| | | |
| | |
| | | import com.ruoyi.stock.dto.StockUninventoryDto; |
| | | import com.ruoyi.stock.execl.StockUnInventoryExportData; |
| | | import com.ruoyi.stock.mapper.StockUninventoryMapper; |
| | | import com.ruoyi.stock.pojo.StockInventory; |
| | | import com.ruoyi.stock.pojo.StockUninventory; |
| | | import com.ruoyi.stock.service.StockInRecordService; |
| | | import com.ruoyi.stock.service.StockOutRecordService; |
| | | import com.ruoyi.stock.service.StockUninventoryService; |
| | | import lombok.AllArgsConstructor; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | |
| | | stockInRecordDto.setStockInNum(stockUninventoryDto.getQualitity()); |
| | | stockInRecordDto.setBatchNo(stockUninventoryDto.getBatchNo()); |
| | | stockInRecordDto.setProductModelId(stockUninventoryDto.getProductModelId()); |
| | | stockInRecordDto.setWarehouseInfoId(stockUninventoryDto.getWarehouseInfoId()); |
| | | stockInRecordDto.setType("1"); |
| | | stockInRecordService.add(stockInRecordDto); |
| | | //再进行新增库存数量库存 |
| | |
| | | newStockUnInventory.setQualitity(stockUninventoryDto.getQualitity()); |
| | | newStockUnInventory.setLockedQuantity(stockUninventoryDto.getLockedQuantity()); |
| | | newStockUnInventory.setBatchNo(stockUninventoryDto.getBatchNo()); |
| | | newStockUnInventory.setWarehouseInfoId(stockUninventoryDto.getWarehouseInfoId()); |
| | | newStockUnInventory.setVersion(1); |
| | | newStockUnInventory.setRemark(stockUninventoryDto.getRemark()); |
| | | stockUninventoryMapper.insert(newStockUnInventory); |
| | |
| | | p.product_name as product_name, |
| | | pm.model, |
| | | pm.unit, |
| | | u.nick_name as createBy |
| | | u.nick_name as createBy, |
| | | swi.warehouse_name |
| | | FROM stock_in_record as sir |
| | | LEFT JOIN product_model as pm on sir.product_model_id = pm.id |
| | | LEFT JOIN product as p on pm.product_id = p.id |
| | | LEFT JOIN sys_user as u on sir.create_user = u.user_id |
| | | left join stock_warehouse_info swi on swi.id = sir.warehouse_info_id |
| | | <where> |
| | | <if test="params.timeStr != null and params.timeStr != ''"> |
| | | and sir.create_time like concat('%',#{params.timeStr},'%') |
| | |
| | | <id column="id" property="id" /> |
| | | <result column="check_no" property="checkNo" /> |
| | | <result column="check_type" property="checkType" /> |
| | | <result column="warehouse_id" property="warehouseId" /> |
| | | <result column="warehouse_name" property="warehouseName" /> |
| | | <result column="total_quantity" property="totalQuantity" /> |
| | | <result column="total_amount" property="totalAmount" /> |
| | | <result column="source_type" property="sourceType" /> |
| | | <result column="source_id" property="sourceId" /> |
| | | <result column="status" property="status" /> |
| | |
| | | <result column="responsible_person_name" property="responsiblePersonName" /> |
| | | <result column="remark" property="remark" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | </resultMap> |
| | | |
| | | </mapper> |
| | |
| | | and plan_no like concat('%',#{ew.planNo},'%') |
| | | </if> |
| | | <if test="ew.status != null"> |
| | | and status = #{ew.status} |
| | | and stock_inventory_check_plan.status = #{ew.status} |
| | | </if> |
| | | <if test="ew.startTime != null"> |
| | | and plan_date_start between #{ew.startTime} and #{ew.endTime} |
| | |
| | | INNER JOIN product_tree pt ON p.parent_id = pt.id |
| | | ) |
| | | select |
| | | SUM(qualifiedQuantity) as qualifiedQuantity, |
| | | SUM(unQualifiedQuantity) as unQualifiedQuantity, |
| | | SUM(qualifiedLockedQuantity) as qualifiedLockedQuantity, |
| | | SUM(unQualifiedLockedQuantity) as unQualifiedLockedQuantity, |
| | | model, |
| | | unit, |
| | | product_name, |
| | | MAX(warn_num) as warn_num, |
| | | MAX(remark) as remark, |
| | | MAX(update_time) as update_time |
| | | batch_no, |
| | | MAX(qualifiedId) as qualifiedId, |
| | | MAX(unQualifiedId) as unQualifiedId, |
| | | SUM(qualifiedQuantity) as qualifiedQuantity, |
| | | SUM(unQualifiedQuantity) as unQualifiedQuantity, |
| | | SUM(qualifiedLockedQuantity) as qualifiedLockedQuantity, |
| | | SUM(unQualifiedLockedQuantity) as unQualifiedLockedQuantity, |
| | | SUM(qualifiedQuantity - qualifiedLockedQuantity - IFNULL(qualifiedPendingOut, 0)) as qualifiedUnLockedQuantity, |
| | | SUM(unQualifiedQuantity - unQualifiedLockedQuantity - IFNULL(unQualifiedPendingOut, 0)) as unQualifiedUnLockedQuantity, |
| | | SUM(IFNULL(qualifiedPendingOut, 0)) as qualifiedPendingOutQuantity, |
| | | SUM(IFNULL(unQualifiedPendingOut, 0)) as unQualifiedPendingOutQuantity, |
| | | product_model_id, |
| | | warehouse_info_id, |
| | | warehouse_name, |
| | | MAX(create_time) as create_time, |
| | | MAX(update_time) as update_time, |
| | | MAX(warn_num) as warn_num, |
| | | MAX(version) as version, |
| | | model, |
| | | MAX(remark) as remark, |
| | | unit, |
| | | product_name, |
| | | product_id, |
| | | 'combined' as stockType |
| | | from ( |
| | | select |
| | | si.qualitity as qualifiedQuantity, |
| | | 0 as unQualifiedQuantity, |
| | | COALESCE(si.locked_quantity, 0) as qualifiedLockedQuantity, |
| | | 0 as unQualifiedLockedQuantity, |
| | | si.product_model_id, |
| | | si.create_time, |
| | | si.update_time, |
| | | COALESCE(si.warn_num, 0) as warn_num, |
| | | si.remark, |
| | | pm.model, |
| | | pm.unit, |
| | | p.product_name, |
| | | p.id as product_id |
| | | from stock_inventory si |
| | | left join product_model pm on si.product_model_id = pm.id |
| | | left join product p on pm.product_id = p.id |
| | | select |
| | | si.batch_no, |
| | | si.id as qualifiedId, |
| | | null as unQualifiedId, |
| | | si.qualitity as qualifiedQuantity, |
| | | 0 as unQualifiedQuantity, |
| | | COALESCE(si.locked_quantity, 0) as locked_quantity, |
| | | COALESCE(si.locked_quantity, 0) as qualifiedLockedQuantity, |
| | | 0 as unQualifiedLockedQuantity, |
| | | si.product_model_id, |
| | | si.warehouse_info_id, |
| | | siw.warehouse_name, |
| | | si.create_time, |
| | | si.update_time, |
| | | COALESCE(si.warn_num, 0) as warn_num, |
| | | si.version, |
| | | (si.qualitity - COALESCE(si.locked_quantity, 0)) as un_locked_quantity, |
| | | pm.model, |
| | | si.remark, |
| | | pm.unit, |
| | | p.product_name, |
| | | p.id as product_id, |
| | | ( |
| | | select IFNULL(SUM(sor.stock_out_num), 0) |
| | | from stock_out_record sor |
| | | where sor.product_model_id = si.product_model_id |
| | | and sor.warehouse_info_id = si.warehouse_info_id |
| | | and (si.batch_no is null and sor.batch_no is null or si.batch_no = sor.batch_no) |
| | | and sor.type = '0' |
| | | and sor.approval_status = 0 |
| | | ) as qualifiedPendingOut, |
| | | 0 as unqualifiedPendingOut |
| | | from stock_inventory si |
| | | left join product_model pm on si.product_model_id = pm.id |
| | | left join product p on pm.product_id = p.id |
| | | left join stock_warehouse_info siw on si.warehouse_info_id = siw.id |
| | | |
| | | union all |
| | | union all |
| | | |
| | | select |
| | | 0 as qualifiedQuantity, |
| | | su.qualitity as unQualifiedQuantity, |
| | | 0 as qualifiedLockedQuantity, |
| | | COALESCE(su.locked_quantity, 0) as unQualifiedLockedQuantity, |
| | | su.product_model_id, |
| | | su.create_time, |
| | | su.update_time, |
| | | 0 as warn_num, |
| | | su.remark, |
| | | pm.model, |
| | | pm.unit, |
| | | p.product_name, |
| | | p.id as product_id |
| | | from stock_uninventory su |
| | | left join product_model pm on su.product_model_id = pm.id |
| | | left join product p on pm.product_id = p.id |
| | | select |
| | | su.batch_no, |
| | | null as qualifiedId, |
| | | su.id as unQualifiedId, |
| | | 0 as qualifiedQuantity, |
| | | su.qualitity as unQualifiedQuantity, |
| | | COALESCE(su.locked_quantity, 0) as locked_quantity, |
| | | 0 as qualifiedLockedQuantity, |
| | | COALESCE(su.locked_quantity, 0) as unQualifiedLockedQuantity, |
| | | su.product_model_id, |
| | | null as warehouse_info_id, |
| | | null as warehouse_name, |
| | | su.create_time, |
| | | su.update_time, |
| | | 0 as warn_num, |
| | | su.version, |
| | | (su.qualitity - COALESCE(su.locked_quantity, 0)) as un_locked_quantity, |
| | | pm.model, |
| | | su.remark, |
| | | pm.unit, |
| | | p.product_name, |
| | | p.id as product_id, |
| | | 0 as qualifiedPendingOut, |
| | | ( |
| | | select IFNULL(SUM(sor.stock_out_num), 0) |
| | | from stock_out_record sor |
| | | where sor.product_model_id = su.product_model_id |
| | | and (su.batch_no is null and sor.batch_no is null or su.batch_no = sor.batch_no) |
| | | and sor.type = '1' |
| | | and sor.approval_status = 0 |
| | | ) as unqualifiedPendingOut |
| | | from stock_uninventory su |
| | | left join product_model pm on su.product_model_id = pm.id |
| | | left join product p on pm.product_id = p.id |
| | | ) as combined |
| | | <where> |
| | | <if test="ew.productName != null and ew.productName !=''"> |
| | |
| | | and combined.product_id in (select id from product_tree) |
| | | </if> |
| | | </where> |
| | | group by product_model_id, model, unit, product_name |
| | | group by batch_no, product_model_id, warehouse_info_id, warehouse_name, model, unit, product_name, product_id |
| | | </select> |
| | | <select id="stockInventoryPage" resultType="com.ruoyi.stock.dto.StockInRecordDto"> |
| | | select sir.*,si.qualitity as current_stock, |
| | |
| | | p.product_name as productName, |
| | | pm.model, |
| | | pm.unit, |
| | | u.nick_name as createBy |
| | | u.nick_name as createBy, |
| | | swi.warehouse_name |
| | | FROM stock_out_record as sor |
| | | LEFT JOIN product_model as pm on sor.product_model_id = pm.id |
| | | LEFT JOIN product as p on pm.product_id = p.id |
| | | LEFT JOIN sys_user as u on sor.create_user = u.user_id |
| | | left join stock_warehouse_info as swi on sor.warehouse_info_id = swi.id |
| | | <where> |
| | | <if test="params.timeStr != null and params.timeStr != ''"> |
| | | and sor.create_time like concat('%',#{params.timeStr},'%') |