add:增加仓储服务,增加需求单至出库单流程

This commit is contained in:
zhangzq
2026-06-08 08:45:53 +08:00
parent ec9fce406c
commit 854a1714fe
45 changed files with 817 additions and 288 deletions

View File

@@ -1,4 +1,4 @@
package org.nl.common.domain.constantt;
package org.nl.common.domain.constant;
/**
* s

View File

@@ -49,9 +49,9 @@ import java.util.stream.Collectors;
public class GroupController {
@Autowired
private final IMdPbGroupplateService iMdPbGroupplateService;
private IMdPbGroupplateService iMdPbGroupplateService;
@Autowired
private final IMdPbStoragevehicleinfoService iMdPbStoragevehicleinfoService;
private IMdPbStoragevehicleinfoService iMdPbStoragevehicleinfoService;
@Autowired
private final MdPbGroupplateMapper mdPbGroupplateMapper;

View File

@@ -3,6 +3,7 @@ package org.nl.wms.basedata_manage.service.dao;
import lombok.Data;
import org.nl.wms.warehouse_manage.service.dao.GroupPlate;
import java.io.Serializable;
import java.math.BigDecimal;
/*
@@ -10,7 +11,7 @@ import java.math.BigDecimal;
* @Date 2023/5/4 19:49
*/
@Data
public class StructattrVechielDto extends GroupPlate {
public class StructattrVechielDto implements Serializable {
private static final long serialVersionUID = 1L;
/**
@@ -22,6 +23,8 @@ public class StructattrVechielDto extends GroupPlate {
* 仓位编码
*/
private String struct_code;
private String lock_type;
/**
* 库区标识
*/
@@ -31,70 +34,8 @@ public class StructattrVechielDto extends GroupPlate {
*/
private String stor_code;
/**
* 宽度
*/
private Integer w;
/**
* 高度
*/
private Integer h;
/**
* 深度(长度)
*/
private Integer l;
/**
* 承受重量
*/
private Integer weight;
/**
* 排
*/
private Integer row_num;
/**
* 列
*/
private Integer col_num;
/**
* 层
*/
private Integer layer_num;
/**
* 块
*/
private Integer block_num;
/**
* 超限货位关联的货位编号
*/
private String control_code;
/**
* 是否临时仓位
*/
private Boolean is_temp;
/**
* 是否启用
*/
private Boolean is_used;
/**
* 锁定类型
*/
private String lock_type;
/**
* 是否判断高度
*/
private String is_zdepth;
private String group_id;
/**
* 存储载具号
@@ -106,11 +47,29 @@ public class StructattrVechielDto extends GroupPlate {
*/
private String material_code;
/**
* 物料名称
*/
private String material_name;
private String material_id;
private String pcsn;
private BigDecimal qty;
private BigDecimal frozen_qty;
private String qty_unit_name;
private String qty_unit_id;
/**
* 来源单据号
*/
private String ext_code;
/**
* 来源单据类型
*/
private String ext_type;

View File

@@ -4,9 +4,9 @@
<select id="getCanuseIvt" resultType="com.alibaba.fastjson.JSONObject">
SELECT
ext.group_id as storagevehicleext_id,
ext.group_id,
ext.storagevehicle_code,
ext.material_id,
ext.material_code,
material.material_code,
material.material_name,
ext.pcsn,
@@ -318,7 +318,7 @@
ext.pcsn LIKE #{param.pcsn}
</if>
<if test="param.material_id_list != null and param.material_id_list.size() > 0">
AND ext.material_id in
AND ext.material_code in
<foreach collection="param.material_id_list" item="value" index="key" open="(" close=")" separator=",">
#{value}
</foreach>

View File

@@ -8,19 +8,22 @@
gro.create_time,
gro.qty_unit_name,
gro.qty_unit_id,
gro.material_id,
gro.material_code,
gro.pcsn,
gro.group_id,
gro.ext_code,
gro.ext_type,
gro.group_id,
mater.material_code,
gro.storagevehicle_code,
mater.material_id,
mater.material_name,
ivt.*
ivt.struct_code,
ivt.struct_id,
ivt.struct_name,
ivt.sect_code,
ivt.stor_code,
ivt.lock_type
FROM
st_ivt_structattr ivt
LEFT JOIN md_pb_groupplate gro ON ivt.storagevehicle_code = gro.storagevehicle_code
LEFT JOIN md_me_materialbase mater ON mater.material_id = gro.material_id
LEFT JOIN md_me_materialbase mater ON mater.material_code = gro.material_code
<where>
<if test="search != null and search != ''">
and (mater.material_code LIKE '%${search}%'
@@ -29,8 +32,8 @@
<if test="status != null and status != ''">
AND gro.status = #{status}
</if>
<if test="material_id != null and material_id != ''">
AND gro.material_id = #{material_id}
<if test="material_code != null and material_code != ''">
AND gro.material_code = #{material_code}
</if>
<if test="pcsn != null and pcsn != ''">
AND gro.pcsn = #{pcsn}

View File

@@ -1,5 +1,8 @@
package org.nl.wms.ext_manage.enums;
import java.util.Arrays;
import java.util.List;
/**
* @author Liuyx
* @date 2025年06月03日
@@ -26,4 +29,7 @@ public class EXTConstant {
* 中鼎查询库存接口地址
*/
public final static String QUERY_INVENTORY_ZD_API = "/app/restful/api/v3/wms/getInventoryList";
public static final List<String> ZD_STOR_SET = Arrays.asList("6001");
}

View File

@@ -2,6 +2,7 @@ package org.nl.wms.ext_manage.service;
import com.alibaba.fastjson.JSONObject;
import org.nl.wms.ext_manage.service.dto.ZDInventory;
import org.nl.wms.pm_manage.demand.service.dto.PmDemandDto;
import org.springframework.http.ResponseEntity;
import java.util.List;
@@ -18,15 +19,13 @@ public interface WmsToZDWmdService {
/**
* 生产领料需求单下发
* @param whereJson {
* data []
* }
* @return JSONObject {
* status: 200 / !=200
* message 信息
* }
*
* @param demands@return JSONObject {
* status: 200 / !=200
* message 信息
* }
*/
ResponseEntity syncDemandOrder(JSONObject whereJson);
ResponseEntity syncDemandOrder(List<PmDemandDto> demands);
/**
* 采购入库单下发

View File

@@ -126,7 +126,7 @@ public class ErpToWmsServiceImpl implements ErpToWmsService {
}
jsonMst.put("tableData",dtlArr);
// 调用出库单新增服务
iOutBillService.insertDtl(jsonMst);
iOutBillService.saveBill(jsonMst);
log.info("sendTask下发出库任务接口输出参数为-------------------" + ErpResponse.requestOk().toString());
return ErpResponse.requestOk();

View File

@@ -1,6 +1,7 @@
package org.nl.wms.ext_manage.service.impl;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
@@ -9,6 +10,7 @@ import org.nl.config.SpringContextHolder;
import org.nl.wms.ext_manage.enums.EXTConstant;
import org.nl.wms.ext_manage.service.WmsToZDWmdService;
import org.nl.wms.ext_manage.service.dto.ZDInventory;
import org.nl.wms.pm_manage.demand.service.dto.PmDemandDto;
import org.nl.wms.system_manage.enums.SysParamConstant;
import org.nl.wms.system_manage.service.param.dao.Param;
import org.nl.wms.system_manage.service.param.impl.SysParamServiceImpl;
@@ -16,20 +18,20 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
@Slf4j
public class WmsToZDWmdServiceImpl implements WmsToZDWmdService {
@Override
public ResponseEntity syncDemandOrder(JSONObject whereJson) {
log.info("syncDemandOrder生产领料需求单下发输入参数-------------------" + whereJson.toString());
public ResponseEntity syncDemandOrder(List<PmDemandDto> demands) {
log.info("syncDemandOrder生产领料需求单下发输入参数-------------------" + demands.size());
String url = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode(SysParamConstant.ZD_URL).getValue();
// TODO: add demand order API path to EXTConstant once endpoint is confirmed
try {
String resultMsg = HttpRequest.post(url)
.body(whereJson.toString())
.body(JSONArray.parseArray(JSON.toJSONString(demands)).toJSONString())
.execute().body();
JSONObject result = JSONObject.parseObject(resultMsg);
log.info("syncDemandOrder需求单下发输出参数-------------------" + result.toString());
@@ -58,10 +60,12 @@ public class WmsToZDWmdServiceImpl implements WmsToZDWmdService {
@Override
public ResponseEntity<List<ZDInventory>> queryInventory(String skuCode) {
List<ZDInventory> inventorys = new ArrayList<>();
log.info("queryInventory查询SKU库存输入参数skuCode={}", skuCode);
Param param = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode(SysParamConstant.ZD_URL);
if (param==null){
throw new BadRequestException("查询中鼎库存失败,接口地址未配置");
return new ResponseEntity<>(inventorys, HttpStatus.OK);
// throw new BadRequestException("查询中鼎库存失败,接口地址未配置");
}
String baseUrl = param.getValue();
String url = baseUrl + EXTConstant.QUERY_INVENTORY_ZD_API;
@@ -83,7 +87,7 @@ public class WmsToZDWmdServiceImpl implements WmsToZDWmdService {
if (respCode == null || respCode != 0) {
throw new BadRequestException("中鼎库存查询失败:" + result.getString("respMsg"));
}
List<ZDInventory> inventorys = result.getJSONArray("data").toJavaList(ZDInventory.class);
inventorys = result.getJSONArray("data").toJavaList(ZDInventory.class);
return new ResponseEntity<>(inventorys, HttpStatus.OK);
} catch (BadRequestException e) {
throw e;

View File

@@ -149,13 +149,6 @@ public class PdaIosOutServiceImpl implements PdaIosOutService {
private PdaPointTask pdaPointTask;
/**
* 入库服务服务
*/
@Autowired
private IInBillService iRawAssistIStorService;
@Override
public PdaResponse getDtl(JSONObject whereJson) {
return PdaResponse.requestParamOk(mdPbStoragevehicleextMapper.getIosDtl(whereJson));

View File

@@ -62,6 +62,7 @@ public class PmDemandController {
return new ResponseEntity<>(pmDemandService.queryInventory(skuCode), HttpStatus.OK);
}
@PostMapping("/allocate")
@Log("库存分配")
@Transactional(rollbackFor = Exception.class)
@@ -73,7 +74,8 @@ public class PmDemandController {
@PostMapping("/push")
@Log("需求单下发")
@Transactional(rollbackFor = Exception.class)
public ResponseEntity<Object> push(@RequestBody PmDemandDto pmDemandDto) {
public ResponseEntity<Object> push(@RequestBody List<PmDemandDto> pmDemandDtos) {
pmDemandService.pushDemand(pmDemandDtos);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -44,5 +44,5 @@ public interface IPmDemandService extends IService<PmDemand> {
* 4。当前
* @param pmDemandDto
*/
void pushDemand(PmDemandDto pmDemandDto);
void pushDemand(List<PmDemandDto> pmDemandDto);
}

View File

@@ -28,7 +28,7 @@ public class PmDemand extends Model<PmDemand> {
private Integer priority;
private Integer status;
private String status;
@TableField("work_order")
private String work_order;

View File

@@ -11,4 +11,5 @@ public class DemandInventryDto {
private BigDecimal qty;
private String houseCode;
private String houseName;
private String unitId;
}

View File

@@ -3,20 +3,21 @@ package org.nl.wms.pm_manage.demand.service.dto;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
public class PmDemandDto {
public class PmDemandDto implements Serializable {
private String id;
private String creator;
private String createTime;
private Integer priority;
private Integer status;
private String status;
private String workOrder;
private String skuCode;
private String skuName;
private BigDecimal qty;
private Integer qty;
private String unit;
private String targetArea;
private String productionLine;

View File

@@ -35,7 +35,7 @@ public class PmDemandParam {
private Integer priority;
@JsonProperty("Status")
private Integer status;
private String status;
@NotBlank(message = "工单编号不能为空")
@JsonProperty("WorkOrder")

View File

@@ -0,0 +1,18 @@
package org.nl.wms.pm_manage.demand.service.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum DemandStatus {
CREATE("0","生成"),
DIS("01","分配"),
SEND("10","下发"),
RUN("20","执行"),
FINISH("80","完成"),
CANCEL("90","取消"),
;
private String value;
private String desc;
}

View File

@@ -1,12 +1,20 @@
package org.nl.wms.pm_manage.demand.service.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.domain.query.PageQuery;
import org.nl.common.exception.BadRequestException;
import org.nl.wms.basedata_manage.service.IMdMeMaterialbaseService;
import org.nl.wms.basedata_manage.service.IMdPbMeasureunitService;
import org.nl.wms.basedata_manage.service.dao.MdMeMaterialbase;
import org.nl.wms.basedata_manage.service.dao.MdPbMeasureunit;
import org.nl.wms.ext_manage.enums.EXTConstant;
import org.nl.wms.ext_manage.service.WmsToZDWmdService;
import org.nl.wms.ext_manage.service.dto.ZDInventory;
import org.nl.wms.pm_manage.demand.service.IPmDemandService;
@@ -16,6 +24,8 @@ import org.nl.wms.pm_manage.demand.service.dto.DemandInventryDto;
import org.nl.wms.pm_manage.demand.service.dto.PmDemandDto;
import org.nl.wms.pm_manage.demand.service.dto.PmDemandParam;
import org.nl.wms.pm_manage.demand.service.dto.PmDemandQuery;
import org.nl.wms.pm_manage.demand.service.enums.DemandStatus;
import org.nl.wms.warehouse_manage.inAndOut.service.IOutBillService;
import org.nl.wms.warehouse_manage.inventory.IStInventoryService;
import org.nl.wms.warehouse_manage.inventory.dto.StInventoryDto;
import org.nl.wms.warehouse_manage.inventory.dto.StInventoryQuery;
@@ -25,7 +35,11 @@ import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.nl.common.domain.query.PageQuery.trimStringFields;
@@ -36,6 +50,12 @@ public class PmDemandServiceImpl extends ServiceImpl<PmDemandMapper, PmDemand> i
private IStInventoryService iStInventoryService;
@Autowired
private WmsToZDWmdService wmsToZDWmdService;
@Autowired
private IOutBillService iOutBillService;
@Autowired
private IMdMeMaterialbaseService iMdMeMaterialbaseService;
@Autowired
private IMdPbMeasureunitService iMdPbMeasureunitService;
@Override
public Page<PmDemandDto> queryPage(PmDemandQuery query, PageQuery pageQuery) {
@@ -115,7 +135,7 @@ public class PmDemandServiceImpl extends ServiceImpl<PmDemandMapper, PmDemand> i
throw new BadRequestException("需求单不存在");
}
demand.setInventory_dis(inventoryDis);
demand.setStatus(1);
demand.setStatus(DemandStatus.DIS.getValue());
this.updateById(demand);
}
@@ -129,7 +149,8 @@ public class PmDemandServiceImpl extends ServiceImpl<PmDemandMapper, PmDemand> i
demandDto.setSkuCode(dto.getMaterialCode());
demandDto.setSkuName(dto.getMaterialName());
demandDto.setQty(dto.getQty());
demandDto.setHouseCode(dto.getStructCode());
demandDto.setHouseCode(dto.getStorCode());
demandDto.setHouseName(dto.getStorName());
demandDto.setHouseName(dto.getStorName());
resultList.add(demandDto);
}
@@ -152,7 +173,74 @@ public class PmDemandServiceImpl extends ServiceImpl<PmDemandMapper, PmDemand> i
@Override
public void pushDemand(PmDemandDto pmDemandDto) {
public void pushDemand(List<PmDemandDto> pmDemandDtos) {
if (CollectionUtils.isEmpty(pmDemandDtos)){
throw new BadRequestException("下推失败,请求数据不能为空");
}
final long count = pmDemandDtos.stream().filter(a -> !a.getStatus().equals("01")).count();
if (count>0){
throw new BadRequestException("下推失败,单据状态不为已分配不能下推");
}
// 一次性分成两组
Map<Boolean, List<PmDemandDto>> partitioned = pmDemandDtos.stream()
.collect(Collectors.partitioningBy(a -> EXTConstant.ZD_STOR_SET
.contains(JSONObject.parseObject(a.getInventoryDis()).getString("horseCode"))));
List<PmDemandDto> zdDemands = partitioned.get(true);
List<PmDemandDto> otherDemands = partitioned.get(false);
if (!CollectionUtils.isEmpty(zdDemands)) {
wmsToZDWmdService.syncDemandOrder(zdDemands);
}
if (!CollectionUtils.isEmpty(otherDemands)) {
JSONObject billParam = convertDemandsToBillParam(otherDemands);
iOutBillService.saveBill(billParam);
this.update(new LambdaUpdateWrapper<PmDemand>()
.set(PmDemand::getStatus,DemandStatus.SEND.getValue())
.in(PmDemand::getId,pmDemandDtos.stream()
.map(PmDemandDto::getId).collect(Collectors.toList())));
}
}
private JSONObject convertDemandsToBillParam(List<PmDemandDto> demands) {
if (CollectionUtils.isEmpty(demands)) {
throw new BadRequestException("需求单数据为空");
}
PmDemandDto firstDemand = demands.get(0);
JSONObject inventoryDis = JSONObject.parseObject(firstDemand.getInventoryDis());
JSONObject billParam = new JSONObject();
billParam.put("stor_code", inventoryDis.getString("horseCode"));
billParam.put("biz_date", DateUtil.today());
billParam.put("bill_type", "010201");
billParam.put("remark", "需求单下推生成");
List<JSONObject> tableData = new ArrayList<>();
//查询物料id;
final List<MdMeMaterialbase> materialbases = iMdMeMaterialbaseService
.list(new LambdaQueryWrapper<MdMeMaterialbase>()
.in(MdMeMaterialbase::getMaterial_code,
demands.stream().map(PmDemandDto::getSkuCode).collect(Collectors.toList()))
.select(MdMeMaterialbase::getQty_unit_id,MdMeMaterialbase::getMaterial_id, MdMeMaterialbase::getMaterial_code));
Map<String, MdMeMaterialbase> codeToIdMap = materialbases.stream()
.collect(Collectors.toMap(
MdMeMaterialbase::getMaterial_code, Function.identity()));
for (PmDemandDto demand : demands) {
JSONObject detailRow = new JSONObject();
detailRow.put("material_code", demand.getSkuCode());
detailRow.put("material_id", codeToIdMap.get(demand.getSkuCode()).getMaterial_id());
detailRow.put("qty_unit_name", demand.getUnit());
detailRow.put("qty_unit_id", codeToIdMap.get(demand.getSkuCode()).getQty_unit_id());
detailRow.put("qty", demand.getQty());
detailRow.put("source_bill_code", demand.getWorkOrder());
detailRow.put("source_bill_type", "PM_DEMAND");
detailRow.put("source_billdtl_id", demand.getId());
detailRow.put("remark", "需求单:" + demand.getId());
tableData.add(detailRow);
}
billParam.put("tableData", tableData);
return billParam;
}
}

View File

@@ -54,7 +54,7 @@ public class OutBillController {
@PostMapping()
@Log("新增出库单")
public ResponseEntity<Object> insertDtl(@RequestBody JSONObject whereJson) {
iOutBillService.insertDtl(whereJson);
iOutBillService.saveBill(whereJson);
return new ResponseEntity<>(HttpStatus.CREATED);
}

View File

@@ -65,7 +65,7 @@ public interface IOutBillService extends IService<IOStorInv> {
* {bill_code=, stor_id=1473161852946092032, stor_code=01, stor_name=原材料库, bill_status=10, total_qty=2, detail_count=1, bill_type=010201, remark=, biz_date=2022-01-08, create_mode=, tableData=[{material_id=1309, material_code=090301010001, bill_status=10, material_name=碳化钨粉 02, pcsn=, quality_scode=02, ivt_level=01, is_active=1, plan_qty=2, qty_unit_name=千克\公斤, qty_unit_id=1, remark=, edit=true}]}
* /
*/
String insertDtl(JSONObject whereJson);
String saveBill(JSONObject whereJson);
/**
* 查询出库单明细

View File

@@ -22,4 +22,11 @@ public interface IOStorInvDisMapper extends BaseMapper<IOStorInvDis> {
//查询未出库单分配
List<IOStorInvDisDto> queryOutBillDisDtl(@Param("params") Map whereJson);
/**
* 批量插入分配明细
* @param list 分配明细列表
* @return 插入成功的记录数
*/
int batchSave(@Param("list") List<IOStorInvDis> list);
}

View File

@@ -47,7 +47,7 @@
LEFT JOIN sch_base_task task ON task.task_id = dis.task_id
LEFT JOIN md_pb_groupplate ext
ON ext.storagevehicle_code = dis.storagevehicle_code
and ext.material_id = dis.material_id and ext.pcsn = dis.pcsn
and ext.material_code = dis.material_code and ext.pcsn = dis.pcsn
where
1=1
<if test="params.iostorinvdtl_id != null">
@@ -60,4 +60,58 @@
</if>
</select>
<!-- 批量插入分配明细 -->
<insert id="batchSave" parameterType="list">
INSERT INTO st_ivt_iostorinvdis (
iostorinvdis_id,
iostorinv_id,
iostorinvdtl_id,
seq_no,
sect_id,
sect_code,
sect_name,
struct_id,
struct_code,
struct_name,
material_id,
material_code,
pcsn,
work_status,
task_id,
storagevehicle_code,
is_issued,
qty_unit_id,
qty_unit_name,
plan_qty,
real_qty,
point_code
) VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.iostorinvdis_id},
#{item.iostorinv_id},
#{item.iostorinvdtl_id},
#{item.seq_no},
#{item.sect_id},
#{item.sect_code},
#{item.sect_name},
#{item.struct_id},
#{item.struct_code},
#{item.struct_name},
#{item.material_id},
#{item.material_code},
#{item.pcsn},
#{item.work_status},
#{item.task_id},
#{item.storagevehicle_code},
#{item.is_issued},
#{item.qty_unit_id},
#{item.qty_unit_name},
#{item.plan_qty},
#{item.real_qty},
#{item.point_code}
)
</foreach>
</insert>
</mapper>

View File

@@ -2,13 +2,26 @@ package org.nl.wms.warehouse_manage.inAndOut.service.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.nl.wms.warehouse_manage.inAndOut.service.dao.IOStorInvDtl;
import java.util.List;
import java.util.Set;
/**
* @author dsh
* 2025/5/21
*/
@Mapper
public interface IOStorInvDtlMapper extends BaseMapper<IOStorInvDtl> {
/**
* 批量插入
* @param list
* @return
*/
int batchInsert(@Param("list") List<IOStorInvDtl> list);
int batchUpdateUnassignQty(@Param("dtlSet") Set<String> dtlSet, @Param("billStatus") String billStatus);
}

View File

@@ -0,0 +1,55 @@
<?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="org.nl.wms.warehouse_manage.inAndOut.service.dao.mapper.IOStorInvDtlMapper">
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO st_ivt_iostorinvdtl (
iostorinvdtl_id,
iostorinv_id,
seq_no,
material_id,
material_code,
pcsn,
bill_status,
qty_unit_id,
qty_unit_name,
source_bill_code,
source_bill_type,
source_billdtl_id,
plan_qty,
remark,
assign_qty,
unassign_qty
) VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.iostorinvdtl_id},
#{item.iostorinv_id},
#{item.seq_no},
#{item.material_id},
#{item.material_code},
#{item.pcsn},
#{item.bill_status},
#{item.qty_unit_id},
#{item.qty_unit_name},
#{item.source_bill_code},
#{item.source_bill_type},
#{item.source_billdtl_id},
#{item.plan_qty},
#{item.remark},
#{item.assign_qty},
#{item.unassign_qty}
)
</foreach>
</insert>
<update id="batchUpdateUnassignQty">
UPDATE st_ivt_iostorinvdtl
SET assign_qty = 0,
unassign_qty = plan_qty,
bill_status = #{billStatus}
WHERE iostorinvdtl_id IN
<foreach collection="dtlSet" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
</mapper>

View File

@@ -50,7 +50,7 @@
<select id="getGroupPlate" resultType="org.nl.wms.warehouse_manage.service.dto.GroupPlateDto">
SELECT group_id,
storagevehicle_code,
gp.material_id,
gp.material_code,
pcsn,
gp.qty_unit_id,
gp.qty_unit_name,
@@ -60,7 +60,7 @@
status,ext_code,ext_type,
mater.material_name,mater.material_spec,mater.material_code
FROM md_pb_groupplate gp
LEFT JOIN md_me_materialbase mater ON mater.material_id = gp.material_id
LEFT JOIN md_me_materialbase mater ON mater.material_code = gp.material_code
<where>
gp.status = '01' and frozen_qty = 0
<if test="params.material_code != null">

View File

@@ -23,6 +23,7 @@ import org.nl.wms.basedata_manage.enums.BaseDataEnum;
import org.nl.wms.basedata_manage.service.IBsrealStorattrService;
import org.nl.wms.basedata_manage.service.IStructattrService;
import org.nl.wms.basedata_manage.service.dao.BsrealStorattr;
import org.nl.wms.basedata_manage.service.dao.Structattr;
import org.nl.wms.basedata_manage.service.dao.mapper.MdPbStoragevehicleextMapper;
import org.nl.wms.basedata_manage.service.dto.*;
import org.nl.wms.sch_manage.enums.TaskStatus;
@@ -33,6 +34,10 @@ import org.nl.wms.sch_manage.service.dao.mapper.SchBasePointMapper;
import org.nl.wms.sch_manage.service.util.tasks.StOutTask;
import org.nl.wms.warehouse_manage.enums.IOSConstant;
import org.nl.wms.warehouse_manage.enums.IOSEnum;
import org.nl.wms.warehouse_manage.inventory.IStInventoryService;
import org.nl.wms.warehouse_manage.inventory.core.param.impl.AddInvParam;
import org.nl.wms.warehouse_manage.inventory.core.enums.InventoryChangeType;
import org.nl.wms.warehouse_manage.inventory.core.param.impl.OutDisReverseParam;
import org.nl.wms.warehouse_manage.service.IMdPbGroupplateService;
import org.nl.wms.warehouse_manage.inAndOut.service.IOutBillService;
import org.nl.wms.warehouse_manage.service.dao.GroupPlate;
@@ -44,6 +49,7 @@ import org.nl.wms.warehouse_manage.inAndOut.service.dao.mapper.IOStorInvDtlMappe
import org.nl.wms.warehouse_manage.inAndOut.service.dao.mapper.IOStorInvMapper;
import org.nl.wms.warehouse_manage.inAndOut.service.dto.IOStorInvDisDto;
import org.nl.wms.warehouse_manage.inAndOut.service.dto.IOStorInvDtlDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@@ -93,6 +99,8 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
@Resource
private IMdPbGroupplateService iMdPbGroupPlateService;
@Autowired
private IStInventoryService iStInventoryService;
@Override
@@ -245,30 +253,29 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
}
@Override
@Transactional(rollbackFor = Exception.class)
public String insertDtl(JSONObject map) {
public String saveBill(JSONObject map) {
//明细
JSONArray array = map.getJSONArray("tableData");
map.remove("tableData");
String currentUserId = SecurityUtils.getCurrentUserId();
String nickName = SecurityUtils.getCurrentNickName();
String user = map.getString("user");
if (ObjectUtil.isNotEmpty(user)) {
if ("erp".equals(user)) {
currentUserId = "2";
nickName = "ERP用户";
}
}
String now = DateUtil.now();
String iostorinv_id = IdUtil.getStringId();
String bill_code = CodeUtil.getNewCode("OUT_STORE_CODE");
BsrealStorattr bsrealStorattr = iBsrealStorattrService.findById((String) map.get("stor_id"));
final String storId = map.getString("stor_id");
BsrealStorattr bsrealStorattr;
if (!StringUtils.isEmpty(storId)){
bsrealStorattr = iBsrealStorattrService.findById(storId);
}else {
final String storCode = map.getString("stor_code");
if (StringUtils.isEmpty(storCode)){
throw new BadRequestException("生成出库单失败,仓库编码不能为空");
}
bsrealStorattr = iBsrealStorattrService.findByCode(storCode);
}
map.put("iostorinv_id", iostorinv_id);
map.put("bill_code", bill_code);
map.put("bill_code", CodeUtil.getNewCode("OUT_STORE_CODE"));
map.put("biz_date", map.getString("biz_date").substring(0, 10));
String bill_type = (String) map.get("bill_type");
map.put("bill_status", IOSEnum.BILL_STATUS.code("生成"));
map.put("io_type", IOSEnum.IO_TYPE.code("出库"));
map.put("detail_count", array.size() + "");
map.put("create_mode", IOSEnum.CREATE_MODE.code("PC产生"));
@@ -283,45 +290,42 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
map.put("is_delete", BaseDataEnum.IS_YES_NOT.code(""));
map.put("is_upload", BaseDataEnum.IS_YES_NOT.code(""));
// 主表重量
double qty = 0.0;
BigDecimal totalQty = BigDecimal.ZERO;
// 明细数
int num = array.size();
ArrayList<IOStorInvDtl> batchSave = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
JSONObject row = array.getJSONObject(i);
// 校验计划数量不能为零
double plan_qty = row.getDoubleValue("qty");
if (Double.compare(plan_qty, 0.0) == 0) {
throw new BadRequestException("数量不能为0");
// 获取数量,使用 BigDecimal 保证精度
BigDecimal planQty = row.getBigDecimal("qty");
if (planQty == null || planQty.compareTo(BigDecimal.ZERO) == 0) {
throw new BadRequestException(String.format("创建失败,第%d行数量不能为0", i + 1));
}
JSONObject ioStorInvDtl = new JSONObject();
ioStorInvDtl.put("iostorinvdtl_id", IdUtil.getStringId());
ioStorInvDtl.put("iostorinv_id", iostorinv_id);
ioStorInvDtl.put("seq_no", (i + 1) + "");
ioStorInvDtl.put("material_id", row.getString("material_id"));
ioStorInvDtl.put("material_code", row.getString("material_code"));
ioStorInvDtl.put("pcsn", row.getString("pcsn"));
ioStorInvDtl.put("bill_status", IOSEnum.BILL_STATUS.code("生成"));
ioStorInvDtl.put("qty_unit_id", row.get("qty_unit_id"));
ioStorInvDtl.put("qty_unit_name", row.getString("qty_unit_name"));
ioStorInvDtl.put("source_bill_code", row.getString("source_bill_code"));
ioStorInvDtl.put("source_bill_type", row.getString("source_bill_type"));
ioStorInvDtl.put("source_billdtl_id", row.getString("source_billdtl_id"));
ioStorInvDtl.put("plan_qty", row.get("qty"));
ioStorInvDtl.put("remark", row.getString("remark"));
ioStorInvDtl.put("assign_qty", "0");
ioStorInvDtl.put("unassign_qty", row.get("qty"));
ioStorInvDtlMapper.insert(ioStorInvDtl.toJavaObject(IOStorInvDtl.class));
qty += ioStorInvDtl.getDoubleValue("plan_qty");
IOStorInvDtl detail = new IOStorInvDtl();
detail.setIostorinvdtl_id(IdUtil.getStringId());
detail.setIostorinv_id(iostorinv_id);
detail.setSeq_no(String.valueOf(i + 1));
detail.setMaterial_id(row.getString("material_id"));
detail.setMaterial_code(row.getString("material_code"));
detail.setPcsn(row.getString("pcsn"));
detail.setBill_status(IOSEnum.BILL_STATUS.code("生成"));
detail.setQty_unit_id(row.getString("qty_unit_id"));
detail.setQty_unit_name(row.getString("qty_unit_name"));
detail.setSource_bill_code(row.getString("source_bill_code"));
detail.setSource_bill_type(row.getString("source_bill_type"));
detail.setSource_billdtl_id(row.getString("source_billdtl_id"));
detail.setPlan_qty(planQty);
detail.setRemark(row.getString("remark"));
detail.setAssign_qty(BigDecimal.ZERO);
detail.setUnassign_qty(planQty);
batchSave.add(detail);
totalQty = totalQty.add(planQty);
}
map.put("total_qty", qty);
ioStorInvDtlMapper.batchInsert(batchSave);
map.put("total_qty", totalQty);
map.put("detail_count", num);
ioStorInvMapper.insert(map.toJavaObject(IOStorInv.class));
return iostorinv_id;
}
@@ -338,19 +342,17 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
@Override
@Transactional(rollbackFor = Exception.class)
public void allDiv(JSONObject whereJson) {
String currentUserId = SecurityUtils.getCurrentUserId();
String nickName = SecurityUtils.getCurrentNickName();
String now = DateUtil.now();
String sectCode = whereJson.getString("sect_code");
// TODO系统如果没有指定出库库区则由WMS手工分配
String iostorinv_id = whereJson.getString("iostorinv_id");
//查询主表信息
IOStorInv ioStorInv = ioStorInvMapper.selectById(iostorinv_id);
if (ObjectUtil.isEmpty(ioStorInv)) {
throw new BadRequestException("查不到出库单信息");
}
//查询生成和未分配完的明细
JSONObject queryDtl = new JSONObject();
queryDtl.put("bill_status", IOSEnum.BILL_STATUS.code("分配完"));
@@ -458,13 +460,7 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
@Override
@Transactional(rollbackFor = Exception.class)
public void allCancel(JSONObject whereJson) {
String currentUserId = SecurityUtils.getCurrentUserId();
String nickName = SecurityUtils.getCurrentNickName();
String now = DateUtil.now();
String iostorinv_id = whereJson.getString("iostorinv_id");
List<IOStorInvDis> ioStorInvDisList = ioStorInvDisMapper.selectList(new LambdaQueryWrapper<>(IOStorInvDis.class)
.le(IOStorInvDis::getWork_status,IOSEnum.INBILL_DIS_STATUS.code("未生成"))
.eq(IOStorInvDis::getIs_issued,BaseDataEnum.IS_YES_NOT.code(""))
@@ -475,53 +471,40 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
}
//需要更新的出入库单明细
Set<String> dtlSet = new HashSet<>();
for (IOStorInvDis ioStorInvDis:ioStorInvDisList){
//添加需要更新的明细标识
Set<String> structSet = new HashSet<>();
List<OutDisReverseParam> OutDisReverseParams = new ArrayList<>();
for (IOStorInvDis ioStorInvDis : ioStorInvDisList){
dtlSet.add(ioStorInvDis.getIostorinvdtl_id());
//更新库存 减冻结加可用
List<JSONObject> updateIvtList = new ArrayList<>();
JSONObject jsonIvt = new JSONObject();
jsonIvt.put("type", IOSConstant.UPDATE_IVT_TYPE_SUB_FROZEN_ADD_CANUSE);
jsonIvt.put("storagevehicle_code", ioStorInvDis.getStoragevehicle_code());
jsonIvt.put("material_id", ioStorInvDis.getMaterial_id());
jsonIvt.put("pcsn", ioStorInvDis.getPcsn());
jsonIvt.put("qty_unit_id", ioStorInvDis.getQty_unit_id());
jsonIvt.put("qty_unit_name", ioStorInvDis.getQty_unit_name());
jsonIvt.put("change_qty", ioStorInvDis.getPlan_qty());
updateIvtList.add(jsonIvt);
iMdPbGroupPlateService.updateIvt(updateIvtList);
final OutDisReverseParam param = OutDisReverseParam.builder()
.materialCode(ioStorInvDis.getMaterial_code())
.changeQty(ioStorInvDis.getPlan_qty())
.structCode(ioStorInvDis.getStruct_code())
.storagevehicleCode(ioStorInvDis.getStoragevehicle_code())
.build();
OutDisReverseParams.add(param);
structSet.add(ioStorInvDis.getStruct_code());
}
iStInventoryService.changeInventory(InventoryChangeType.OUT_DIS_REVERSE,OutDisReverseParams);
//解锁库位
JSONObject unlock_map = new JSONObject();
unlock_map.put("struct_code", ioStorInvDis.getStruct_code());
unlock_map.put("inv_type", null);
unlock_map.put("inv_id", null);
unlock_map.put("inv_code", null);
iStructattrService.updateStatusByCode("2",unlock_map);
//删除出入库单分配表
ioStorInvDisMapper.deleteById(ioStorInvDis.getIostorinvdis_id());
}
//更新出库明细单状态
for (String dtlId:dtlSet){
IOStorInvDtl ioStorInvDtl = ioStorInvDtlMapper.selectById(dtlId);
ioStorInvDtl.setAssign_qty(BigDecimal.ZERO);
ioStorInvDtl.setUnassign_qty(ioStorInvDtl.getPlan_qty());
ioStorInvDtl.setBill_status(IOSEnum.BILL_STATUS.code("生成"));
ioStorInvDtlMapper.updateById(ioStorInvDtl);
}
iStructattrService.update(new LambdaUpdateWrapper<Structattr>()
.set(Structattr::getInv_type,null)
.set(Structattr::getInv_id,null)
.set(Structattr::getInv_code,null)
.set(Structattr::getLock_type,IOSEnum.LOCK_TYPE.code("未锁定"))
.in(Structattr::getStruct_code,structSet));
//删除出入库单分配表
ioStorInvDisMapper.deleteBatchIds(ioStorInvDisList.stream()
.map(IOStorInvDis::getIostorinvdis_id)
.collect(Collectors.toList()));
//回滚明细中的已分配数
ioStorInvDtlMapper.batchUpdateUnassignQty(dtlSet,IOSEnum.BILL_STATUS.code("生成"));
//更新主表单据状态
IOStorInv ios = new IOStorInv();
ios.setIostorinv_id(iostorinv_id);
ios.setUpdate_optid(currentUserId);
ios.setUpdate_optname(nickName);
ios.setUpdate_time(now);
ios.setBill_status(IOSEnum.BILL_STATUS.code("生成"));
ioStorInvMapper.updateById(ios);
ioStorInvMapper.update(null, new LambdaUpdateWrapper<IOStorInv>()
.eq(IOStorInv::getIostorinv_id, iostorinv_id)
.set(IOStorInv::getUpdate_optid, SecurityUtils.getCurrentUserId())
.set(IOStorInv::getUpdate_optname, SecurityUtils.getCurrentNickName())
.set(IOStorInv::getUpdate_time, DateUtil.now())
.set(IOStorInv::getBill_status, IOSEnum.BILL_STATUS.code("生成")));
}
@Override
@@ -537,7 +520,6 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
if (ObjectUtil.isEmpty(ioStorInv)) {
throw new BadRequestException("查不到出库单信息");
}
//查询生成和未分配完的明细
JSONObject queryDtl = new JSONObject();
queryDtl.put("bill_status", IOSEnum.BILL_STATUS.code("分配完"));
@@ -571,6 +553,7 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
);
int seq_no = 1;
BigDecimal allocation_canuse_qty=BigDecimal.ZERO;
final List<IOStorInvDis> disSet = new ArrayList<>();
for (StrategyStructMaterialVO outAllocation : structMaterials) {
//分配明细
IOStorInvDis ioStorInvDis = new IOStorInvDis();
@@ -593,14 +576,6 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
ioStorInvDis.setQty_unit_name(outAllocation.getQty_unit_name());
ioStorInvDis.setWork_status(IOSEnum.INBILL_DIS_STATUS.code("未生成"));
ioStorInvDis.setPlan_qty(outAllocation.getFrozen_qty());
//锁定货位
JSONObject lock_map = new JSONObject();
lock_map.put("struct_code", outAllocation.getStruct_code());
lock_map.put("inv_id", ioStorInv.getIostorinv_id());
lock_map.put("inv_code", ioStorInv.getBill_code());
lock_map.put("inv_type", ioStorInv.getBill_type());
lock_map.put("lock_type", IOSEnum.LOCK_TYPE.code("出库锁"));
iStructattrService.updateStatusByCode("0",lock_map);
//更新组盘表冻结数量状态
iMdPbGroupPlateService.update(new LambdaUpdateWrapper<GroupPlate>()
.set(GroupPlate::getFrozen_qty, outAllocation.getFrozen_qty())
@@ -610,13 +585,24 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
.eq(GroupPlate::getMaterial_code, outAllocation.getMaterial_id())
.eq(GroupPlate::getStatus,IOSEnum.GROUP_PLATE_STATUS.code("入库")));
//生成分配明细
ioStorInvDisMapper.insert(ioStorInvDis);
disSet.add(ioStorInvDis);
allocation_canuse_qty = allocation_canuse_qty.add(outAllocation.getFrozen_qty());
//分配完成 结束分配
if (unassign_qty.doubleValue() <= 0){
break;
}
}
ioStorInvDisMapper.insert(ioStorInvDis);
//锁定货位
JSONObject lock_map = new JSONObject();
lock_map.put("struct_code", outAllocation.getStruct_code());
lock_map.put("inv_id", ioStorInv.getIostorinv_id());
lock_map.put("inv_code", ioStorInv.getBill_code());
lock_map.put("inv_type", ioStorInv.getBill_type());
lock_map.put("lock_type", IOSEnum.LOCK_TYPE.code("出库锁"));
iStructattrService.updateStatusByCode("0",lock_map);
//更新详情
dtl.setBill_status(IOSEnum.BILL_STATUS.code("分配完"));
dtl.setUnassign_qty(unassign_qty);

View File

@@ -1,5 +1,7 @@
package org.nl.wms.warehouse_manage.inventory;
import org.nl.wms.warehouse_manage.inventory.core.param.InventoryParam;
import org.nl.wms.warehouse_manage.inventory.core.enums.InventoryChangeType;
import org.nl.wms.warehouse_manage.inventory.dto.StInventoryDto;
import org.nl.wms.warehouse_manage.inventory.dto.StInventoryQuery;
@@ -10,6 +12,8 @@ import java.util.List;
*/
public interface IStInventoryService {
public List<StInventoryDto> queryInventory(StInventoryQuery query);
List<StInventoryDto> queryInventory(StInventoryQuery query);
<T extends InventoryParam> void changeInventory(InventoryChangeType<T> type, List<T> params);
}

View File

@@ -0,0 +1,38 @@
package org.nl.wms.warehouse_manage.inventory.core.enums;
import org.nl.wms.warehouse_manage.inventory.core.param.InventoryParam;
import org.nl.wms.warehouse_manage.inventory.core.param.impl.*;
//库存变动枚举类强制指定泛型T
public abstract class InventoryChangeType<T extends InventoryParam> {
//加库存可用数
public static final InventoryChangeType<AddInvParam> ADD_INV =
new InventoryChangeType<AddInvParam>(AddInvParam.class) {};
//减库存可用数
public static final InventoryChangeType<SubInvParam> SUB_INV =
new InventoryChangeType<SubInvParam>(SubInvParam.class) {};
//减库存可用数加冻结数
public static final InventoryChangeType<OutDisParam> OUT_DIS =
new InventoryChangeType<OutDisParam>(OutDisParam.class) {};
//OUT_DIS 反函数
public static final InventoryChangeType<OutDisReverseParam> OUT_DIS_REVERSE =
new InventoryChangeType<OutDisReverseParam>(OutDisReverseParam.class) {};
//减冻结数
public static final InventoryChangeType<OutFinishParam> OUT_FINS =
new InventoryChangeType<OutFinishParam>(OutFinishParam.class) {};
//入库相关不用处理,基于组盘
public static final InventoryChangeType<InDisParam> IN_DIS =
new InventoryChangeType<InDisParam>(InDisParam.class) {};
public static final InventoryChangeType<InDisParam> IN_DIS_REVERSE =
new InventoryChangeType<InDisParam>(InDisParam.class) {};
public static final InventoryChangeType<InFinishParam> IN_FINISH =
new InventoryChangeType<InFinishParam>(InFinishParam.class) {};
private final Class<T> paramClass;
public String getType() {
return paramClass.getSimpleName();
}
private InventoryChangeType(Class<T> paramClass) { this.paramClass = paramClass; }
}

View File

@@ -0,0 +1,9 @@
package org.nl.wms.warehouse_manage.inventory.core.param;
// 定
// 义参数接口
public interface InventoryParam {
InventoryParam validation();
}

View File

@@ -0,0 +1,23 @@
package org.nl.wms.warehouse_manage.inventory.core.param.impl;
import lombok.Data;
import org.nl.wms.warehouse_manage.inventory.core.param.InventoryParam;
import java.math.BigDecimal;
@Data
public class AddInvParam implements InventoryParam {
private String storagevehicleCode;
private String materialCode;
private String pcsn;
private BigDecimal qty;
private String extCode;
private String extType;
private String unitName;
private String remark;
@Override
public AddInvParam validation() {
return this;
}
}

View File

@@ -0,0 +1,10 @@
package org.nl.wms.warehouse_manage.inventory.core.param.impl;
import org.nl.wms.warehouse_manage.inventory.core.param.InventoryParam;
public class InDisParam implements InventoryParam {
@Override
public InDisParam validation() {
return this;
}
}

View File

@@ -0,0 +1,11 @@
package org.nl.wms.warehouse_manage.inventory.core.param.impl;
import org.nl.wms.warehouse_manage.inventory.core.param.InventoryParam;
public class InFinishParam implements InventoryParam {
@Override
public InFinishParam validation() {
return this;
}
}

View File

@@ -0,0 +1,23 @@
package org.nl.wms.warehouse_manage.inventory.core.param.impl;
import lombok.Data;
import org.nl.wms.warehouse_manage.inventory.core.param.InventoryParam;
import java.math.BigDecimal;
@Data
public class OutDisParam implements InventoryParam {
private String storagevehicleCode;
private String materialCode;
private String pcsn;
private BigDecimal qty;
private String extCode;
private String extType;
private String unitName;
private String remark;
@Override
public OutDisParam validation() {
return this;
}
}

View File

@@ -0,0 +1,29 @@
package org.nl.wms.warehouse_manage.inventory.core.param.impl;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.nl.wms.warehouse_manage.enums.IOSConstant;
import org.nl.wms.warehouse_manage.inventory.core.param.InventoryParam;
import java.math.BigDecimal;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OutDisReverseParam implements InventoryParam {
private String storagevehicleCode;
private String structCode;
private String materialCode;
private BigDecimal changeQty;
private String pcsn;
@Override
public OutDisReverseParam validation() {
return this;
}
}

View File

@@ -0,0 +1,18 @@
package org.nl.wms.warehouse_manage.inventory.core.param.impl;
import lombok.Data;
import org.nl.wms.warehouse_manage.inventory.core.param.InventoryParam;
import java.math.BigDecimal;
@Data
public class OutFinishParam implements InventoryParam {
private String storagevehicleCode;
private String materialCode;
private String pcsn;
private BigDecimal qty;
@Override
public OutFinishParam validation() {
return this;
}
}

View File

@@ -0,0 +1,21 @@
package org.nl.wms.warehouse_manage.inventory.core.param.impl;
import lombok.Data;
import org.nl.wms.warehouse_manage.inventory.core.param.InventoryParam;
import java.math.BigDecimal;
@Data
public class SubInvParam implements InventoryParam {
private String storagevehicleCode;
private String materialCode;
private String pcsn;
private BigDecimal qty;
private String extCode;
private String extType;
private String unitName;
private String remark;
@Override
public SubInvParam validation() {
return this;
}
}

View File

@@ -1,6 +1,7 @@
package org.nl.wms.warehouse_manage.inventory.dao.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.nl.wms.warehouse_manage.inventory.dto.StInventoryDto;
import org.nl.wms.warehouse_manage.inventory.dto.StInventoryQuery;
@@ -13,5 +14,5 @@ import java.util.List;
@Mapper
public interface StInventoryMapper {
List<StInventoryDto> queryInventory(StInventoryQuery query);
List<StInventoryDto> queryInventory(@Param("query") StInventoryQuery query);
}

View File

@@ -3,17 +3,17 @@
<mapper namespace="org.nl.wms.warehouse_manage.inventory.dao.mapper.StInventoryMapper">
<select id="queryInventory" resultType="org.nl.wms.warehouse_manage.inventory.dto.StInventoryDto">
SELECT
s.stor_id,
s.stor_code,
s.stor_name,
g.material_code,
SUM(g.qty - g.frozen_qty) AS available_qty, -- 可用库存
SUM(g.qty) AS total_qty -- 总库存
s.stor_id as storId,
s.stor_code as storCode,
s.stor_name as storName,
g.material_code as materialCode,
SUM(g.frozen_qty) AS frozenQty, -- 可用库存
SUM(g.qty) AS qty -- 总库存
FROM md_pb_groupplate g
INNER JOIN st_ivt_structattr s
ON g.storagevehicle_code = s.storagevehicle_code
WHERE g.material_id = #{query.materialCode}
AND g.status != '03' -- 排除已移除/已禁用的组盘记录
WHERE g.material_code = #{query.materialCode}
AND g.status = '02' -- 排除已移除/已禁用的组盘记录
AND s.is_used = 1 -- 只统计启用的仓位
GROUP BY s.stor_id, s.stor_code, s.stor_name, g.material_code
ORDER BY s.stor_code;

View File

@@ -60,11 +60,13 @@ public class StInventoryDto {
* 库位名称
*/
private String storName;
private String storCode;
/**
* 区域名称
*/
private String sectName;
private String sectcode;
/**
* 物料编码

View File

@@ -1,27 +1,166 @@
package org.nl.wms.warehouse_manage.inventory.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.SecurityUtils;
import org.nl.wms.warehouse_manage.enums.IOSEnum;
import org.nl.wms.warehouse_manage.inventory.IStInventoryService;
import org.nl.wms.warehouse_manage.inventory.core.param.InventoryParam;
import org.nl.wms.warehouse_manage.inventory.core.enums.InventoryChangeType;
import org.nl.wms.warehouse_manage.inventory.core.param.impl.*;
import org.nl.wms.warehouse_manage.inventory.dao.mapper.StInventoryMapper;
import org.nl.wms.warehouse_manage.inventory.dto.StInventoryDto;
import org.nl.wms.warehouse_manage.inventory.dto.StInventoryQuery;
import org.nl.wms.warehouse_manage.service.IMdPbGroupplateService;
import org.nl.wms.warehouse_manage.service.dao.GroupPlate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.math.BigDecimal;
import java.util.List;
/**
* 库存查询服务
*/
@Service
@Slf4j
public class StInventoryServiceImpl implements IStInventoryService {
@Resource
private StInventoryMapper stInventoryMapper;
@Autowired
private IMdPbGroupplateService iMdPbGroupplateService;
@Override
public List<StInventoryDto> queryInventory(StInventoryQuery query){
List<StInventoryDto> result = stInventoryMapper.queryInventory(query);
return result;
};
}
@Override
public <T extends InventoryParam> void changeInventory(InventoryChangeType<T> typeEnum, List<T> params) {
final String type = typeEnum.getType();
params.forEach(a->a.validation());
//AddInvParam,SubInvParam,OutDisParam,OutFinishParam,InDisParam,InFinishParam
switch (type){
case "AddInvParam":
final List<AddInvParam> addInvParams = (List<AddInvParam>) params;
for (AddInvParam invParam : addInvParams) {
LambdaQueryWrapper<GroupPlate> query = new QueryWrapper<GroupPlate>().lambda()
.eq(GroupPlate::getStoragevehicle_code, invParam.getStoragevehicleCode())
.eq(GroupPlate::getMaterial_code, invParam.getMaterialCode());
if (!StringUtils.isEmpty(invParam.getPcsn())){
query.eq(GroupPlate::getPcsn,invParam.getPcsn());
}
GroupPlate groupPlate = iMdPbGroupplateService.getOne(query);
if (groupPlate == null){
throw new BadRequestException("库存增加失败,当前库存不存在");
}
iMdPbGroupplateService.update(new LambdaUpdateWrapper<GroupPlate>()
.set(GroupPlate::getQty,groupPlate.getQty().add(invParam.getQty()))
.set(GroupPlate::getRemark,invParam.getRemark())
.set(GroupPlate::getUpdate_time,DateUtil.now())
.eq(GroupPlate::getGroup_id,groupPlate.getGroup_id()));
}
break;
case "SubInvParam":
final List<SubInvParam> subInvParams = (List<SubInvParam>) params;
for (SubInvParam subInvParam : subInvParams) {
LambdaQueryWrapper<GroupPlate> query = new QueryWrapper<GroupPlate>().lambda()
.eq(GroupPlate::getStoragevehicle_code, subInvParam.getStoragevehicleCode())
.eq(GroupPlate::getMaterial_code, subInvParam.getMaterialCode());
if (!StringUtils.isEmpty(subInvParam.getPcsn())){
query.eq(GroupPlate::getPcsn,subInvParam.getPcsn());
}
GroupPlate groupPlate = iMdPbGroupplateService.getOne(query);
final BigDecimal qty = groupPlate.getQty().subtract(subInvParam.getQty());
if (groupPlate == null || qty.doubleValue() < 0){
throw new BadRequestException("库存扣减失败,当前库存不存在");
}
iMdPbGroupplateService.update(new LambdaUpdateWrapper<GroupPlate>()
.set(GroupPlate::getQty, qty)
.set(GroupPlate::getRemark,subInvParam.getRemark())
.set(GroupPlate::getUpdate_time,DateUtil.now())
.eq(GroupPlate::getGroup_id,groupPlate.getGroup_id()));
}
break;
case "OutDisParam":
final List<OutDisParam> outDisParams = (List<OutDisParam>) params;
for (OutDisParam outDisParam : outDisParams) {
LambdaQueryWrapper<GroupPlate> query = new QueryWrapper<GroupPlate>().lambda()
.eq(GroupPlate::getStoragevehicle_code, outDisParam.getStoragevehicleCode())
.eq(GroupPlate::getMaterial_code, outDisParam.getMaterialCode());
if (!StringUtils.isEmpty(outDisParam.getPcsn())){
query.eq(GroupPlate::getPcsn,outDisParam.getPcsn());
}
GroupPlate groupPlate = iMdPbGroupplateService.getOne(query);
if (groupPlate == null){
throw new BadRequestException("库存增加失败,当前库存不存在");
}
final BigDecimal qty = groupPlate.getQty().subtract(outDisParam.getQty());
if (qty.intValue() < 0) {
throw new BadRequestException("库存变动失败,可用数量-变动数量为负数"+groupPlate.getStoragevehicle_code());
}
final BigDecimal frozenQty = groupPlate.getFrozen_qty().add(outDisParam.getQty());
iMdPbGroupplateService.update(new LambdaUpdateWrapper<GroupPlate>()
.set(GroupPlate::getQty, qty)
.set(GroupPlate::getFrozen_qty,frozenQty)
.set(GroupPlate::getUpdate_time,DateUtil.now())
.eq(GroupPlate::getGroup_id,groupPlate.getGroup_id()));
}
break;
case "OutFinishParam":
final List<OutFinishParam> outFinishParams = (List<OutFinishParam>) params;
for (OutFinishParam outFinishParam : outFinishParams) {
final LambdaQueryWrapper<GroupPlate> queryWrapper = new QueryWrapper<GroupPlate>().lambda()
.eq(GroupPlate::getStoragevehicle_code, outFinishParam.getStoragevehicleCode())
.eq(GroupPlate::getMaterial_code, outFinishParam.getMaterialCode())
.eq(GroupPlate::getStatus, IOSEnum.GROUP_PLATE_STATUS.code("入库"));
if (!StringUtils.isEmpty(outFinishParam.getPcsn())){
queryWrapper.eq(GroupPlate::getPcsn, outFinishParam.getPcsn());
}
GroupPlate groupPlate = iMdPbGroupplateService.getOne(queryWrapper);
groupPlate.setFrozen_qty(groupPlate.getFrozen_qty().subtract(outFinishParam.getQty()));
groupPlate.setUpdate_id(SecurityUtils.getCurrentUserId());
groupPlate.setUpdate_name(SecurityUtils.getCurrentNickName());
groupPlate.setUpdate_time(DateUtil.now());
iMdPbGroupplateService.updateById(groupPlate);
}
break;
case "OutDisReverseParam":
final List<OutDisReverseParam> outFinishReverseParams = (List<OutDisReverseParam>) params;
for (OutDisReverseParam param : outFinishReverseParams) {
final LambdaQueryWrapper<GroupPlate> queryWrapper = new QueryWrapper<GroupPlate>().lambda()
.eq(GroupPlate::getStoragevehicle_code, param.getStoragevehicleCode())
.eq(GroupPlate::getMaterial_code, param.getMaterialCode())
.eq(GroupPlate::getStatus, IOSEnum.GROUP_PLATE_STATUS.code("入库"));
if (!StringUtils.isEmpty(param.getPcsn())){
queryWrapper.eq(GroupPlate::getPcsn, param.getPcsn());
}
GroupPlate groupPlate = iMdPbGroupplateService.getOne(queryWrapper);
groupPlate.setFrozen_qty(groupPlate.getFrozen_qty().subtract(param.getChangeQty()));
groupPlate.setQty(groupPlate.getQty().add(param.getChangeQty()));
groupPlate.setUpdate_id(SecurityUtils.getCurrentUserId());
groupPlate.setUpdate_name(SecurityUtils.getCurrentNickName());
groupPlate.setUpdate_time(DateUtil.now());
System.out.println("========="+groupPlate.getFrozen_qty()+"=========");
iMdPbGroupplateService.updateById(groupPlate);
}
break;
case "InDisParam":
break;
case "InFinishParam":
break;
default:
throw new BadRequestException(String.format("库存变动失败,当前变动类型%d未定义",type));
}
}
}

View File

@@ -23,7 +23,7 @@
LEFT JOIN st_ivt_moreorlessmst ios ON ios.mol_id = dtl.mol_id
LEFT JOIN md_me_materialbase material ON material.material_id = dtl.material_id
INNER JOIN md_pb_groupplate ext ON ext.storagevehicle_code = dtl.storagevehicle_code
AND ext.material_id = dtl.material_id AND dtl.pcsn = ext.pcsn
AND ext.material_code = dtl.material_code AND dtl.pcsn = ext.pcsn
<where>
ios.is_delete = '0'
<if test="param.mol_id != null and param.mol_id != ''">

View File

@@ -62,7 +62,7 @@ public class UpdateIvtUtils {
break;
case IOSConstant.UPDATE_IVT_TYPE_ADD_FROZEN :
// 加冻结减可用
updateAddFrozenIvt(where);
// updateAddFrozenIvt(where);
break;
case IOSConstant.UPDATE_IVT_TYPE_SUB_FROZEN :
// 减冻结
@@ -70,15 +70,15 @@ public class UpdateIvtUtils {
break;
case IOSConstant.UPDATE_IVT_TYPE_SUB_FROZEN_ADD_CANUSE :
// 减冻结加可用
updateSubFrozenAddIvt(where);
// updateSubFrozenAddIvt(where);
break;
case IOSConstant.UPDATE_IVT_TYPE_ADD_CANUSE_IVT :
// 加可用(加库存)
updateAddCanuseIvt(where);
// updateAddCanuseIvt(where);
break;
case IOSConstant.UPDATE_IVT_TYPE_SUB_CANUSE_IVT :
// 减可用(减库存)
updateSubCanuseIvt(where);
// updateSubCanuseIvt(where);
break;
default:
break;