优化出库拣选模块的命名, 魔法数字, 代码结构, 业务流程未动

This commit is contained in:
李宇奇 2026-03-11 10:24:16 +08:00
parent fa1fd09170
commit ea7e1aae4e
11 changed files with 582 additions and 1292 deletions

199
README.md
View File

@ -49,4 +49,201 @@
* 将主单数据移入 TRkWareNoticeBak。
* 将明细数据移入 TRkWareNoticeTabBak。
* 数据清理: 物理删除 TRkWareNotice 和 TRkWareNoticeTab 中的原数据。
* 关闭通知: 关闭关联的 TCallNoticeOrder 任务。
* 关闭通知: 关闭关联的 TCallNoticeOrder 任务。
### 详细出库流程解析
> TCkOrdersServiceImpl
> TCkPickingwavegoodsServiceImpl
#### 单据创建阶段 (Creation)
* 动作:
* 用户通过 add 接口新增主单,或通过 importData 导入 Excel。
* 用户通过 updateTckOrderDetails 维护出库明细。
* 数据变更:
* 插入 TCkOrders主单状态 Status = "0"(新建)。
* 插入或更新 TCkOrderdetail明细 ConfirmStatus = "0"(待执行)。
* 业务逻辑:
1. 校验来源单号 DeliveryId 不能重复。
2. 校验同一单据内不能重复添加相同 GoodsId。
3. 若对应物料已有锁定库存,则不允许继续追加明细。
4. 回填价格、总金额、建单人、部门、记录人等基础信息。
* 关键点: 此阶段只是在系统内形成“出库需求”,还不会锁库存,也不会生成拣货任务。
#### 审核提交流程 (Audit Submission)
这一步负责把出库申请送入审批链,而不是直接执行出库。
* 接口: changeStatus / auditCkOrders
* 业务逻辑:
1. 查询当前出库单及其全部明细。
2. 将明细转换成 GoodsVo 列表,组装 OutBound 审批数据。
3. 把每条明细的 CallShelvesNum 回写为申请数量 ShelvesNum。
4. 调用钉钉创建审批实例,生成 InstanceId。
5. 写入本地 OutBound 审批记录,并把 InstanceId 回写到 TCkOrders。
* 关键点:
* updateStatus 负责发起审批流。
* auditCkOrders 是本地审核通过入口。
#### 任务分流阶段 (Dispatch)
审核通过后,系统会根据仓库类型决定走“推送 IWMS”还是“本地生成出库任务”。
* 接口: send / sendiwms / issue
* 业务逻辑:
1. send 会按仓库是否为 AGV 仓拆分出库明细。
2. AGV 仓明细调用 sendIwms向 IWMS 推送出库数据。
3. 非 AGV 仓明细调用 confirmOut走本地锁库与任务生成。
4. 手持出库 issue 会先自动创建一张已审核的普通出库单,再直接调用 confirmOut。
* 数据变更:
* sendIwms 成功后,会回写明细 TrNum = GoodsNum、PickNum并把 CkType 置为普通出库。
* 关键点: sendOrderNotice 还保留了向手持端补发 TCallNoticeOrder 的能力,但当前控制层入口已注释。
#### IWMS 推送阶段 (AGV Branch)
该分支只处理 AGV 仓明细,主要目标是把出库需求推送给外部 IWMS。
* 接口: sendiwms / sendIwms
* 业务逻辑:
1. 重新加载当前出库单,筛选出 AGV 仓明细。
2. 按 GoodsId、GoodsName、Ctl、StorageId、ShelvesNum 匹配库存记录。
3. 逐条组装推送报文,包含单号、物料、数量、追溯码、仓库、容器类型等字段。
4. 调用外部接口 `pushOutOrder` 发送数据。
5. 外部返回“成功”后,回写对应明细的提货数量与出库类型。
* 关键点: 该分支负责“推送外部系统”,不在本类内创建 TCkPickingwavegoods 本地拣货任务。
#### 本地出库任务生成阶段 (Local Task Generation)
这一阶段是 TCkOrdersServiceImpl 内最核心的“选库存 + 锁库存 + 生成任务”流程。
* 接口: confirmOut
* 业务逻辑:
1. 校验出库明细不能为空,并跳过 ConfirmStatus = "2" 的已完成明细。
2. 按物料、仓库、托盘号 Ctl、库位 LocationId 查询可用库存;若未指定仓库,则从当前部门有权限的仓库中查找。
3. 若指定了 Ctl则按托盘分组否则按库位分组逐组累加库存直到满足 GoodsNum。
4. 将本次命中的库位与数量写回明细:累计 PickNum并把销售单号集合拼接到 BusinessId。
5. 将主单 TCkOrders.Status 更新为 "1"(已锁定)。
6. 把“按物料汇总”的结果转换成“按库位汇总”的任务数据,避免同一库位重复创建任务。
7. 校验该库位是否已存在同单出库任务;若不存在,则进入 createLocationOutboundTasks。
8. 按仓库维度发送 TCallNotice 出库通知。
* 关键点: 这里完成的是库存占用与任务拆分,不是最终库存扣减。
#### 库存锁定与拣货任务落地 (Stock Locking / Picking Task Creation)
* 接口: createLocationOutboundTasks由 confirmOut 内部调用)
* 业务逻辑:
1. 对命中的每条 TMiStock 回写 OccupyNum并把库存状态设为 "1"(已锁定)。
2. 逐条生成 TCkPickingwavegoods 拣货任务,带出托盘号、库位、批次、库存主键、来源单号、仓库等信息。
3. 初始化拣货任务 RecNum = 0、ConfirmStatus = "0"(待执行),并挂接同一个 CallNoticeId。
* 数据变更:
* 更新 TMiStock。
* 插入 TCkPickingwavegoods。
* 发送 TCallNotice。
* 关键点: 本类到这里为止,已经完成出库资源占用和任务下发。
#### 调拨联动阶段 (Transfer)
调拨出库是本类中的另一条专用支路,会同时联动生成一张入库通知单。
* 接口: create / install
* 业务逻辑:
1. 创建一张 TCkOrders 调拨出库单OrderType 和 CkType 都为调拨出库。
2. 写入对应的 TCkOrderdetail 调拨明细。
3. 同步创建一张 TRkWareNotice 调拨入库通知单,以及对应的 TRkWareNoticeTab 明细。
4. 创建 TransferOrder把出库单和入库单关联起来。
* 关键点: 这里完成的是“调拨单据联动建单”,后续实际出库仍要继续走任务分配或确认链路。
#### 流程边界说明 (Boundary)
从 TCkOrdersServiceImpl 代码来看,它主要负责“建单、审批、分流、锁库、建拣货任务、推送 IWMS”。
* 关键点:
* 本类没有完成最终的库存实扣。
* 本类没有完成拣货任务归档。
* 本类也没有把主单推进到“出库完成”终态。
* 结论: 真正的拣货执行、库存扣减、任务完成与归档,发生在后续拣货/出库执行链路,而不是在本类中闭环完成。
### 出库执行闭环补充TCkPickingwavegoods
#### 拣货确认阶段 (Picking Confirmation)
这一阶段对应实际执行出库任务后的确认动作,是本地出库链路真正开始“落账”的地方。
* 接口: confirm
* 业务逻辑:
1. 校验提交的拣货确认明细不能为空。
2. 按当前托盘/任务条件查询待拣任务,若未查到任务则直接报错。
3. 要求本次确认必须把同一批待确认任务一起提交,否则拒绝确认。
4. 先把出库主单 TCkOrders.Status 重置为 "0",解除前一阶段的锁定态。
5. 遍历每条 TCkPickingwavegoods依次执行库存实扣、任务备份、明细累计出库量更新。
* 关键点: confirm 使用的是拣货任务上的 RecNum本次实际出库数量而不是申请数量 ShelvesNum。
#### 库存实扣与资源释放阶段 (Stock Deduction / Resource Release)
* 内部方法: updateTmiStock
* 业务逻辑:
1. 通过 DoctNumber 定位被锁定的 TMiStock 库存记录。
2. 用库存现存量 ShelvesNum 减去本次实际出库量 RecNum。
3. 若扣减后库存为 0则直接删除该库存记录。
4. 若扣减后仍有余量,则把库存状态恢复为 "0",并把 OccupyNum 清零。
5. 若当前库位已无任何库存,则把 TBaseStorageAreaLocation.Status 释放为 "0"。
6. 若当前托盘号 Ctl 下已无库存,则把托盘 TBasePallet.Status 释放为 "0"。
* 关键点: confirmOut 负责“占用库存”confirm 才真正完成“库存实扣”。
#### 任务备份与明细回写阶段 (Task Backup / Detail Update)
* 业务逻辑:
1. 每条已确认的 TCkPickingwavegoods 都会复制到 TCkPickingwavegoodsBak。
2. 备份记录的 ConfirmStatus 会被置为 "3"。
3. 回写对应的 TCkOrderdetailTrNum += RecNum表示累计实际出库量增加。
4. 清空本次明细上的 GoodsNum避免旧的申请数量继续参与后续出库。
5. 若 TrNum == ShelvesNum则把明细 ConfirmStatus 更新为 "2"(全部完成)。
6. 若 TrNum < ShelvesNum则把明细 ConfirmStatus "0" 推进为 "1"部分完成
* 关键点: 出库明细是否完成,取决于累计实际出库量 TrNum 是否追平申请数量 ShelvesNum。
#### 主单收口与归档阶段 (Order Convergence / Archiving)
系统会在每次确认后,重新判断整张出库单是否已经全部完成。
* 业务逻辑:
1. 重新查询该出库单下全部 TCkOrderdetail。
2. 只要还有任意一条明细 ConfirmStatus 不是 "2",则主单仍未完结。
3. 若主单未完结,则把 TCkOrders.ConfirmStatus 更新为 "1"(部分完成)。
4. 若主单全部完成,则把 TCkOrders 备份到 TckOrdersBak。
5. 同时把全部 TCkOrderdetail 备份到 TckOrderdetailBak并补齐审核人、审核时间、申请人、驳回原因等主单信息。
6. 备份完成后,物理删除原 TCkOrders 和 TCkOrderdetail 数据。
* 关键点: 主单是否归档,不取决于是否生成过任务,而取决于所有明细是否都已完成实际出库。
#### 任务删除与通知关闭阶段 (Task Cleanup / Notice Closing)
* 业务逻辑:
1. 当前批次确认完成后,会删除对应的原始 TCkPickingwavegoods 任务。
2. 再按 CallNoticeId 查询是否还存在未完成的同批呼叫任务。
3. 若同一 CallNoticeId 下已无剩余任务,则关闭对应的 TCallNotice 出库通知。
* 关键点: 通知关闭的判断粒度是 CallNoticeId不是单条拣货任务。
#### 设备平台推送阶段 (Device Push)
当某个呼叫批次下的本地出库任务全部结束后,系统会尝试把出库完成结果推送到设备管理平台。
* 内部方法: sendDevice
* 业务逻辑:
1. 生成签名并组装请求头。
2. 以已完成的出库主单和明细为基础,拼装外部表单数据。
3. 调用设备平台 `batchSaveEntity` 接口推送出库完成结果。
4. 不论成功还是失败,都会记录 DeviceLog 日志。
* 关键点:
* 成功时返回“推送成功出库完成”。
* 失败时返回“出库完成,请求超时或失败”或签名失败提示。
#### 手工撤销补充 (Manual Cleanup)
除正常确认链路外,代码中还保留了手工删除出库任务的兜底处理。
* 接口: deleteTCkPickingwavegoodsByIds
* 业务逻辑:
1. 按任务查出对应托盘号 Ctl。
2. 删除该托盘关联的出库任务记录。
3. 将该托盘关联库存状态释放为 "0"。
* 关键点: 这是异常处理或人工干预分支,不属于标准的出库完成闭环。

View File

@ -1,8 +1,11 @@
package com.zbf.common.enums.custom;
import lombok.Getter;
/**
* 出库确认状态
*/
@Getter
public enum OutboundConfirmStatus
{
PENDING("0", "待执行"),
@ -17,14 +20,4 @@ public enum OutboundConfirmStatus
this.code = code;
this.description = description;
}
public String getCode()
{
return code;
}
public String getDescription()
{
return description;
}
}

View File

@ -0,0 +1,29 @@
package com.zbf.common.enums.custom;
/**
* 出库单明细启停状态
*/
public enum OutboundOrderDetailStatus
{
ENABLED("0", "启用"),
DISABLED("1", "停用");
private final String code;
private final String description;
OutboundOrderDetailStatus(String code, String description)
{
this.code = code;
this.description = description;
}
public String getCode()
{
return code;
}
public String getDescription()
{
return description;
}
}

View File

@ -0,0 +1,31 @@
package com.zbf.common.enums.custom;
/**
* 出库拣选任务状态
*/
public enum OutboundPickingTaskStatus
{
PENDING("0", "待处理"),
DISABLED("1", "停用"),
DISPATCHED_TO_PLC("2", "已下发PLC"),
CONFIRMED("3", "已确认");
private final String code;
private final String description;
OutboundPickingTaskStatus(String code, String description)
{
this.code = code;
this.description = description;
}
public String getCode()
{
return code;
}
public String getDescription()
{
return description;
}
}

View File

@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zbf.common.annotation.Excel;
import com.zbf.common.core.domain.BaseEntity;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -18,6 +20,8 @@ import java.util.Date;
* @date 2024-08-07
*/
@TableName(resultMap = "com.zbf.system.mapper.OutBoundMapper.OutBoundResult")
@Getter
@Setter
public class OutBound extends BaseEntity {
private static final long serialVersionUID = 1L;
@ -70,123 +74,6 @@ private static final long serialVersionUID = 1L;
@Excel(name = "后台实例ID")
private String fInstanceId;
private String finishName;
public String getfInstanceId() {
return fInstanceId;
}
public String getFinishName() {
return finishName;
}
public void setFinishName(String finishName) {
this.finishName = finishName;
}
public void setfInstanceId(String fInstanceId) {
this.fInstanceId = fInstanceId;
}
public String getInstanceId() {
return instanceId;
}
public void setInstanceId(String instanceId) {
this.instanceId = instanceId;
}
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public String getCrossDeptManager() {
return crossDeptManager;
}
public void setCrossDeptManager(String crossDeptManager) {
this.crossDeptManager = crossDeptManager;
}
public String getDeliveryId() {
return deliveryId;
}
public void setDeliveryId(String deliveryId) {
this.deliveryId = deliveryId;
}
public String getDeptmanager() {
return deptmanager;
}
public void setDeptmanager(String deptmanager) {
this.deptmanager = deptmanager;
}
public String getManagerName() {
return managerName;
}
public void setManagerName(String managerName) {
this.managerName = managerName;
}
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setItemList(String itemList)
{
this.itemList = itemList;
}
public String getItemList()
{
return itemList;
}
public void setCkType(String ckType)
{
this.ckType = ckType;
}
public String getCkType()
{
return ckType;
}
public String getApplyTime() {
return applyTime;
}
public void setApplyTime(String applyTime) {
this.applyTime = applyTime;
}
public void setApplyer(String applyer)
{
this.applyer = applyer;
}
public String getApplyer()
{
return applyer;
}
public String getStorageId() {
return storageId;
}
public void setStorageId(String storageId) {
this.storageId = storageId;
}
@Override
public String toString() {

View File

@ -8,6 +8,8 @@ import com.baomidou.mybatisplus.annotation.TableName;
import com.zbf.common.annotation.Excel;
import com.zbf.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.IndexedColors;
import java.lang.reflect.Field;
@ -21,6 +23,8 @@ import java.util.List;
*/
@Data
@TableName(resultMap = "com.zbf.system.mapper.TBaseStorageMapper.TBaseStorageResult")
@Getter
@Setter
public class TBaseStorage extends BaseEntity {
private static final long serialVersionUID = 1L;
@ -116,126 +120,6 @@ public class TBaseStorage extends BaseEntity {
return columns;
}
public String getStorageShortName() {
return storageShortName;
}
public void setStorageShortName(String storageShortName) {
this.storageShortName = storageShortName;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFactoryId() {
return factoryId;
}
public void setFactoryId(String factoryId) {
this.factoryId = factoryId;
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public String getStorageId() {
return storageId;
}
public void setStorageId(String storageId) {
this.storageId = storageId;
}
public String getStorageName() {
return storageName;
}
public void setStorageName(String storageName) {
this.storageName = storageName;
}
public String getStorageAddress() {
return storageAddress;
}
public void setStorageAddress(String storageAddress) {
this.storageAddress = storageAddress;
}
public String getStorageConcatsName() {
return storageConcatsName;
}
public void setStorageConcatsName(String storageConcatsName) {
this.storageConcatsName = storageConcatsName;
}
public String getStorageConcatsMobile() {
return storageConcatsMobile;
}
public void setStorageConcatsMobile(String storageConcatsMobile) {
this.storageConcatsMobile = storageConcatsMobile;
}
public String getAutoStatus() {
return autoStatus;
}
public void setAutoStatus(String autoStatus) {
this.autoStatus = autoStatus;
}
public String getIsAgv() {
return isAgv;
}
public void setIsAgv(String isAgv) {
this.isAgv = isAgv;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<String> getStorageList() {
return storageList;
}
public void setStorageList(List<String> storageList) {
this.storageList = storageList;
}
public String[] getSelectIds() {
return selectIds;
}
public void setSelectIds(String[] selectIds) {
this.selectIds = selectIds;
}
@Override
public String toString() {
return "TBaseStorage{" +
@ -253,22 +137,4 @@ public class TBaseStorage extends BaseEntity {
", type='" + type + '\'' +
'}';
}
}
}

View File

@ -4,6 +4,8 @@ package com.zbf.system.domain;
import java.util.Date;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -20,6 +22,8 @@ import com.zbf.common.core.domain.BaseEntity;
* @date 2024-06-24
*/
@Getter
@Setter
public class TCkOrderdetail extends BaseEntity {
private static final long serialVersionUID = 1L;
@ -161,318 +165,6 @@ private static final long serialVersionUID = 1L;
private String original;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getBusinessId() {
return businessId;
}
public void setBusinessId(String businessId) {
this.businessId = businessId;
}
public String getGoodsId() {
return goodsId;
}
public void setGoodsId(String goodsId) {
this.goodsId = goodsId;
}
public String getGoodsName() {
return goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
}
public String getLocationId() {
return locationId;
}
public void setLocationId(String locationId) {
this.locationId = locationId;
}
public String getGoodsTo() {
return goodsTo;
}
public void setGoodsTo(String goodsTo) {
this.goodsTo = goodsTo;
}
public String getSpecification() {
return specification;
}
public void setSpecification(String specification) {
this.specification = specification;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public String getStorageId() {
return storageId;
}
public void setStorageId(String storageId) {
this.storageId = storageId;
}
public String getStorageShortName() {
return storageShortName;
}
public void setStorageShortName(String storageShortName) {
this.storageShortName = storageShortName;
}
public BigDecimal getShelvesNum() {
return shelvesNum;
}
public void setShelvesNum(BigDecimal shelvesNum) {
this.shelvesNum = shelvesNum;
}
public BigDecimal getGoodsNum() {
return goodsNum;
}
public void setGoodsNum(BigDecimal goodsNum) {
this.goodsNum = goodsNum;
}
public BigDecimal getCallShelvesNum() {
return callShelvesNum;
}
public void setCallShelvesNum(BigDecimal callShelvesNum) {
this.callShelvesNum = callShelvesNum;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public String getGoodsTypeId() {
return goodsTypeId;
}
public void setGoodsTypeId(String goodsTypeId) {
this.goodsTypeId = goodsTypeId;
}
public String getProviderId() {
return providerId;
}
public void setProviderId(String providerId) {
this.providerId = providerId;
}
public String getRecoil() {
return recoil;
}
public void setRecoil(String recoil) {
this.recoil = recoil;
}
public String getStorageAreaId() {
return storageAreaId;
}
public void setStorageAreaId(String storageAreaId) {
this.storageAreaId = storageAreaId;
}
public BigDecimal getPickNum() {
return pickNum;
}
public void setPickNum(BigDecimal pickNum) {
this.pickNum = pickNum;
}
public BigDecimal getTrNum() {
return trNum;
}
public void setTrNum(BigDecimal trNum) {
this.trNum = trNum;
}
public String getBarcode() {
return barcode;
}
public void setBarcode(String barcode) {
this.barcode = barcode;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getToLoc() {
return toLoc;
}
public void setToLoc(String toLoc) {
this.toLoc = toLoc;
}
public String getConfirmStatus() {
return confirmStatus;
}
public void setConfirmStatus(String confirmStatus) {
this.confirmStatus = confirmStatus;
}
public Date getExpiryDate() {
return expiryDate;
}
public void setExpiryDate(Date expiryDate) {
this.expiryDate = expiryDate;
}
public BigDecimal getStockNum() {
return stockNum;
}
public void setStockNum(BigDecimal stockNum) {
this.stockNum = stockNum;
}
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public String getAbc() {
return abc;
}
public void setAbc(String abc) {
this.abc = abc;
}
public String getLevelType() {
return levelType;
}
public void setLevelType(String levelType) {
this.levelType = levelType;
}
public String getDeliveryId() {
return deliveryId;
}
public void setDeliveryId(String deliveryId) {
this.deliveryId = deliveryId;
}
public String getCkType() {
return ckType;
}
public void setCkType(String ckType) {
this.ckType = ckType;
}
public String getOrderType() {
return orderType;
}
public void setOrderType(String orderType) {
this.orderType = orderType;
}
public String getSupplier() {
return supplier;
}
public void setSupplier(String supplier) {
this.supplier = supplier;
}
public String getApplicant() {
return applicant;
}
public void setApplicant(String applicant) {
this.applicant = applicant;
}
public String getCtl() {
return ctl;
}
public void setCtl(String ctl) {
this.ctl = ctl;
}
public BigDecimal getToMoney() {
return toMoney;
}
public void setToMoney(BigDecimal toMoney) {
this.toMoney = toMoney;
}
public String getBatchNo() {
return batchNo;
}
public void setBatchNo(String batchNo) {
this.batchNo = batchNo;
}
public String getOriginal() {
return original;
}
public void setOriginal(String original) {
this.original = original;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@ -505,17 +197,4 @@ public String toString() {
.append("updateTime", getUpdateTime())
.toString();
}
}
}

View File

@ -5,6 +5,8 @@ import java.util.Date;
import java.util.List;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -23,6 +25,8 @@ import com.zbf.common.core.domain.BaseEntity;
*/
@Data
@TableName(resultMap = "com.zbf.system.mapper.TCkOrdersMapper.TCkOrdersResult")
@Getter
@Setter
public class TCkOrders extends BaseEntity {
private static final long serialVersionUID = 1L;
@ -144,38 +148,6 @@ private static final long serialVersionUID = 1L;
@Excel(name = "审核原因",needMerge = true)
private String why;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
public String getDeliveryId() {
return deliveryId;
}
public void setDeliveryId(String deliveryId) {
this.deliveryId = deliveryId;
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
/** 出库物料明细信息 */
private List<TCkOrderdetail> tckOrderdetailList;
@ -184,275 +156,6 @@ private static final long serialVersionUID = 1L;
private String auditPerson2;
private String auditPerson3;
public String getCtl() {
return ctl;
}
public void setCtl(String ctl) {
this.ctl = ctl;
}
public BigDecimal getSum() {
return sum;
}
public void setSum(BigDecimal sum) {
this.sum = sum;
}
public int getIsAvgExec() {
return isAvgExec;
}
public void setIsAvgExec(int isAvgExec) {
this.isAvgExec = isAvgExec;
}
public String getAuditPerson3() {
return auditPerson3;
}
public String getInstanceId() {
return instanceId;
}
public void setInstanceId(String instanceId) {
this.instanceId = instanceId;
}
public void setAuditPerson3(String auditPerson3) {
this.auditPerson3 = auditPerson3;
}
public String getAuditPerson1() {
return auditPerson1;
}
public void setAuditPerson1(String auditPerson1) {
this.auditPerson1 = auditPerson1;
}
public String getAuditPerson2() {
return auditPerson2;
}
public void setAuditPerson2(String auditPerson2) {
this.auditPerson2 = auditPerson2;
}
public String getRejectReason() {
return rejectReason;
}
public void setRejectReason(String rejectReason) {
this.rejectReason = rejectReason;
}
public String getIsAudit() {
return isAudit;
}
public void setIsAudit(String isAudit) {
this.isAudit = isAudit;
}
public void setId(String id)
{
this.id = id;
}
public String getId()
{
return id;
}
public void setOrderId(String orderId)
{
this.orderId = orderId;
}
public String getOrderId()
{
return orderId;
}
public void setStorageId(String storageId)
{
this.storageId = storageId;
}
public String getStorageId()
{
return storageId;
}
public void setStorageAreaId(String storageAreaId)
{
this.storageAreaId = storageAreaId;
}
public String getStorageAreaId()
{
return storageAreaId;
}
public void setCkType(String ckType)
{
this.ckType = ckType;
}
public String getCkType()
{
return ckType;
}
public void setDeliveryMethod(String deliveryMethod)
{
this.deliveryMethod = deliveryMethod;
}
public String getDeliveryMethod()
{
return deliveryMethod;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setAuditMan(String auditMan)
{
this.auditMan = auditMan;
}
public String getAuditMan()
{
return auditMan;
}
public void setAuditDate(Date auditDate)
{
this.auditDate = auditDate;
}
public Date getAuditDate()
{
return auditDate;
}
public void setOrderSource(String orderSource)
{
this.orderSource = orderSource;
}
public String getOrderSource()
{
return orderSource;
}
public void setOutStand(String outStand)
{
this.outStand = outStand;
}
public String getOutStand()
{
return outStand;
}
public void setOrderType(String orderType)
{
this.orderType = orderType;
}
public String getOrderType()
{
return orderType;
}
public void setConfirmStatus(String confirmStatus)
{
this.confirmStatus = confirmStatus;
}
public String getConfirmStatus()
{
return confirmStatus;
}
public void setRecordPerson(String recordPerson)
{
this.recordPerson = recordPerson;
}
public String getRecordPerson()
{
return recordPerson;
}
public void setApplicant(String applicant)
{
this.applicant = applicant;
}
public String getApplicant()
{
return applicant;
}
public void setRecordDate(Date recordDate)
{
this.recordDate = recordDate;
}
public Date getRecordDate()
{
return recordDate;
}
public void setProductId(String productId)
{
this.productId = productId;
}
public String getProductId()
{
return productId;
}
public void setStationId(String stationId)
{
this.stationId = stationId;
}
public String getStationId()
{
return stationId;
}
public void setTaskId(String taskId)
{
this.taskId = taskId;
}
public String getTaskId()
{
return taskId;
}
public void setOrderDate(String orderDate)
{
this.orderDate = orderDate;
}
public String getOrderDate()
{
return orderDate;
}
public List<TCkOrderdetail> getTckOrderdetailList() {
return tckOrderdetailList;
}
public void setTckOrderdetailList(List<TCkOrderdetail> tckOrderdetailList) {
this.tckOrderdetailList = tckOrderdetailList;
}
public String getStorageShortName() {
return storageShortName;
}
public void setStorageShortName(String storageShortName) {
this.storageShortName = storageShortName;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -121,7 +121,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
private TransferOrderMapper transferOrderMapper;
@Autowired
private SysDeptMapper sysDeptMapper;
private SysDeptMapper sysDeptMapper;
@Value("${deptmanager}")
@ -133,8 +133,6 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
private D_Service dingTalkService;
/**
* 查询出库
*
@ -212,17 +210,17 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
if (existingOrders.size() > 0) {
throw new RuntimeException("来源单号已存在,请修改后再提交!");
}
if(StringUtils.isEmpty(tCkOrders.getApplicant())){
if (StringUtils.isEmpty(tCkOrders.getApplicant())) {
tCkOrders.setApplicant(SecurityUtils.getUserNick());
}else{
} else {
tCkOrders.setApplicant(tCkOrders.getApplicant());
}
SysDept sysDept = sysDeptMapper.selectDeptById(tCkOrders.getDeptId());
String[] ancestorDeptIds = sysDept.getAncestors().split(",");
if(ancestorDeptIds.length>3){
if (ancestorDeptIds.length > 3) {
SysDept businessDept = sysDeptMapper.selectDeptById(Long.valueOf(ancestorDeptIds[3]));
tCkOrders.setDeptName(businessDept.getDeptName());
}else{
} else {
tCkOrders.setDeptName(sysDept.getDeptName());
}
@ -243,13 +241,13 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
@Override
public int updateTCkOrders(TCkOrders tCkOrders) {
tCkOrders.setUpdateTime(DateUtils.getNowDate());
LoginUser loginUser = SecurityUtils.getLoginUser();
if(loginUser != null){
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
SysUser user = loginUser.getUser();
if(user != null){
if (user != null) {
tCkOrders.setUpdateBy(user.getNickName());
}
}else{
} else {
tCkOrders.setUpdateBy("callBack 更新");
}
@ -321,25 +319,24 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
/**
* 修改状态
*
* @param tCkOrders 工序管理主键
* @return 结果
*/
@Override
@Transactional
public int updateStatus(TCkOrders tCkOrders) {
if (StringUtils.isNotBlank(tCkOrders.getIsAudit())) {
if (StringUtils.isNotBlank(tCkOrders.getAuditPerson1())) {
this.deptManager = tCkOrders.getAuditPerson1();
// 出库流程
public int updateStatus(TCkOrders tCkOrder) {
if (StringUtils.isNotBlank(tCkOrder.getIsAudit())) {
if (StringUtils.isNotBlank(tCkOrder.getAuditPerson1())) {
this.deptManager = tCkOrder.getAuditPerson1();
}
if (StringUtils.isNotBlank(tCkOrders.getAuditPerson2())) {
this.managerName = tCkOrders.getAuditPerson2();
if (StringUtils.isNotBlank(tCkOrder.getAuditPerson2())) {
this.managerName = tCkOrder.getAuditPerson2();
}
//tCkOrders.setAuditMan(deptManager);
tCkOrders.setRejectReason("");
//tCkOrder.setAuditMan(deptManager);
tCkOrder.setRejectReason("");
}
TCkOrders currentOrder = tCkOrdersMapper.get(tCkOrders.getId());
TCkOrders currentOrder = tCkOrdersMapper.get(tCkOrder.getId());
OutBound outBound = new OutBound();
outBound.setDeptmanager(deptManager); //第一审核人
outBound.setManagerName(managerName); //第二审核人
@ -348,16 +345,16 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
outBound.setApplyTime(DateUtils.getDate());
// outBound.setApplyer(SecurityUtils.getUserNick());
outBound.setApplyer(getUsername());
if (StringUtils.isNotBlank(tCkOrders.getAuditPerson3())) {
outBound.setCrossDeptManager(tCkOrders.getAuditPerson3());
if (StringUtils.isNotBlank(tCkOrder.getAuditPerson3())) {
outBound.setCrossDeptManager(tCkOrder.getAuditPerson3());
}
List<GoodsVo> outboundGoodsList = new ArrayList<>();
//查询明细
TCkOrderdetail orderDetailQuery = new TCkOrderdetail();
orderDetailQuery.setOrderId(tCkOrders.getId());
orderDetailQuery.setOrderId(tCkOrder.getId());
List<TCkOrderdetail> orderDetailList = tCkOrderdetailMapper.selectTCkOrderdetailList(orderDetailQuery);
if(orderDetailList.size() == 0){
if (orderDetailList.isEmpty()) {
logger.error("没有获取到明细条数====");
throw new RuntimeException("未获取到明细,请确认!");
}
@ -372,7 +369,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
goodsVo.setShelvesNum(orderDetail.getShelvesNum());
goodsVo.setStorageId(orderDetail.getStorageId());
goodsVo.setStorageShortName(orderDetail.getStorageShortName());
if(StringUtils.isBlank(outboundStorageShortName)){
if (StringUtils.isBlank(outboundStorageShortName)) {
outboundStorageShortName = orderDetail.getStorageShortName();
}
goodsVo.setTotal(orderDetail.getStockNum());
@ -393,19 +390,18 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
}
outBound.setStorageId(outboundStorageShortName);
outBound.setItemList(JSONUtil.toJsonStr(outboundGoodsList));
//查询token创建实例
String instanceId = dingTalkService.createInstance(outBound);
logger.info("创建的实例ID{}",instanceId);
if(StringUtils.isBlank(instanceId)){
logger.warn("创建实例ID异常,只能本地审批,无法通过钉钉审批了,流程继续,申请人:{}",getUsername());
//throw new RuntimeException("创建钉钉实例异常===》》》》");
}
outBound.setInstanceId(instanceId);
// String instanceId = dingTalkService.createInstance(outBound);
// logger.info("创建的实例ID{}",instanceId);
// if(StringUtils.isBlank(instanceId)){
// logger.warn("创建实例ID异常,只能本地审批,无法通过钉钉审批了,流程继续,申请人:{}",getUsername());
// throw new RuntimeException("创建钉钉实例异常===》》》》");
// }
// outBound.setInstanceId(instanceId);
outBoundService.insertOutBound(outBound);
//更新出库主表钉钉实例ID
tCkOrders.setInstanceId(instanceId);
int row = tCkOrdersMapper.updateTCkOrders(tCkOrders);
return row;
// tCkOrder.setInstanceId(instanceId);
return tCkOrdersMapper.updateTCkOrders(tCkOrder);
}
@Transactional
@ -424,7 +420,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
.values()
.stream()
.anyMatch(list -> list.size() > 1);
if(hasDuplicate){
if (hasDuplicate) {
throw new RuntimeException("请不要添加重复的物料");
}
@ -480,7 +476,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
}
orderDetail.setId(OrderCodeFactory.getOrderCode("CKTM", ""));
//todo 暂时通过remark记录物资流向
if(StringUtils.isNotBlank(orderDetail.getRemark())) {
if (StringUtils.isNotBlank(orderDetail.getRemark())) {
orderDetail.setGoodsTo(orderDetail.getRemark());
}
tCkOrderdetailMapper.insert(orderDetail);
@ -498,18 +494,16 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
@Override
@Transactional
public int confirmOut(TCkOrders tCkOrders) {
List<TCkOrderdetail> orderDetails = tCkOrders.getTckOrderdetailList();
if (orderDetails.size() == 0) {
// 出库流程
public int confirmOut(TCkOrders tCkOrder) {
List<TCkOrderdetail> orderDetails = tCkOrder.getTckOrderdetailList();
if (orderDetails.isEmpty()) {
logger.error("出库明细条数必须大于0");
throw new RuntimeException("出库明细条数必须大于0");
}
//1. 判断库存是否满足
// String storageId = tCkOrders.getStorageId();
//判断是否选中了仓库如果没有选中则从所有权限下仓库进行查询如果选中了则从指定仓库选择
// 判断是否选中了仓库如果没有选中则从所有权限下仓库进行查询如果选中了则从指定仓库选择
logger.info("出库请求解析开始:{}", orderDetails);
//value: 以托盘号为key该托盘出库该物料的出库数量为value的map
Map<String, Map<String, BigDecimal>> goodsLocationQuantityMap = new HashMap<String, Map<String, BigDecimal>>();
Map<String, Map<String, BigDecimal>> goodsLocationQuantityMap = new HashMap<>();
List<OutStockVo> selectedOutboundStocks = new ArrayList<>();
// 所有仓库集合
@ -530,25 +524,21 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
stockQuery.setStorageId(orderDetail.getStorageId());
} else {
TBaseStorage storageQuery = new TBaseStorage();
storageQuery.setDeptId(tCkOrders.getDeptId());
storageQuery.setDeptId(tCkOrder.getDeptId());
List<TBaseStorage> availableStorages = baseStorageService.selectTBaseStorageList(storageQuery);
stockQuery.setStorageList(availableStorages.stream().map(TBaseStorage::getStorageId).collect(Collectors.toList()));
}
if(StringUtils.isNotBlank(orderDetail.getCtl())){
if (StringUtils.isNotBlank(orderDetail.getCtl())) {
stockQuery.setCtl(orderDetail.getCtl());
}
if(StringUtils.isNotBlank(orderDetail.getLocationId())){
if (StringUtils.isNotBlank(orderDetail.getLocationId())) {
stockQuery.setLocationId(orderDetail.getLocationId());
}
// LambdaQueryWrapper<TMiStock> wrapper = new LambdaQueryWrapper<>();
// wrapper.eq(TMiStock::getGoodsId, tMiStock.getGoodsId());
// wrapper.eq(TMiStock::getGoodsName, tMiStock.getGoodsName());
List<TMiStock> candidateStocks = tMiStockMapper.selectTMiStockList(stockQuery);
if (candidateStocks.size() == 0) {
if (candidateStocks.isEmpty()) {
logger.warn("未找到该物料库存或在冻结中:{}", orderDetail.getGoodsId());
throw new RuntimeException("未找到该物料库存或在冻结中:" + orderDetail.getGoodsId());
}
@ -570,7 +560,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
// 处理分组
StringBuilder salesOrderNumbersBuilder = new StringBuilder();
for (List<TMiStock> stockGroup : groupedStockMap.values()) {
TMiStock stockSnapshot = stockGroup.get(0); // 取每组的第一条记录
TMiStock stockSnapshot = stockGroup.get(0);
accumulatedAvailableQuantity = accumulatedAvailableQuantity.add(stockSnapshot.getShelvesNum());
if (orderDetail.getPickNum() == null) {
orderDetail.setPickNum(BigDecimal.ZERO);
@ -579,7 +569,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
outboundStock.setId(stockSnapshot.getId());
outboundStock.setLocationId(stockSnapshot.getLocationId());
if (requiredGoodsNum.compareTo(accumulatedAvailableQuantity) == 0) {
if (requiredGoodsNum.compareTo(accumulatedAvailableQuantity) >= 0) {
locationOutboundQuantityMap.put(stockSnapshot.getLocationId(), stockSnapshot.getShelvesNum());
outboundStock.setShelvesNum(stockSnapshot.getShelvesNum());
selectedOutboundStocks.add(outboundStock);
@ -606,8 +596,8 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
break;
}
}
if(salesOrderNumbersBuilder.toString().length()>1){
String salesOrderNumbers = salesOrderNumbersBuilder.substring(0, salesOrderNumbersBuilder.length()-1);
if (salesOrderNumbersBuilder.toString().length() > 1) {
String salesOrderNumbers = salesOrderNumbersBuilder.substring(0, salesOrderNumbersBuilder.length() - 1);
orderDetail.setBusinessId(salesOrderNumbers);
}
goodsLocationQuantityMap.put(orderDetail.getGoodsId(), locationOutboundQuantityMap);
@ -621,10 +611,10 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
throw new RuntimeException("未找到出库物料,请确认!");
}
//设置主表status为锁定
// 设置主表status为锁定
TCkOrders lockedOrder = new TCkOrders();
lockedOrder.setStatus(OutboundOrderStatus.LOCKED.getCode());
lockedOrder.setId(tCkOrders.getId());
lockedOrder.setId(tCkOrder.getId());
lockedOrder.setUpdateBy(SecurityUtils.getUserNick());
lockedOrder.setUpdateTime(new Date());
tCkOrdersMapper.updateById(lockedOrder);
@ -637,8 +627,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
* 根据这个逻辑进行开发
*/
//lambda表达式遍历
//蒋map进行转换转换为以托盘为大key以物料和数量为小map的map
// 将map进行转换转换为以托盘为大key以物料和数量为小map的map
Map<String, Map<String, BigDecimal>> locationGoodsQuantityMap = new HashMap<>();
goodsLocationQuantityMap.forEach((goodsId, locationQuantityMap) -> {
locationQuantityMap.forEach((locationId, shelvesNum) -> {
@ -665,23 +654,23 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
TCallNotice callNotice = new TCallNotice();
callNotice.setId(IdUtils.randomUUID());
//根据每个托盘创建出库任务
//1. 判断出库任务是否已产生该托盘的任务
// 根据每个托盘创建出库任务
// 1. 判断出库任务是否已产生该托盘的任务
locationGoodsQuantityMap.forEach((locationId, goodsQuantityMap) -> {
TCkPickingwavegoods pickingTaskQuery = new TCkPickingwavegoods();
pickingTaskQuery.setLocationId(locationId);
pickingTaskQuery.setGoodsIdList(new ArrayList<>(goodsQuantityMap.keySet()));
pickingTaskQuery.setOutId(tCkOrders.getId());
pickingTaskQuery.setOutId(tCkOrder.getId());
//判断该库位编号是否产生出库任务
List<TCkPickingwavegoods> existingPickingTasks = tCkPickingwavegoodsMapper.selectTCkPickingwavegoodsList(pickingTaskQuery);
if (existingPickingTasks.size() > 0) {
if (!existingPickingTasks.isEmpty()) {
logger.error("该库位已产生出库任务:{}", locationId);
throw new RuntimeException("该库位已产生出库任务:" + locationId);
}
//出库 添加呼叫任务号
createLocationOutboundTasks(locationId, tCkOrders.getId(), tCkOrders.getOrderId(), tCkOrders.getCkType(),
createLocationOutboundTasks(locationId, tCkOrder.getId(), tCkOrder.getOrderId(), tCkOrder.getCkType(),
selectedOutboundStocks.stream().filter(stock -> stock.getLocationId().equals(locationId)).collect(Collectors.toList()),
callNotice.getId());
@ -693,18 +682,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
involvedStorageIds.forEach((storageId) -> {
// 仓库id
callNotice.setStorageId(storageId);
// 托盘号
// tCallNotice.setCtl("");
// pLCID
// tCallNotice.setPlcid("");
// 任务类型 1:出库任务
callNotice.setTaskType(NoticeTaskType.OUTBOUND.getCode());
// 物料编码
// tCallNotice.setGoodsId(tCkPickingwavegoods.getGoodsId());
// 物料名称
// tCallNotice.setGoodsName(tCkPickingwavegoods.getGoodsName());
// 出库任务ID
// tCallNotice.setChukuId(tCkPickingwavegoods.getId());
// 创建者
callNotice.setCreateBy(SecurityUtils.getUserNick());
// 时间
@ -712,7 +690,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
// 状态 0未处理
callNotice.setStatus(NoticeTaskStatus.PENDING.getCode());
// 出库通知单号
callNotice.setTaskId(tCkOrders.getOrderId());
callNotice.setTaskId(tCkOrder.getOrderId());
// 虚拟入库标识 0:非虚拟
callNotice.setFictitious(TaskFictitiousFlag.REAL.getCode());
@ -760,55 +738,9 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
private void createLocationOutboundTasks(String locationId, String outboundOrderId, String outboundNoticeId,
String outboundType, List<OutStockVo> outboundStocks, String callNoticeId) {
if (outboundStocks.size() == 0) {
if (outboundStocks.isEmpty()) {
throw new RuntimeException("没有获取到该物料库存明细");
}
// TMiStock tMiStock = new TMiStock();
// tMiStock.setLocationId(locationId);
// List<TMiStock> tMiStocks = tMiStockMapper.selectTMiStockList(tMiStock);
//设置库存里面的出库数量
// for (TMiStock tMiStock1 : tMiStocks) {
// for (String key : map.keySet()) {
// BigDecimal value = map.get(key);
// if (tMiStock1.getGoodsId().equals(key)) {
// //出库数量
// tMiStock1.setPackingNum(value);
// break;
// }
// }
// }
//
// boolean isExist = false;
// for (TMiStock tMiStock1 : tMiStocks) {
// if (tMiStock1.getPackingNum() == null) {
// isExist = true;
// break;
// }
// if (tMiStock1.getShelvesNum().compareTo(tMiStock1.getPackingNum()) > 0) {
// isExist = true;
// break;
// }
// }
//CkType 1.零捡 2全量 3移库
//boxtype1不需要出库 2零捡 3全出
// if (isExist) {
// tMiStocks.forEach(e -> {
// if (e.getPackingNum() == null) {
// //不需要出库的
// e.setBoxType("1");
// } else {
// //零检
// e.setBoxType("2");
// }
// e.setCkType("1");
// });
// } else {
// tMiStocks.forEach(e -> {
// e.setCkType("2");
// e.setBoxType("3");
// });
// }
//是否需要冻结库存
//出哪条锁定哪条
for (OutStockVo outboundStock : outboundStocks) {
@ -820,12 +752,6 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
stockOccupancyUpdate.setStatus(OutboundResourceLockStatus.LOCKED.getCode());
tMiStockMapper.updateById(stockOccupancyUpdate);
}
// TMiStock tMiStock3 = new TMiStock();
// tMiStock3.setLocationId(locationId);
// tMiStock3.setStatus("1");
// tMiStock3.setUpdateBy(SecurityUtils.getUserNick());
// tMiStock3.setUpdateTime(DateUtils.getNowDate());
// tMiStockMapper.updateSts(tMiStock3);
//创建出库任务
for (OutStockVo outboundStock : outboundStocks) {
@ -1040,23 +966,19 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
}
@Override
public Map<String, String> sendOrderNotice(TCkOrders update) {
// 出库流程
public Map<String, String> sendOrderNotice(TCkOrders ckOrderUpdate) {
Map<String, String> resultMap = new HashMap<>();
// 获取通知单信息
TCkOrders currentOrder = tCkOrdersMapper.selectTCkOrdersById(update.getId());
TCkOrders currentOrder = tCkOrdersMapper.selectTCkOrdersById(ckOrderUpdate.getId());
if (ObjectUtils.isEmpty(currentOrder)) {
resultMap.put("error", "待发送消息的出库通知单不存在");
return resultMap;
}
if (currentOrder.getTckOrderdetailList() == null || currentOrder.getTckOrderdetailList().isEmpty()) {
resultMap.put("error", "待发送消息的出库通知单没有物料明细数据");
return resultMap;
}
if (!OutboundAuditStatus.APPROVED.getCode().equals(currentOrder.getIsAudit())) {
resultMap.put("error", "出库通知单未审核完成,不能发送到手持设备");
return resultMap;
@ -1066,22 +988,16 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
TCallNoticeOrder noticeOrder = new TCallNoticeOrder();
// 通知单编号
noticeOrder.setTaskId(currentOrder.getOrderId());
// 任务类型 1:通知单出库
noticeOrder.setTaskType(NoticeTaskType.OUTBOUND.getCode());
// 状态
noticeOrder.setStatus(NoticeTaskStatus.PENDING.getCode());
// 创建者
noticeOrder.setCreateBy(update.getCreateBy());
noticeOrder.setCreateBy(ckOrderUpdate.getCreateBy());
noticeOrder.setCreateTime(new Date());
noticeOrder.setUpdateBy(update.getCreateBy());
noticeOrder.setUpdateBy(ckOrderUpdate.getCreateBy());
noticeOrder.setUpdateTime(new Date());
// 0:正常任务
noticeOrder.setFictitious(TaskFictitiousFlag.REAL.getCode());
// 来源单号
noticeOrder.setDeliveryId(currentOrder.getDeliveryId());
// 部门ID
noticeOrder.setDeptId(update.getDeptId());
noticeOrder.setDeptId(ckOrderUpdate.getDeptId());
// 订单类型
String outboundTypeLabel = sysDictDataMapper.selectDictLabel("outbound_type", currentOrder.getCkType());
noticeOrder.setOrderType(outboundTypeLabel);
@ -1224,6 +1140,8 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
*/
@Override
@Transactional
// 出库流程
public AjaxResult send(TCkOrders outboundOrder) {
List<TCkOrderdetail> orderDetails = outboundOrder.getTckOrderdetailList();
@ -1252,19 +1170,19 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
}
}
Map<String, String> iwmsResult = sendIwms(agvOutboundOrder);
Map<String, String> iWmsResult = sendIwms(agvOutboundOrder);
if (agvOrderDetails.size() == outboundOrder.getTckOrderdetailList().size()) {
if (iwmsResult.containsKey("error")) {
return AjaxResult.error(iwmsResult.get("error"));
if (iWmsResult.containsKey("error")) {
return AjaxResult.error(iWmsResult.get("error"));
} else {
return AjaxResult.success("推送成功");
}
}
List<TCkOrderdetail> manualOrderDetails = orderDetails.stream()
.filter(orderdetail -> {
String isAgv = baseStorageService.getIsAgvByStorageId(orderdetail.getStorageId());
.filter(orderDetail -> {
String isAgv = baseStorageService.getIsAgvByStorageId(orderDetail.getStorageId());
return !StorageAgvFlag.AGV.getCode().equals(isAgv);
})
.collect(Collectors.toList());
@ -1281,6 +1199,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
*/
@Transactional(rollbackFor = Exception.class)
@Override
// 出库流程
public int install(TCkOrdersVo transferOrderRequest) {
String transferOutboundOrderId = OrderCodeFactory.getOrderCode("", "");
// 1. 创建并验证出库单
@ -1378,7 +1297,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
.orElseThrow(() -> new RuntimeException("创建入库通知单失败"));
// 4. 处理通知单明细
List<TRkWareNoticeTab> transferInboundNoticeTabs = new ArrayList<TRkWareNoticeTab>();
List<TRkWareNoticeTab> transferInboundNoticeTabs = new ArrayList<>();
transferOrderRequest.getData().stream()
.map(transferItem -> {
TRkWareNoticeTab tab = new TRkWareNoticeTab();
@ -1437,7 +1356,6 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
transferOrderMapper.insertTransferOrder(transferOrder);
return 1;
}
@ -1445,7 +1363,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
public Long statisticCallShelvesNum(TCkOrderdetail tCkOrderdetail) {
//1. 首先查询已审核
Long aLong = tCkOrdersMapper.queryTotalCallShelvesNum(tCkOrderdetail);
if(aLong == null){
if (aLong == null) {
aLong = 0L;
}
return aLong;
@ -1475,11 +1393,9 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
/**
* 推出库数据
*
*/
// @Log(title = "推送数据出库")
public Map<String, String> sendIwms(TCkOrders outboundOrder) {
logger.info("推送数据出库====》》》》》");
logger.info("推送数据出库====>>>>>");
Map<String, String> resultMap = new HashMap<>();
TCkOrders currentOrder = tCkOrdersMapper.selectTCkOrdersById(outboundOrder.getId());
if (currentOrder != null) {
@ -1488,8 +1404,8 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
List<TCkOrderdetail> orderDetails = outboundOrder.getTckOrderdetailList();
List<TCkOrderdetail> agvOrderDetails = orderDetails.stream()
.filter(orderdetail -> {
String isAgv = baseStorageService.getIsAgvByStorageId(orderdetail.getStorageId());
.filter(orderDetail -> {
String isAgv = baseStorageService.getIsAgvByStorageId(orderDetail.getStorageId());
return StorageAgvFlag.AGV.getCode().equals(isAgv);
})
.collect(Collectors.toList());
@ -1512,7 +1428,7 @@ public class TCkOrdersServiceImpl extends ServiceImpl<TCkOrdersMapper, TCkOrders
List<TMiStock> matchedStocks = tMiStockMapper.selectList(queryWrapper);
if (CollectionUtils.isEmpty(matchedStocks)) {
resultMap.put("error", "库存不存在");
continue; // Skip this iteration and continue with the next
continue;
}
TMiStock matchedStock = matchedStocks.get(0);
Map<String, Object> dataObject = createDataObject(orderDetail, matchedStock, outboundOrder);

View File

@ -11,6 +11,13 @@ import com.zbf.common.annotation.DataScope;
import com.zbf.common.annotation.Log;
import com.zbf.common.core.domain.model.LoginUser;
import com.zbf.common.enums.BusinessType;
import com.zbf.common.enums.custom.NoticeTaskType;
import com.zbf.common.enums.custom.OutboundConfirmStatus;
import com.zbf.common.enums.custom.OutboundOrderDetailStatus;
import com.zbf.common.enums.custom.OutboundOrderStatus;
import com.zbf.common.enums.custom.OutboundPickingTaskStatus;
import com.zbf.common.enums.custom.OutboundResourceLockStatus;
import com.zbf.common.enums.custom.OutboundResourceOccupancyStatus;
import com.zbf.common.utils.DateUtils;
import com.zbf.common.utils.OrderCodeFactory;
import com.zbf.common.utils.SecurityUtils;
@ -75,7 +82,7 @@ public class TCkPickingwavegoodsServiceImpl extends ServiceImpl<TCkPickingwavego
@Autowired
private TCkOrdersServiceImpl tCkOrdersService;
@Autowired
@Autowired
private ITCallNoticeService tNoticeService;
@Autowired
@ -99,12 +106,14 @@ public class TCkPickingwavegoodsServiceImpl extends ServiceImpl<TCkPickingwavego
public TCkPickingwavegoods selectTCkPickingwavegoodsById(String id) {
return tCkPickingwavegoodsMapper.selectTCkPickingwavegoodsById(id);
}
private List<TBaseStorage> getStorageList(Long deptId){
private List<TBaseStorage> getStorageList(Long deptId) {
TBaseStorage baseStorage = new TBaseStorage();
baseStorage.setDeptId(deptId);
return baseStorageService.selectTBaseStorageList(baseStorage);
}
/**
* 查询出库任务列表
*
@ -418,6 +427,7 @@ public class TCkPickingwavegoodsServiceImpl extends ServiceImpl<TCkPickingwavego
return countOut.size();
}
/**
* 首页出库任务未审核完成统计
*
@ -722,227 +732,211 @@ public class TCkPickingwavegoodsServiceImpl extends ServiceImpl<TCkPickingwavego
/**
* 出库拣选确认操作
*
* @param goodsList
* @return
*/
@Log(title = "出库拣选")
@Transactional(rollbackFor = Exception.class)
// 出库流程
public int confirm(List<TCkPickingwavegoods> goodsList) {
logger.info("确认出库开始:{}", goodsList);
if (goodsList.size() == 0) {
if (goodsList.isEmpty()) {
logger.error("拣选明细不能为空");
throw new RuntimeException("拣选明细不能为空");
}
//托盘所有数据
List<TCkPickingwavegoods> tCkPickingwavegoodsList = tCkPickingwavegoodsMapper.selectgoodsByCtl(goodsList.get(0));
logger.info("获取数据:{}", tCkPickingwavegoodsList.size());
if (tCkPickingwavegoodsList.size() == 0) {
List<TCkPickingwavegoods> pendingPalletPickingTaskList = tCkPickingwavegoodsMapper.selectgoodsByCtl(goodsList.get(0));
logger.info("获取数据:{}", pendingPalletPickingTaskList.size());
if (pendingPalletPickingTaskList.isEmpty()) {
logger.error("未查询到待拣选任务");
throw new RuntimeException("未查询到该托盘号待拣选任务");
}
if (tCkPickingwavegoodsList.size() != goodsList.size()) {
if (pendingPalletPickingTaskList.size() != goodsList.size()) {
logger.error("拣选确认必须同一个库位一起进行确认");
throw new RuntimeException("拣选确认必须同一个库位一起进行确认");
}
//释放该库位
//备份出库任务
String id = StringUtils.EMPTY;
String ctl = StringUtils.EMPTY;
String storageId = StringUtils.EMPTY;
String locationId = StringUtils.EMPTY;
String callNoticeId = StringUtils.EMPTY;
String outboundOrderId = StringUtils.EMPTY;
String palletId = StringUtils.EMPTY;
String warehouseId = StringUtils.EMPTY;
String storageLocationId = StringUtils.EMPTY;
String outboundCallNoticeId = StringUtils.EMPTY;
//更新主表状态
TCkOrders tCkOrders5 = new TCkOrders();
tCkOrders5.setId(goodsList.get(0).getOutId());
tCkOrders5.setStatus("0");
tCkOrdersMapper.updateById(tCkOrders5);
for (TCkPickingwavegoods tCkPickingwavegoods : goodsList) {
TCkOrders outboundOrderStatusUpdate = new TCkOrders();
outboundOrderStatusUpdate.setId(goodsList.get(0).getOutId());
outboundOrderStatusUpdate.setStatus(OutboundOrderStatus.CREATED.getCode());
tCkOrdersMapper.updateById(outboundOrderStatusUpdate);
for (TCkPickingwavegoods pickingTask : goodsList) {
// 备份呼叫单号
callNoticeId = tCkPickingwavegoods.getCallNoticeId();
outboundCallNoticeId = pickingTask.getCallNoticeId();
//更新库存
updateTmiStock(tCkPickingwavegoods);
updateTmiStock(pickingTask);
// 1. 备份修改后的出库任务
TCkPickingwavegoodsBak bak = new TCkPickingwavegoodsBak();
BeanUtils.copyProperties(tCkPickingwavegoods,bak);
bak.setConfirmStatus("3");
tCkPickingwavegoodsBakService.insertTCkPickingwavegoodsBak(bak);
TCkPickingwavegoodsBak pickingTaskBackup = new TCkPickingwavegoodsBak();
BeanUtils.copyProperties(pickingTask, pickingTaskBackup);
pickingTaskBackup.setConfirmStatus(OutboundPickingTaskStatus.CONFIRMED.getCode());
tCkPickingwavegoodsBakService.insertTCkPickingwavegoodsBak(pickingTaskBackup);
//出库单出库数量
TCkOrderdetail tCkOrderdetail = new TCkOrderdetail();
tCkOrderdetail.setGoodsId(tCkPickingwavegoods.getGoodsId());
TCkOrderdetail orderDetailQuery = new TCkOrderdetail();
orderDetailQuery.setGoodsId(pickingTask.getGoodsId());
//主表主键
if (StringUtils.isBlank(id)) {
id = tCkPickingwavegoods.getOutId();
ctl = tCkPickingwavegoods.getCtl();
storageId = tCkPickingwavegoods.getStorageId();
locationId = tCkPickingwavegoods.getLocationId();
if (StringUtils.isBlank(outboundOrderId)) {
outboundOrderId = pickingTask.getOutId();
palletId = pickingTask.getCtl();
warehouseId = pickingTask.getStorageId();
storageLocationId = pickingTask.getLocationId();
}
tCkOrderdetail.setOrderId(id);
List<TCkOrderdetail> tCkOrderdetails = tCkOrderdetailMapper.selectTCkOrderdetailList(tCkOrderdetail);
if (tCkOrderdetails.size() > 0) {
TCkOrderdetail tCkOrderdetail1 = tCkOrderdetails.get(0);
orderDetailQuery.setOrderId(outboundOrderId);
List<TCkOrderdetail> matchedOrderDetailList = tCkOrderdetailMapper.selectTCkOrderdetailList(orderDetailQuery);
if (!matchedOrderDetailList.isEmpty()) {
TCkOrderdetail matchedOrderDetail = matchedOrderDetailList.get(0);
//确认出库数量
if (tCkOrderdetail1.getTrNum() == null) tCkOrderdetail1.setTrNum(BigDecimal.ZERO);
if (tCkPickingwavegoods.getRecNum() == null) tCkPickingwavegoods.setRecNum(BigDecimal.ZERO);
tCkOrderdetail1.setTrNum(tCkOrderdetail1.getTrNum().add(tCkPickingwavegoods.getRecNum()));
if (matchedOrderDetail.getTrNum() == null) matchedOrderDetail.setTrNum(BigDecimal.ZERO);
if (pickingTask.getRecNum() == null) pickingTask.setRecNum(BigDecimal.ZERO);
matchedOrderDetail.setTrNum(matchedOrderDetail.getTrNum().add(pickingTask.getRecNum()));
//清空上次出库数量
tCkOrderdetail1.setGoodsNum(BigDecimal.ZERO);
if (tCkOrderdetail1.getShelvesNum().compareTo(tCkOrderdetail1.getTrNum()) == 0) {
tCkOrderdetail1.setConfirmStatus("2");
matchedOrderDetail.setGoodsNum(BigDecimal.ZERO);
if (matchedOrderDetail.getShelvesNum().compareTo(matchedOrderDetail.getTrNum()) == 0) {
matchedOrderDetail.setConfirmStatus(OutboundConfirmStatus.COMPLETED.getCode());
} else {
if ("0".equals(tCkOrderdetail1.getConfirmStatus())) {
tCkOrderdetail1.setConfirmStatus("1");
if (OutboundConfirmStatus.PENDING.getCode().equals(matchedOrderDetail.getConfirmStatus())) {
matchedOrderDetail.setConfirmStatus(OutboundConfirmStatus.PARTIAL.getCode());
}
}
tCkOrderdetail1.setUpdateTime(DateUtils.getNowDate());
tCkOrderdetail1.setStatus("0");
tCkOrderdetailMapper.updateTCkOrderdetail(tCkOrderdetail1);
matchedOrderDetail.setUpdateTime(DateUtils.getNowDate());
matchedOrderDetail.setStatus(OutboundOrderDetailStatus.ENABLED.getCode());
tCkOrderdetailMapper.updateTCkOrderdetail(matchedOrderDetail);
}
}
//根据库位查询是否有库存
LambdaQueryWrapper<TMiStock> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(TMiStock::getLocationId,locationId);
// queryWrapper.eq(TMiStock::getCtl,ctl);
LambdaQueryWrapper<TMiStock> stockByLocationQueryWrapper = new LambdaQueryWrapper<>();
stockByLocationQueryWrapper.eq(TMiStock::getLocationId, storageLocationId);
List<TMiStock> tMiStocks = tMiStockMapper.selectList(queryWrapper);
if(tMiStocks.size() == 0){
List<TMiStock> remainingLocationStockList = tMiStockMapper.selectList(stockByLocationQueryWrapper);
if (remainingLocationStockList.isEmpty()) {
//释放库位
TBaseStorageAreaLocation baseStorageAreaLocation = new TBaseStorageAreaLocation();
baseStorageAreaLocation.setLocationId(locationId);
baseStorageAreaLocation.setStatus("0");
tBaseStorageAreaLocationMapper.updateLocationSts(baseStorageAreaLocation);
TBaseStorageAreaLocation locationStatusUpdate = new TBaseStorageAreaLocation();
locationStatusUpdate.setLocationId(storageLocationId);
locationStatusUpdate.setStatus(OutboundResourceOccupancyStatus.IDLE.getCode());
tBaseStorageAreaLocationMapper.updateLocationSts(locationStatusUpdate);
}
//校验托盘容器是否正确
if(StringUtils.isNotBlank(ctl)){
LambdaQueryWrapper<TMiStock> queryWrapper2 = new LambdaQueryWrapper<>();
queryWrapper2.eq(TMiStock::getCtl,ctl);
List<TMiStock> tMiStocks2 = tMiStockMapper.selectList(queryWrapper);
if(tMiStocks2.size() == 0){
LambdaQueryWrapper<TBasePallet> ctlWrapper = new LambdaQueryWrapper<>();
ctlWrapper.eq(TBasePallet::getPalletId, ctl);
List<TBasePallet> plcs = basePalletMapper.selectList(ctlWrapper);
if (!plcs.isEmpty()) {
TBasePallet palletChk = plcs.get(0);
if("1".equals(palletChk.getStatus())){
TBasePallet tBasePallet = new TBasePallet();
tBasePallet.setStatus("0");
tBasePallet.setId(palletChk.getId());
tBasePallet.setUpdateTime(new Date());
basePalletMapper.updateTBasePallet(tBasePallet);
if (StringUtils.isNotBlank(palletId)) {
LambdaQueryWrapper<TMiStock> stockByPalletQueryWrapper = new LambdaQueryWrapper<>();
stockByPalletQueryWrapper.eq(TMiStock::getCtl, palletId);
List<TMiStock> remainingLocationStockListForPalletCheck = tMiStockMapper.selectList(stockByLocationQueryWrapper);
if (remainingLocationStockListForPalletCheck.isEmpty()) {
LambdaQueryWrapper<TBasePallet> palletQueryWrapper = new LambdaQueryWrapper<>();
palletQueryWrapper.eq(TBasePallet::getPalletId, palletId);
List<TBasePallet> matchedPalletList = basePalletMapper.selectList(palletQueryWrapper);
if (!matchedPalletList.isEmpty()) {
TBasePallet matchedPallet = matchedPalletList.get(0);
if (OutboundResourceOccupancyStatus.OCCUPIED.getCode().equals(matchedPallet.getStatus())) {
TBasePallet palletStatusUpdate = new TBasePallet();
palletStatusUpdate.setStatus(OutboundResourceOccupancyStatus.IDLE.getCode());
palletStatusUpdate.setId(matchedPallet.getId());
palletStatusUpdate.setUpdateTime(new Date());
basePalletMapper.updateTBasePallet(palletStatusUpdate);
}
}
}
}
}
// else {
// TMiStock tMiStock = new TMiStock();
// tMiStock.setStorageId(storageId);
// tMiStock.setCtl(ctl);
// tMiStock.setStatus("0");
// tMiStockMapper.updateSts(tMiStock);
// }
//查询通知单是否已经全部出库完成
TCkOrderdetail tCkOrderdetail = new TCkOrderdetail();
tCkOrderdetail.setOrderId(id);
List<TCkOrderdetail> tCkOrderdetails = tCkOrderdetailMapper.selectTCkOrderdetailList(tCkOrderdetail);
boolean isExist = false;
for(TCkOrderdetail tCkOrderdetail1:tCkOrderdetails){
if(!"2".equals(tCkOrderdetail1.getConfirmStatus())){
isExist = true;
TCkOrderdetail orderDetailStatusQuery = new TCkOrderdetail();
orderDetailStatusQuery.setOrderId(outboundOrderId);
List<TCkOrderdetail> currentOrderDetailList = tCkOrderdetailMapper.selectTCkOrderdetailList(orderDetailStatusQuery);
boolean hasUnconfirmedOrderDetail = false;
for (TCkOrderdetail orderDetail : currentOrderDetailList) {
if (!OutboundConfirmStatus.COMPLETED.getCode().equals(orderDetail.getConfirmStatus())) {
hasUnconfirmedOrderDetail = true;
break;
}
}
//删除出库通知单 备份出库通知单
TCkOrders tCkOrders = tCkOrdersMapper.selectTCkOrdersById(id);
if(!isExist){
TckOrdersBak tckOrdersBak =new TckOrdersBak();
BeanUtils.copyProperties(tCkOrders,tckOrdersBak);
LambdaQueryWrapper<TCkOrderdetail> queryWrapper1 = new LambdaQueryWrapper<>();
queryWrapper1.eq(TCkOrderdetail::getOrderId,id);
List<TCkOrderdetail> tckOrderdetailList = tCkOrderdetailMapper.selectList(queryWrapper1);
// List<TCkOrderdetail> tckOrderdetailList = tCkOrders.getTckOrderdetailList();
List<TckOrderdetailBak> bakList = new ArrayList<>();
for(TCkOrderdetail tCkOrderdetail1 : tckOrderdetailList){
TckOrderdetailBak tckOrderdetailBak = new TckOrderdetailBak();
BeanUtils.copyProperties(tCkOrderdetail1,tckOrderdetailBak);
TCkOrders outboundOrder = tCkOrdersMapper.selectTCkOrdersById(outboundOrderId);
if (!hasUnconfirmedOrderDetail) {
TckOrdersBak outboundOrderBackup = new TckOrdersBak();
BeanUtils.copyProperties(outboundOrder, outboundOrderBackup);
LambdaQueryWrapper<TCkOrderdetail> orderDetailByOrderQueryWrapper = new LambdaQueryWrapper<>();
orderDetailByOrderQueryWrapper.eq(TCkOrderdetail::getOrderId, outboundOrderId);
List<TCkOrderdetail> outboundOrderDetailList = tCkOrderdetailMapper.selectList(orderDetailByOrderQueryWrapper);
List<TckOrderdetailBak> orderDetailBackupList = new ArrayList<>();
for (TCkOrderdetail outboundOrderDetail : outboundOrderDetailList) {
TckOrderdetailBak orderDetailBackup = new TckOrderdetailBak();
BeanUtils.copyProperties(outboundOrderDetail, orderDetailBackup);
//存储审核人和审核时间
tckOrderdetailBak.setAuditDate(tCkOrders.getAuditDate());
tckOrderdetailBak.setAuditMan(tCkOrders.getAuditMan());
tckOrderdetailBak.setApplicant(tCkOrders.getApplicant());
tckOrderdetailBak.setRejectReason(tCkOrders.getRejectReason());
bakList.add(tckOrderdetailBak);
orderDetailBackup.setAuditDate(outboundOrder.getAuditDate());
orderDetailBackup.setAuditMan(outboundOrder.getAuditMan());
orderDetailBackup.setApplicant(outboundOrder.getApplicant());
orderDetailBackup.setRejectReason(outboundOrder.getRejectReason());
orderDetailBackupList.add(orderDetailBackup);
}
tckOrdersBak.setTckOrderdetailBakList(bakList);
tckOrdersBakService.insertTckOrdersBak(tckOrdersBak);
outboundOrderBackup.setTckOrderdetailBakList(orderDetailBackupList);
tckOrdersBakService.insertTckOrdersBak(outboundOrderBackup);
//删除
tCkOrdersMapper.deleteTCkOrdersById(id);
tCkOrdersMapper.deleteTCkOrderdetailByOrderId(id);
tCkOrdersMapper.deleteTCkOrdersById(outboundOrderId);
tCkOrdersMapper.deleteTCkOrderdetailByOrderId(outboundOrderId);
//用于发送设备
tCkOrders.setTckOrderdetailList(tckOrderdetailList);
outboundOrder.setTckOrderdetailList(outboundOrderDetailList);
// 关闭出库通知单任务消息
// TCallNoticeOrder tCallNotice = new TCallNoticeOrder();
// tCallNotice.setTaskId(tCkOrders.getOrderId());
// tCallNotice.setTaskType("0");
// tCallNotice.setUpdateBy(SecurityUtils.getUsername());
// tCallNotice.setUpdateTime(new Date());
// tNoticeOrderService.updateTaskStatus(tCallNotice);
TCallNoticeOrder callNoticeOrder = new TCallNoticeOrder();
callNoticeOrder.setTaskId(outboundOrder.getOrderId());
callNoticeOrder.setTaskType("0");
callNoticeOrder.setUpdateBy(SecurityUtils.getUsername());
callNoticeOrder.setUpdateTime(new Date());
tNoticeOrderService.updateTaskStatus(callNoticeOrder);
}else{
tCkOrders.setConfirmStatus("1");
tCkOrdersMapper.updateConfirmStatus(tCkOrders);
} else {
outboundOrder.setConfirmStatus(OutboundConfirmStatus.PARTIAL.getCode());
tCkOrdersMapper.updateConfirmStatus(outboundOrder);
}
// 2. 删除原有出库任务
for(TCkPickingwavegoods tCkPickingwavegoods : goodsList) {
tCkPickingwavegoods.setConfirmStatus("2");
tCkPickingwavegoodsMapper.deleteGoods(tCkPickingwavegoods);
for (TCkPickingwavegoods pickingTask : goodsList) {
pickingTask.setConfirmStatus(OutboundPickingTaskStatus.DISPATCHED_TO_PLC.getCode());
tCkPickingwavegoodsMapper.deleteGoods(pickingTask);
}
if (!StringUtils.isEmpty(callNoticeId)) {
TCkPickingwavegoods tCkPgoods = new TCkPickingwavegoods();
tCkPgoods.setCallNoticeId(callNoticeId);
List<TCkPickingwavegoods> tCkPickingwavegoodList = tCkPickingwavegoodsMapper.selectTCkPickingwavegoodsList(tCkPgoods);
if (!StringUtils.isEmpty(outboundCallNoticeId)) {
TCkPickingwavegoods callNoticePickingTaskQuery = new TCkPickingwavegoods();
callNoticePickingTaskQuery.setCallNoticeId(outboundCallNoticeId);
List<TCkPickingwavegoods> remainingCallNoticeTaskList = tCkPickingwavegoodsMapper.selectTCkPickingwavegoodsList(callNoticePickingTaskQuery);
// 不存在该呼叫任务号的出库任务全部出库
if (tCkPickingwavegoodList.size() == 0) {
if (remainingCallNoticeTaskList.isEmpty()) {
// 关闭出库任务通知
TCallNotice tCallNotice = new TCallNotice();
tCallNotice.setId(callNoticeId);
tCallNotice.setTaskType("1");
tCallNotice.setUpdateBy(SecurityUtils.getUserNick());
tCallNotice.setUpdateTime(new Date());
tNoticeService.updateTaskStatus(tCallNotice);
TCallNotice callNoticeStatusUpdate = new TCallNotice();
callNoticeStatusUpdate.setId(outboundCallNoticeId);
callNoticeStatusUpdate.setTaskType(NoticeTaskType.OUTBOUND.getCode());
callNoticeStatusUpdate.setUpdateBy(SecurityUtils.getUserNick());
callNoticeStatusUpdate.setUpdateTime(new Date());
tNoticeService.updateTaskStatus(callNoticeStatusUpdate);
//发送设备
String s = sendDevice(tCkOrders);
if (s.equals("推送成功出库完成")){
String devicePushResult = sendDevice(outboundOrder);
if (devicePushResult.equals("推送成功出库完成")) {
return 1;
}else {
} else {
return 0;
}
}
}
return 1;
}
@Log(title = "设备管理系统数据推送",businessType = BusinessType.TUISONG)
@Log(title = "设备管理系统数据推送", businessType = BusinessType.TUISONG)
public String sendDevice(TCkOrders tCkOrders) {
// 获取签名
String sign = StringUtils.EMPTY;
String datalinkSign = StringUtils.EMPTY;
try {
sign = SignTool.generateSign(DeviceInfo.AKSKID, DeviceInfo.AK, DeviceInfo.SK);
datalinkSign = SignTool.generateSign(DeviceInfo.AKSKID, DeviceInfo.AK, DeviceInfo.SK);
} catch (Exception e) {
e.printStackTrace();
logger.error("出库完成,产生签名失败,无法发送设备平台==>>>{}", tCkOrders);
@ -950,116 +944,116 @@ public class TCkPickingwavegoodsServiceImpl extends ServiceImpl<TCkPickingwavego
}
// 设置请求头
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json;charset=UTF-8");
headers.put("Datalink-Sign", sign);
headers.put("datalink-region", "SA");
Map<String, String> devicePushRequestHeaders = new HashMap<>();
devicePushRequestHeaders.put("Content-Type", "application/json;charset=UTF-8");
devicePushRequestHeaders.put("Datalink-Sign", datalinkSign);
devicePushRequestHeaders.put("datalink-region", "SA");
// 设置请求体
Map<String, Object> reqMap = new HashMap<>();
reqMap.put("workSpaceId", DeviceInfo.WORKSPACEID);
reqMap.put("appId", DeviceInfo.APPID);
reqMap.put("formId", DeviceInfo.FORMID);
reqMap.put("primaryValidate", DeviceInfo.PRIMARYVALIDATE);
reqMap.put("terminal", DeviceInfo.terminal);
reqMap.put("permissionGroupId", DeviceInfo.permissionGroupId);
Map<String, Object> devicePushRequestBody = new HashMap<>();
devicePushRequestBody.put("workSpaceId", DeviceInfo.WORKSPACEID);
devicePushRequestBody.put("appId", DeviceInfo.APPID);
devicePushRequestBody.put("formId", DeviceInfo.FORMID);
devicePushRequestBody.put("primaryValidate", DeviceInfo.PRIMARYVALIDATE);
devicePushRequestBody.put("terminal", DeviceInfo.terminal);
devicePushRequestBody.put("permissionGroupId", DeviceInfo.permissionGroupId);
List<Map<String, Object>> dataList = new ArrayList<>();
for (TCkOrderdetail orderDetail : tCkOrders.getTckOrderdetailList()) {
Map<String, Object> objMap = new HashMap<>();
Map<String, Object> dataMap = new HashMap<>();
List<Map<String, Object>> devicePushEntityList = new ArrayList<>();
for (TCkOrderdetail outboundOrderDetail : tCkOrders.getTckOrderdetailList()) {
Map<String, Object> entityRequestItem = new HashMap<>();
Map<String, Object> entityFieldValueMap = new HashMap<>();
//物料编码
dataMap.put("16762714231051e323", orderDetail.getGoodsId());
entityFieldValueMap.put("16762714231051e323", outboundOrderDetail.getGoodsId());
//物料名称
dataMap.put("16730628000781fffc",orderDetail.getGoodsName());
entityFieldValueMap.put("16730628000781fffc", outboundOrderDetail.getGoodsName());
//物料分类
dataMap.put("168630280159119fd9","橡塑制品");
entityFieldValueMap.put("168630280159119fd9", "橡塑制品");
//出库单编号 主表id
dataMap.put("167996646260610a52",orderDetail.getOrderId());
entityFieldValueMap.put("167996646260610a52", outboundOrderDetail.getOrderId());
//出库单日期
dataMap.put("167996676942815d49", DateUtil.formatDate(tCkOrders.getRecordDate()));
entityFieldValueMap.put("167996676942815d49", DateUtil.formatDate(tCkOrders.getRecordDate()));
// 批次号 168221810201118f6b
//dataMap.put("168221810201118f6b",orderDetail.getBatchNo());
dataMap.put("168221810201118f6b","2306120198-00012308110001");
//entityFieldValueMap.put("168221810201118f6b", outboundOrderDetail.getBatchNo());
entityFieldValueMap.put("168221810201118f6b", "2306120198-00012308110001");
//
// 数量 16799843524131dcef
dataMap.put("16799843524131dcef",orderDetail.getTrNum());
entityFieldValueMap.put("16799843524131dcef", outboundOrderDetail.getTrNum());
// 成本单价() 167996659624410000
dataMap.put("167996659624410000",orderDetail.getPrice());
entityFieldValueMap.put("167996659624410000", outboundOrderDetail.getPrice());
// 成本金额() 167996659930419d98
dataMap.put("167996659930419d98",0);
entityFieldValueMap.put("167996659930419d98", 0);
// 含税单价() 16799666417161c2df
dataMap.put("16799666417161c2df",0);
entityFieldValueMap.put("16799666417161c2df", 0);
// 含税金额() 16799666405351ad3e
dataMap.put("16799666405351ad3e",0);
entityFieldValueMap.put("16799666405351ad3e", 0);
// 单位 167627140151616e43
dataMap.put("167627140151616e43",orderDetail.getUnit());
entityFieldValueMap.put("167627140151616e43", outboundOrderDetail.getUnit());
// 规格说明 16885354383311f996
dataMap.put("16885354383311f996",orderDetail.getSpecification());
entityFieldValueMap.put("16885354383311f996", outboundOrderDetail.getSpecification());
// 供应商 16885286378311586a
dataMap.put("16885286378311586a",orderDetail.getProviderId());
entityFieldValueMap.put("16885286378311586a", outboundOrderDetail.getProviderId());
// 仓库 167996683943010c1c
dataMap.put("167996683943010c1c",orderDetail.getStorageId());
entityFieldValueMap.put("167996683943010c1c", outboundOrderDetail.getStorageId());
// 物料来源 168852880606217e05
if(StringUtils.isBlank(orderDetail.getOriginal())){
dataMap.put("168852880606217e05","仓储系统");
}else{
dataMap.put("168852880606217e05",orderDetail.getOriginal());
if (StringUtils.isBlank(outboundOrderDetail.getOriginal())) {
entityFieldValueMap.put("168852880606217e05", "仓储系统");
} else {
entityFieldValueMap.put("168852880606217e05", outboundOrderDetail.getOriginal());
}
// 税率 6uqmar
dataMap.put("6uqmar",0);
entityFieldValueMap.put("6uqmar", 0);
// 申请人 168852830803817e1c
// dataMap.put("168852830803817e1c",tCkOrders.getApplicant());
dataMap.put("168852830803817e1c","lannanceshi");
// entityFieldValueMap.put("168852830803817e1c", tCkOrders.getApplicant());
entityFieldValueMap.put("168852830803817e1c", "lannanceshi");
// 维修中心 8uv8xq
dataMap.put("8uv8xq","东区维修中心");
entityFieldValueMap.put("8uv8xq", "东区维修中心");
// 包机组 2usyjy 待测试
dataMap.put("2usyjy","第一包机组");
entityFieldValueMap.put("2usyjy", "第一包机组");
// 领料部门 16885281379451def6
dataMap.put("16885281379451def6",null);
entityFieldValueMap.put("16885281379451def6", null);
// 领料时间 1upjlj
dataMap.put("1upjlj",tCkOrders.getOrderDate());
objMap.put("entityData",dataMap);
dataList.add(objMap);
entityFieldValueMap.put("1upjlj", tCkOrders.getOrderDate());
entityRequestItem.put("entityData", entityFieldValueMap);
devicePushEntityList.add(entityRequestItem);
}
reqMap.put("data", dataList);
devicePushRequestBody.put("data", devicePushEntityList);
// 将请求体转换为 JSON 字符串
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = null;
ObjectMapper jsonObjectMapper = new ObjectMapper();
String requestBodyJson = null;
try {
jsonString = objectMapper.writeValueAsString(reqMap);
requestBodyJson = jsonObjectMapper.writeValueAsString(devicePushRequestBody);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
System.out.println(jsonString);
System.out.println(requestBodyJson);
String ip = "https://iepm.rzport.com:38443/datalinkprobackend/aksk/formentity/entityManagement/batchSaveEntity";
String deviceSystemPushUrl = "https://iepm.rzport.com:38443/datalinkprobackend/aksk/formentity/entityManagement/batchSaveEntity";
try {
JSONObject result = HttpUtils.post(ip, jsonString, headers);
String code = result.containsKey("code") ? result.getStr("code") : "500";
String errMsg = result.containsKey("msg") ? result.getStr("msg") : "未知错误";
JSONObject devicePushResponse = HttpUtils.post(deviceSystemPushUrl, requestBodyJson, devicePushRequestHeaders);
String responseCode = devicePushResponse.containsKey("code") ? devicePushResponse.getStr("code") : "500";
String responseMessage = devicePushResponse.containsKey("msg") ? devicePushResponse.getStr("msg") : "未知错误";
// 记录日志
DeviceLog deviceLog = new DeviceLog();
deviceLog.setCode(code);
deviceLog.setMsg(errMsg);
deviceLog.setOrders(tCkOrders.getId());
deviceLog.setObj(jsonString);
deviceLogMapper.insertDeviceLog(deviceLog);
DeviceLog devicePushLog = new DeviceLog();
devicePushLog.setCode(responseCode);
devicePushLog.setMsg(responseMessage);
devicePushLog.setOrders(tCkOrders.getId());
devicePushLog.setObj(requestBodyJson);
deviceLogMapper.insertDeviceLog(devicePushLog);
} catch (Exception e) {
// 处理超时或其他异常
DeviceLog deviceLog = new DeviceLog();
deviceLog.setCode("500");
deviceLog.setMsg("请求超时或失败");
deviceLog.setOrders(tCkOrders.getId());
deviceLog.setObj(jsonString);
deviceLogMapper.insertDeviceLog(deviceLog);
DeviceLog failedDevicePushLog = new DeviceLog();
failedDevicePushLog.setCode("500");
failedDevicePushLog.setMsg("请求超时或失败");
failedDevicePushLog.setOrders(tCkOrders.getId());
failedDevicePushLog.setObj(requestBodyJson);
deviceLogMapper.insertDeviceLog(failedDevicePushLog);
logger.error("请求失败: {}", e.getMessage());
return "出库完成,请求超时或失败";
}
@ -1067,29 +1061,24 @@ public class TCkPickingwavegoodsServiceImpl extends ServiceImpl<TCkPickingwavego
}
/**
* 更新库存
* @param tCkPickingwavegoods
*/
private void updateTmiStock(TCkPickingwavegoods tCkPickingwavegoods) {
if(StringUtils.isBlank(tCkPickingwavegoods.getDoctNumber())){
throw new RuntimeException("出库任务库存ID为空异常请传入库存ID");
}
TMiStock tMiStock = tMiStockMapper.selectById(tCkPickingwavegoods.getDoctNumber());
if (StringUtils.isBlank(tCkPickingwavegoods.getDoctNumber())) {
throw new RuntimeException("出库任务库存ID为空异常请传入库存ID");
}
TMiStock stockRecord = tMiStockMapper.selectById(tCkPickingwavegoods.getDoctNumber());
if (tCkPickingwavegoods.getRecNum() == null) tCkPickingwavegoods.setRecNum(BigDecimal.ZERO);
tMiStock.setShelvesNum(tMiStock.getShelvesNum().subtract(tCkPickingwavegoods.getRecNum()));
tMiStock.setUpdateTime(DateUtils.getNowDate());
tMiStock.setUpdateBy(SecurityUtils.getUserNick());
if(tMiStock.getShelvesNum().compareTo(BigDecimal.ZERO) == 0){
tMiStockMapper.deleteById(tMiStock);
}else{
tMiStock.setStatus("0");
tMiStock.setOccupyNum(BigDecimal.ZERO);
tMiStockMapper.updateById(tMiStock);
}
stockRecord.setShelvesNum(stockRecord.getShelvesNum().subtract(tCkPickingwavegoods.getRecNum()));
stockRecord.setUpdateTime(DateUtils.getNowDate());
stockRecord.setUpdateBy(SecurityUtils.getUserNick());
if (stockRecord.getShelvesNum().compareTo(BigDecimal.ZERO) == 0) {
tMiStockMapper.deleteById(stockRecord);
} else {
stockRecord.setStatus(OutboundResourceLockStatus.UNLOCKED.getCode());
stockRecord.setOccupyNum(BigDecimal.ZERO);
tMiStockMapper.updateById(stockRecord);
}
}
}

View File

@ -507,10 +507,10 @@
<select id="selectgoodsByCtl" parameterType="String" resultMap="TCkPickingwavegoodsResult">
<include refid="selectTCkPickingwavegoodsVo"/>
<where>
<if test="ctl != null and ctl != ''"> and ctl = #{ctl}</if>
<if test="locationId != null and locationId != ''"> and location_id = #{locationId}</if>
<if test="confirmStatus != null and confirmStatus != ''"> and confirm_status = #{confirmStatus}</if>
<if test="plcId != null and plcId != ''"> and plc_id = #{plcId}</if>
<if test="ctl != null and ctl != ''">and ctl = #{ctl}</if>
<if test="locationId != null and locationId != ''">and location_id = #{locationId}</if>
<if test="confirmStatus != null and confirmStatus != ''">and confirm_status = #{confirmStatus}</if>
<if test="plcId != null and plcId != ''">and plc_id = #{plcId}</if>
</where>
</select>
<update id="updatePlcId" parameterType="TCkPickingwavegoods">