Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
孙克
/
smf-core
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit 0f5ffa54
由
zshaohui
编写于
2024-08-23 13:25:22 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
1.单据领料,逻辑修改
2.单据转库,可以多个箱子进行转库
1 个父辈
b1fb2e17
隐藏空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
547 行增加
和
187 行删除
src/main/java/com/neotel/smfcore/core/order/LiteOrderCache.java
src/main/java/com/neotel/smfcore/custom/luxsan/api/LuxsanApi.java
src/main/java/com/neotel/smfcore/custom/luxsan/api/bean/request/TicketGbPostRequest.java
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/bean/TicketOut.java
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/controller/AgvDeviceController.java
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/controller/BoxTransferController.java
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/controller/LineController.java
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/controller/TakeOutController.java
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/controller/WipStorCheckOutController.java
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/kafka/service/KafkaService.java
src/main/resources/config/application-21088prod.yml
src/main/resources/config/application-21088test.yml
src/main/java/com/neotel/smfcore/core/order/LiteOrderCache.java
查看文件 @
0f5ffa5
...
@@ -437,38 +437,6 @@ public class LiteOrderCache {
...
@@ -437,38 +437,6 @@ public class LiteOrderCache {
}
}
}
}
finishedOrderTasks
(
order
);
finishedOrderTasks
(
order
);
//如果是单据领料的话,一盘都没有出的,通知wms,缺料
if
(
LiteorderCheckType
.
TICKET_CHECKOUT
==
order
.
getCheckType
())
{
List
<
LiteOrderItem
>
orderItems
=
order
.
getOrderItems
();
for
(
LiteOrderItem
orderItem
:
orderItems
)
{
if
(
orderItem
.
getTotalOutNum
()
<=
0
)
{
log
.
info
(
"行号:"
+
orderItem
.
getTicketItem
()+
",单据号:"
+
orderItem
.
getTicketCode
()+
",发料数量为0,通知wms缺料"
);
try
{
String
binCode
=
""
;
Map
<
String
,
String
>
binCacheMap
=
BinCacheUtil
.
binCodeCacheMap
(
orderItem
.
getSrcWarehouse
(),
""
);
for
(
String
code
:
binCacheMap
.
keySet
())
{
binCode
=
code
;
break
;
}
TicketPickRequest
request
=
new
TicketPickRequest
();
request
.
setBIN_CODE
(
binCode
);
request
.
setLABEL_LIST
(
new
ArrayList
<>());
request
.
setPLANT_CODE
(
CommonUtil
.
plantCode
);
request
.
setQTY
(
0
);
request
.
setTICKET_CODE
(
orderItem
.
getTicketCode
());
request
.
setTICKET_ITEM
(
orderItem
.
getTicketItem
());
LuxsanApi
.
ticketPick
(
request
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
log
.
info
(
"行号:"
+
orderItem
.
getTicketItem
()+
",单据号:"
+
orderItem
.
getTicketCode
()+
",通知缺料失败:"
+
e
.
getMessage
());
}
}
}
}
}
}
liteOrderManager
.
save
(
order
);
liteOrderManager
.
save
(
order
);
liteOrderMap
.
put
(
orderNo
,
order
);
liteOrderMap
.
put
(
orderNo
,
order
);
...
@@ -1273,7 +1241,7 @@ public class LiteOrderCache {
...
@@ -1273,7 +1241,7 @@ public class LiteOrderCache {
}
}
public
synchronized
void
wipTicketOut
(
String
orderNo
,
boolean
isHold
)
{
public
void
wipTicketOut
(
String
orderNo
,
boolean
isHold
,
List
<
StoragePos
>
storagePosList
)
{
LiteOrder
cacheOrder
=
liteOrderMap
.
get
(
orderNo
);
LiteOrder
cacheOrder
=
liteOrderMap
.
get
(
orderNo
);
if
(
cacheOrder
==
null
)
{
if
(
cacheOrder
==
null
)
{
cacheOrder
=
liteOrderManager
.
findByOrderNo
(
orderNo
);
cacheOrder
=
liteOrderManager
.
findByOrderNo
(
orderNo
);
...
@@ -1297,7 +1265,7 @@ public class LiteOrderCache {
...
@@ -1297,7 +1265,7 @@ public class LiteOrderCache {
log
.
info
(
"开始执行工单:"
+
orderNo
);
log
.
info
(
"开始执行工单:"
+
orderNo
);
cacheOrder
.
setTaskReelCount
(
0
);
cacheOrder
.
setTaskReelCount
(
0
);
cacheOrder
.
setFinishedReelCount
(
0
);
cacheOrder
.
setFinishedReelCount
(
0
);
cacheOrder
.
setStatus
(
LITEORDER_STATUS
.
TAILS
);
CHECKOUT_TYPE
checkoutType
=
dataCache
.
getCheckOutType
();
CHECKOUT_TYPE
checkoutType
=
dataCache
.
getCheckOutType
();
List
<
String
>
storageIdList
=
new
ArrayList
<>();
List
<
String
>
storageIdList
=
new
ArrayList
<>();
...
@@ -1305,102 +1273,206 @@ public class LiteOrderCache {
...
@@ -1305,102 +1273,206 @@ public class LiteOrderCache {
storageIdList
.
add
(
storage
.
getId
());
storageIdList
.
add
(
storage
.
getId
());
}
}
int
taskReelCount
=
0
;
//查找是否为Hold的料箱
List
<
String
>
holdPosIdList
=
getHoldPosIdList
(
cacheOrder
);
//如果是hold的,判断有没有符合的条件
List
<
StoragePos
>
holdPosList
=
getHoldPosList
(
cacheOrder
);
List
<
StoragePos
>
holdPosList
=
new
ArrayList
<>();
List
<
String
>
holdPosIdList
=
new
ArrayList
<>();
for
(
LiteOrderItem
orderItem
:
cacheOrder
.
getOrderItems
())
{
List
<
FetchHoldInfoResult
>
resultList
=
LuxsanApi
.
fetchHoldInfo
(
new
FetchHoldInfoRequest
(
CommonUtil
.
plantCode
,
orderItem
.
getSrcWarehouse
(),
orderItem
.
getPn
()));
if
(
resultList
!=
null
&&
!
resultList
.
isEmpty
())
{
List
<
String
>
palletIdList
=
resultList
.
stream
().
map
(
FetchHoldInfoResult:
:
getPALLET_ID
).
collect
(
Collectors
.
toList
());
List
<
Criteria
>
orCriterialList
=
Lists
.
newArrayList
();
orCriterialList
.
add
(
Criteria
.
where
(
"barcode.barcode"
).
in
(
palletIdList
));
orCriterialList
.
add
(
Criteria
.
where
(
"barcode.palletId"
).
in
(
palletIdList
));
Criteria
c
=
new
Criteria
().
orOperator
(
orCriterialList
);
List
<
StoragePos
>
posList
=
storagePosManager
.
findByQuery
(
new
Query
(
c
));
if
(
posList
!=
null
&&
!
posList
.
isEmpty
())
{
for
(
StoragePos
pos
:
posList
)
{
holdPosList
.
add
(
pos
);
holdPosIdList
.
add
(
pos
.
getId
());
}
}
}
}
List
<
DataLog
>
dataLogList
=
new
ArrayList
<>();
for
(
LiteOrderItem
orderItem
:
cacheOrder
.
getOrderItems
())
{
for
(
LiteOrderItem
orderItem
:
cacheOrder
.
getOrderItems
())
{
String
partNumber
=
orderItem
.
getPn
();
int
taskNum
=
0
;
int
remainNum
=
orderItem
.
getNeedNum
()
-
orderItem
.
getTotalOutNum
();
int
remainNum
=
orderItem
.
getNeedNum
()
-
orderItem
.
getTotalOutNum
();
if
(
remainNum
<=
0
)
{
continue
;
}
String
pn
=
orderItem
.
getPn
();
String
warehouseCode
=
orderItem
.
getSrcWarehouse
();
while
(
taskNum
<
remainNum
)
{
//不出Hold的,就满足数量才可以出,出Hold,只要有,就可以出,不卡控数量
log
.
info
(
"当前分配的数量为:"
+
taskNum
+
",剩余数量为:"
+
remainNum
);
if
(!
isHold
)
{
Collection
<
String
>
excludePosIds
=
excludeOutPosIds
();
List
<
StoragePos
>
needOutPosList
=
new
ArrayList
<>();
if
(
storagePosList
!=
null
&&
!
storagePosList
.
isEmpty
())
{
//1.先从执行的料箱中出库
for
(
StoragePos
storagePos
:
storagePosList
)
{
StoragePos
pos
=
null
;
Barcode
barcode
=
storagePos
.
getBarcode
();
String
loc
=
TaskLocUtil
.
MW
;
if
(
barcode
.
getPartNumber
().
equals
(
pn
)
&&
barcode
.
getWarehouseCode
().
equals
(
warehouseCode
))
{
if
(
isHold
)
{
if
(
holdPosIdList
!=
null
&&
!
holdPosIdList
.
isEmpty
())
{
if
(
holdPosList
!=
null
&&
!
holdPosList
.
isEmpty
())
{
if
(
holdPosIdList
.
contains
(
storagePos
.
getId
()))
{
for
(
StoragePos
storagePos
:
holdPosList
)
{
throw
new
ValidateException
(
""
,
barcode
.
getPalletId
()
+
"被hold,不允许出库"
);
if
(
excludePosIds
.
contains
(
storagePos
.
getId
()))
{
}
continue
;
}
}
Barcode
barcode
=
storagePos
.
getBarcode
();
if
(
dataLogList
!=
null
&&
!
dataLogList
.
isEmpty
())
{
if
(
partNumber
.
equals
(
barcode
.
getPartNumber
()))
{
for
(
DataLog
dataLog
:
dataLogList
)
{
if
(
orderItem
.
getSrcWarehouse
().
equals
(
barcode
.
getWarehouseCode
()))
{
if
(
storagePos
.
getId
().
equals
(
dataLog
.
getPosId
()))
{
pos
=
storagePos
;
log
.
info
(
storagePos
.
getPosName
()
+
"已经在任务列表中,跳过"
);
break
;
continue
;
//throw new ValidateException("", barcode.getPalletId()+"已在任务列表中,不允许出库");;
}
}
}
}
}
needOutPosList
.
add
(
storagePos
);
}
}
}
}
}
else
{
excludePosIds
.
addAll
(
holdPosIdList
);
pos
=
storagePosManager
.
findPartNumberInStorages
(
storageIdList
,
partNumber
,
excludePosIds
,
checkoutType
,
orderItem
.
getBrand
(),
orderItem
.
getSrcWarehouse
());
}
}
if
(
pos
==
null
)
{
break
;
if
(
needOutPosList
!=
null
&&
!
needOutPosList
.
isEmpty
())
{
}
else
{
List
<
Barcode
>
barcodeList
=
needOutPosList
.
stream
().
map
(
StoragePos:
:
getBarcode
).
collect
(
Collectors
.
toList
());
int
count
=
barcodeList
.
stream
().
collect
(
Collectors
.
summingInt
(
Barcode:
:
getQty
));
if
(
count
>
remainNum
)
{
throw
new
ValidateException
(
""
,
"手动输入的料箱号数量为:"
+
count
+
"大于实际需要的数量:"
+
remainNum
+
"料号为:"
+
pn
+
"库别为:"
+
warehouseCode
);
}
remainNum
=
(
remainNum
-
count
);
}
if
(
remainNum
>
0
)
{
Collection
<
String
>
excludePosIds
=
excludeOutPosIds
();
if
(
dataLogList
!=
null
&&
!
dataLogList
.
isEmpty
())
{
for
(
DataLog
dataLog
:
dataLogList
)
{
excludePosIds
.
add
(
dataLog
.
getId
());
}
}
if
(
holdPosIdList
!=
null
&&
!
holdPosIdList
.
isEmpty
())
{
for
(
String
holdPosId
:
holdPosIdList
)
{
excludePosIds
.
add
(
holdPosId
);
}
}
//查找符合条件的库位
Criteria
c
=
Criteria
.
where
(
"barcode.partNumber"
).
is
(
pn
)
.
and
(
"id"
).
nin
(
excludePosIds
)
.
and
(
"enabled"
).
is
(
true
)
.
and
(
"storageId"
).
in
(
storageIdList
)
.
and
(
"barcode.warehouseCode"
).
is
(
warehouseCode
);
List
<
StoragePos
>
posList
=
storagePosManager
.
findByQuery
(
new
Query
(
c
));
if
(
posList
==
null
||
posList
.
isEmpty
())
{
throw
new
ValidateException
(
""
,
"料号:"
+
pn
+
",库别:"
+
warehouseCode
+
"未找到可用出库的物料"
);
}
List
<
StoragePos
>
targetPos
=
findTargetPos
(
posList
,
remainNum
);
if
(
targetPos
==
null
||
targetPos
.
isEmpty
())
{
throw
new
ValidateException
(
""
,
"料号:"
+
pn
+
",库别:"
+
warehouseCode
+
"未找到符合出库的组合"
);
}
needOutPosList
.
addAll
(
targetPos
);
}
for
(
StoragePos
pos
:
needOutPosList
)
{
Storage
storage
=
dataCache
.
getStorageById
(
pos
.
getStorageId
());
Barcode
barcode
=
pos
.
getBarcode
();
Barcode
barcode
=
pos
.
getBarcode
();
log
.
info
(
barcode
.
getBarcode
()
+
"需要生成出库任务,工单号为:"
+
orderNo
);
DataLog
dataLog
=
new
DataLog
(
storage
,
barcode
,
pos
);
taskNum
=
taskNum
+
barcode
.
getQty
();
dataLog
.
setSubSourceId
(
orderItem
.
getId
());
taskReelCount
=
taskReelCount
+
1
;
dataLog
.
setSourceName
(
cacheOrder
.
getOrderNo
());
DataLog
task
=
newTask
(
pos
);
dataLog
.
setSourceId
(
cacheOrder
.
getId
());
task
.
setSourceId
(
cacheOrder
.
getId
());
dataLog
.
setStatus
(
OP_STATUS
.
WAIT
.
name
());
task
.
setSourceName
(
cacheOrder
.
getOrderNo
());
dataLog
.
setType
(
OP
.
CHECKOUT
);
task
.
setSubSourceId
(
orderItem
.
getId
());
dataLog
.
setLoc
(
TaskLocUtil
.
OUT
);
task
.
setSubSourceInfo
(
orderItem
.
getFeederInfo
());
if
(
StringUtils
.
isNotEmpty
(
barcode
.
getCartonId
()))
{
task
.
setType
(
OP
.
CHECKOUT
);
dataLog
.
setCartonId
(
barcode
.
getCartonId
());
task
.
setStatus
(
OP_STATUS
.
WAIT
.
name
());
}
task
.
setLoc
(
loc
);
dataLog
.
setOdn
(
true
);
dataLogList
.
add
(
dataLog
);
}
}
else
{
int
taskNum
=
0
;
while
(
taskNum
<
remainNum
)
{
log
.
info
(
"当前分配的数量为:"
+
taskNum
+
",剩余数量为:"
+
remainNum
);
if
(
StringUtils
.
isNotEmpty
(
barcode
.
getCartonId
())){
Collection
<
String
>
excludePosIds
=
excludeOutPosIds
();
task
.
setCartonId
(
barcode
.
getCartonId
());
if
(
dataLogList
!=
null
&&
!
dataLogList
.
isEmpty
())
{
for
(
DataLog
dataLog
:
dataLogList
)
{
excludePosIds
.
add
(
dataLog
.
getId
());
}
}
}
taskService
.
addTaskToExecute
(
task
);
boolean
hasTask
=
false
;
if
(
storagePosList
!=
null
&&
!
storagePosList
.
isEmpty
())
{
for
(
StoragePos
pos
:
storagePosList
)
{
Barcode
barcode
=
pos
.
getBarcode
();
if
(
barcode
.
getPartNumber
().
equals
(
pn
)
&&
barcode
.
getWarehouseCode
().
equals
(
warehouseCode
))
{
if
(
holdPosIdList
!=
null
&&
!
holdPosIdList
.
isEmpty
())
{
if
(!
holdPosIdList
.
contains
(
pos
.
getId
()))
{
throw
new
ValidateException
(
""
,
barcode
.
getPalletId
()
+
"不是hold,不允许出库"
);
}
}
if
(
dataLogList
!=
null
&&
!
dataLogList
.
isEmpty
())
{
for
(
DataLog
dataLog
:
dataLogList
)
{
if
(
pos
.
getId
().
equals
(
dataLog
.
getPosId
()))
{
log
.
info
(
pos
.
getPosName
()
+
"已经在任务列表中,跳过"
);
continue
;
//throw new ValidateException("", barcode.getPalletId()+"已在任务列表中,不允许出库");;
}
}
}
hasTask
=
true
;
taskNum
=
taskNum
+
barcode
.
getQty
();
//生成出库任务
Storage
storage
=
dataCache
.
getStorageById
(
pos
.
getStorageId
());
DataLog
dataLog
=
new
DataLog
(
storage
,
barcode
,
pos
);
dataLog
.
setSourceId
(
cacheOrder
.
getId
());
dataLog
.
setSourceName
(
cacheOrder
.
getOrderNo
());
dataLog
.
setSubSourceId
(
orderItem
.
getId
());
dataLog
.
setSubSourceInfo
(
orderItem
.
getFeederInfo
());
dataLog
.
setType
(
OP
.
CHECKOUT
);
dataLog
.
setStatus
(
OP_STATUS
.
WAIT
.
name
());
dataLog
.
setLoc
(
TaskLocUtil
.
MW
);
dataLogList
.
add
(
dataLog
);
}
}
}
if
(!
hasTask
)
{
StoragePos
pos
=
null
;
if
(
holdPosList
!=
null
&&
!
holdPosList
.
isEmpty
())
{
for
(
StoragePos
storagePos
:
holdPosList
)
{
if
(
excludePosIds
.
contains
(
storagePos
.
getId
()))
{
continue
;
}
Barcode
barcode
=
storagePos
.
getBarcode
();
if
(
pn
.
equals
(
barcode
.
getPartNumber
()))
{
if
(
orderItem
.
getSrcWarehouse
().
equals
(
barcode
.
getWarehouseCode
()))
{
pos
=
storagePos
;
break
;
}
}
}
}
if
(
pos
==
null
)
{
break
;
}
Storage
storage
=
dataCache
.
getStorageById
(
pos
.
getStorageId
());
Barcode
barcode
=
pos
.
getBarcode
();
taskNum
=
taskNum
+
barcode
.
getQty
();
DataLog
dataLog
=
new
DataLog
(
storage
,
barcode
,
pos
);
dataLog
.
setSourceId
(
cacheOrder
.
getId
());
dataLog
.
setSourceName
(
cacheOrder
.
getOrderNo
());
dataLog
.
setSubSourceId
(
orderItem
.
getId
());
dataLog
.
setSubSourceInfo
(
orderItem
.
getFeederInfo
());
dataLog
.
setType
(
OP
.
CHECKOUT
);
dataLog
.
setStatus
(
OP_STATUS
.
WAIT
.
name
());
dataLog
.
setLoc
(
TaskLocUtil
.
MW
);
dataLogList
.
add
(
dataLog
);
}
}
}
}
}
}
}
if
(
taskReelCount
<=
0
)
{
if
(
dataLogList
==
null
||
dataLogList
.
isEmpty
()
)
{
log
.
info
(
"工单:"
+
orderNo
+
"没有找到对应的任务"
);
log
.
info
(
"工单:"
+
orderNo
+
"没有找到对应的任务"
);
finishedOrderTasks
(
cacheOrder
);
//
finishedOrderTasks(cacheOrder);
throw
new
ValidateException
(
"smfcore.order.out.noTask"
,
"工单无可执行的任务"
);
throw
new
ValidateException
(
"smfcore.order.out.noTask"
,
"工单无可执行的任务"
);
}
}
cacheOrder
.
setTaskReelCount
(
taskReelCount
);
taskService
.
batchSave
(
dataLogList
);
cacheOrder
.
setStatus
(
LITEORDER_STATUS
.
TAILS
);
cacheOrder
.
setTaskReelCount
(
dataLogList
.
size
());
liteOrderManager
.
save
(
cacheOrder
);
liteOrderManager
.
save
(
cacheOrder
);
liteOrderMap
.
put
(
cacheOrder
.
getOrderNo
(),
cacheOrder
);
liteOrderMap
.
put
(
cacheOrder
.
getOrderNo
(),
cacheOrder
);
log
.
info
(
"生成工单"
+
orderNo
+
"任务结束,数量为:"
+
dataLogList
.
size
());
log
.
info
(
"生成工单"
+
orderNo
+
"任务结束,数量为:"
+
taskReelCount
);
}
}
public
synchronized
void
odnCheckOut
(
String
orderNo
,
List
<
StoragePos
>
storagePosList
)
{
public
synchronized
void
odnCheckOut
(
String
orderNo
,
List
<
StoragePos
>
storagePosList
)
{
...
@@ -1554,82 +1626,100 @@ public class LiteOrderCache {
...
@@ -1554,82 +1626,100 @@ public class LiteOrderCache {
cacheOrder
=
liteOrderManager
.
findByOrderNo
(
orderNo
);
cacheOrder
=
liteOrderManager
.
findByOrderNo
(
orderNo
);
}
}
if
(
cacheOrder
==
null
)
{
if
(
cacheOrder
==
null
)
{
log
.
info
(
"未找到
单据
:"
+
orderNo
+
"的信息"
);
log
.
info
(
"未找到
工单
:"
+
orderNo
+
"的信息"
);
throw
new
ValidateException
(
"
"
,
"未找到单据
"
);
throw
new
ValidateException
(
"
smfcore.order.out.notFound"
,
"未找到工单
"
);
}
}
if
(
cacheOrder
.
isClosed
())
{
if
(
cacheOrder
.
isClosed
())
{
log
.
info
(
"
单据
:"
+
orderNo
+
"已经关闭"
);
log
.
info
(
"
工单
:"
+
orderNo
+
"已经关闭"
);
throw
new
ValidateException
(
"
"
,
"单据
已关闭"
);
throw
new
ValidateException
(
"
smfcore.order.hasClose"
,
"工单
已关闭"
);
}
}
if
(!
cacheOrder
.
isTaskFinished
()
&&
!
cacheOrder
.
isNew
())
{
if
(!
cacheOrder
.
isTaskFinished
()
&&
!
cacheOrder
.
isNew
())
{
log
.
info
(
"
单据
:"
+
orderNo
+
"正在执行中"
);
log
.
info
(
"
工单
:"
+
orderNo
+
"正在执行中"
);
throw
new
ValidateException
(
"
"
,
"单据
正在执行"
);
throw
new
ValidateException
(
"
smfcore.order.out.executing"
,
"工单
正在执行"
);
}
}
log
.
info
(
"开始执行工单:"
+
orderNo
);
log
.
info
(
"开始执行工单:"
+
orderNo
);
cacheOrder
.
setTaskReelCount
(
0
);
cacheOrder
.
setTaskReelCount
(
0
);
cacheOrder
.
setFinishedReelCount
(
0
);
cacheOrder
.
setFinishedReelCount
(
0
);
cacheOrder
.
setStatus
(
LITEORDER_STATUS
.
TAILS
);
CHECKOUT_TYPE
checkoutType
=
dataCache
.
getCheckOutType
();
List
<
Storage
>
storageList
=
new
ArrayList
<>();
List
<
String
>
storageIdList
=
new
ArrayList
<>();
List
<
String
>
storageIdList
=
new
ArrayList
<>();
for
(
Storage
storage
:
dataCache
.
getAllStorage
().
values
())
{
for
(
Storage
storage
:
dataCache
.
getAllStorage
().
values
())
{
storageIdList
.
add
(
storage
.
getId
());
storageIdList
.
add
(
storage
.
getId
());
storageList
.
add
(
storage
);
}
}
int
taskReelCount
=
0
;
List
<
DataLog
>
dataLogList
=
new
ArrayList
<>();
//转库可以出hold,置为空
//List<String> holdPosIdList = getHoldPosIdList(cacheOrder);
List
<
String
>
holdPosIdList
=
new
ArrayList
<>();
for
(
LiteOrderItem
orderItem
:
cacheOrder
.
getOrderItems
())
{
for
(
LiteOrderItem
orderItem
:
cacheOrder
.
getOrderItems
())
{
int
taskNum
=
0
;
int
remainNum
=
orderItem
.
getNeedNum
()
-
orderItem
.
getTotalOutNum
();
int
remainNum
=
orderItem
.
getNeedNum
()
-
orderItem
.
getTotalOutNum
();
if
(
remainNum
<=
0
)
{
if
(
remainNum
<=
0
)
{
continue
;
continue
;
}
}
Collection
<
String
>
excludePosIds
=
excludeOutPosIds
();
//找到hold的
if
(
holdPosIdList
!=
null
&&
!
holdPosIdList
.
isEmpty
())
{
excludePosIds
.
addAll
(
holdPosIdList
);
}
String
pn
=
orderItem
.
getPn
();
String
pn
=
orderItem
.
getPn
();
String
warehouseCode
=
orderItem
.
getSrcWarehouse
();
String
warehouseCode
=
orderItem
.
getSrcWarehouse
();
while
(
taskNum
<
remainNum
)
{
List
<
StoragePos
>
needOutPosList
=
new
ArrayList
<>();
StoragePos
pos
=
null
;
if
(
storagePosList
!=
null
&&
!
storagePosList
.
isEmpty
())
{
if
(
storagePosList
!=
null
&&
!
storagePosList
.
isEmpty
())
{
for
(
StoragePos
storagePos
:
storagePosList
)
{
for
(
StoragePos
storagePos
:
storagePosList
)
{
Barcode
barcode
=
storagePos
.
getBarcode
();
if
(
excludePosIds
.
contains
(
storagePos
.
getId
()))
{
if
(
barcode
.
getPartNumber
().
equals
(
pn
)
&&
barcode
.
getWarehouseCode
().
equals
(
warehouseCode
))
{
continue
;
if
(
dataLogList
!=
null
&&
!
dataLogList
.
isEmpty
())
{
}
for
(
DataLog
dataLog
:
dataLogList
)
{
Barcode
barcode
=
storagePos
.
getBarcode
();
if
(
storagePos
.
getId
().
equals
(
dataLog
.
getPosId
()))
{
if
(
barcode
.
getPartNumber
().
equals
(
pn
)
||
barcode
.
getPn
().
equals
(
pn
))
{
log
.
info
(
storagePos
.
getPosName
()
+
"已经在任务列表中,跳过"
);
if
(
warehouseCode
.
equals
(
barcode
.
getWarehouseCode
()))
{
continue
;
pos
=
storagePos
;
}
break
;
}
}
}
}
needOutPosList
.
add
(
storagePos
);
}
}
}
}
if
(
pos
==
null
)
{
}
log
.
info
(
orderNo
+
"需要的库别为:"
+
orderItem
.
getSrcWarehouse
());
pos
=
storagePosManager
.
findPartNumberInStorages
(
storageIdList
,
pn
,
excludePosIds
,
checkoutType
,
orderItem
.
getBrand
(),
orderItem
.
getSrcWarehouse
());
if
(
needOutPosList
!=
null
&&
!
needOutPosList
.
isEmpty
())
{
List
<
Barcode
>
barcodeList
=
needOutPosList
.
stream
().
map
(
StoragePos:
:
getBarcode
).
collect
(
Collectors
.
toList
());
int
count
=
barcodeList
.
stream
().
collect
(
Collectors
.
summingInt
(
Barcode:
:
getQty
));
if
(
count
>
remainNum
)
{
throw
new
ValidateException
(
""
,
"手动输入的料箱号数量为:"
+
count
+
"大于实际需要的数量:"
+
remainNum
+
"料号为:"
+
pn
+
"库别为:"
+
warehouseCode
);
}
}
if
(
pos
==
null
)
{
remainNum
=
(
remainNum
-
count
);
break
;
}
}
else
{
if
(
remainNum
>
0
)
{
Collection
<
String
>
excludePosIds
=
excludeOutPosIds
();
if
(
dataLogList
!=
null
&&
!
dataLogList
.
isEmpty
())
{
for
(
DataLog
dataLog
:
dataLogList
)
{
excludePosIds
.
add
(
dataLog
.
getId
());
}
}
//查找符合条件的库位
Criteria
c
=
Criteria
.
where
(
"barcode.partNumber"
).
is
(
pn
)
.
and
(
"id"
).
nin
(
excludePosIds
)
.
and
(
"enabled"
).
is
(
true
)
.
and
(
"storageId"
).
in
(
storageIdList
)
.
and
(
"barcode.warehouseCode"
).
is
(
warehouseCode
);
List
<
StoragePos
>
posList
=
storagePosManager
.
findByQuery
(
new
Query
(
c
));
if
(
posList
==
null
||
posList
.
isEmpty
())
{
throw
new
ValidateException
(
""
,
"料号:"
+
pn
+
",库别:"
+
warehouseCode
+
"未找到可用出库的物料"
);
}
if
(
posList
==
null
||
posList
.
isEmpty
())
{
throw
new
ValidateException
(
""
,
"料号:"
+
pn
+
",库别:"
+
warehouseCode
+
"未找到可用出库的物料"
);
}
List
<
StoragePos
>
targetPos
=
findTargetPos
(
posList
,
remainNum
);
if
(
targetPos
==
null
||
targetPos
.
isEmpty
())
{
throw
new
ValidateException
(
""
,
"料号:"
+
pn
+
",库别:"
+
warehouseCode
+
"未找到符合出库的组合"
);
}
needOutPosList
.
addAll
(
targetPos
);
for
(
StoragePos
pos
:
needOutPosList
)
{
Barcode
barcode
=
pos
.
getBarcode
();
Barcode
barcode
=
pos
.
getBarcode
();
log
.
info
(
barcode
.
getBarcode
()
+
"需要生成出库任务,工单号为:"
+
orderNo
);
log
.
info
(
barcode
.
getBarcode
()
+
"需要生成出库任务,工单号为:"
+
orderNo
);
taskNum
=
taskNum
+
barcode
.
getQty
();
taskReelCount
=
taskReelCount
+
1
;
DataLog
task
=
newTask
(
pos
);
DataLog
task
=
newTask
(
pos
);
task
.
setSourceId
(
cacheOrder
.
getId
());
task
.
setSourceId
(
cacheOrder
.
getId
());
task
.
setSourceName
(
cacheOrder
.
getOrderNo
());
task
.
setSourceName
(
cacheOrder
.
getOrderNo
());
...
@@ -1637,29 +1727,43 @@ public class LiteOrderCache {
...
@@ -1637,29 +1727,43 @@ public class LiteOrderCache {
task
.
setSubSourceInfo
(
orderItem
.
getFeederInfo
());
task
.
setSubSourceInfo
(
orderItem
.
getFeederInfo
());
task
.
setType
(
OP
.
CHECKOUT
);
task
.
setType
(
OP
.
CHECKOUT
);
task
.
setStatus
(
OP_STATUS
.
WAIT
.
name
());
task
.
setStatus
(
OP_STATUS
.
WAIT
.
name
());
task
.
setLoc
(
TaskLocUtil
.
MW
);
task
.
setTicketCode
(
orderNo
);
task
.
setTicketCode
(
orderNo
);
task
.
setTicketItem
(
orderItem
.
getTicketItem
());
task
.
setTicketItem
(
orderItem
.
getTicketItem
());
task
.
setSourceType
(
LiteorderCheckType
.
TICKET_TRANSFER_CHECKOUT
+
""
);
task
.
setSourceType
(
LiteorderCheckType
.
TICKET_TRANSFER_CHECKOUT
+
""
);
task
.
setCartonId
(
barcode
.
getCartonId
());
if
(
StringUtils
.
isNotEmpty
(
barcode
.
getCartonId
()))
{
task
.
setCartonId
(
barcode
.
getCartonId
());
//获取目的库别
String
targetWarhouseCode
=
StringUtils
.
isNotEmpty
(
orderItem
.
getDstWarehouse
())
?
orderItem
.
getDstWarehouse
()
:
orderItem
.
getSrcWarehouse
();
task
.
setWarehouseCode
(
targetWarhouseCode
);
barcode
.
setWarehouseCode
(
targetWarhouseCode
);
StoragePos
newPos
=
taskService
.
findEmptyPosForPutIn
(
storageList
,
barcode
,
""
,
""
);
if
(
newPos
==
null
)
{
barcode
.
setModelFamily
(
""
);
newPos
=
taskService
.
findEmptyPosForPutIn
(
storageList
,
barcode
,
""
,
""
);
}
}
task
.
setWarehouseCode
(
StringUtils
.
isNotEmpty
(
orderItem
.
getDstWarehouse
())
?
orderItem
.
getDstWarehouse
()
:
orderItem
.
getSrcWarehouse
());
if
(
newPos
==
null
)
{
throw
new
ValidateException
(
""
,
"料号:"
+
pn
+
",库别:"
+
warehouseCode
+
"未找到目的库别:"
+
targetWarhouseCode
+
"的可用库位"
);
taskService
.
addTaskToExecute
(
task
);
}
task
.
setLoc
(
newPos
.
getPosName
());
task
.
updateExtraDataMap
(
"targetPos"
,
newPos
.
getPosName
());
task
.
setOperator
(
SecurityUtils
.
getLoginUsername
()+
"单据转库"
);
dataLogList
.
add
(
task
);
}
}
}
}
}
}
if
(
taskReelCount
<=
0
)
{
if
(
dataLogList
==
null
||
dataLogList
.
isEmpty
()
)
{
log
.
info
(
"工单:"
+
orderNo
+
"
单据
找到对应的任务"
);
log
.
info
(
"工单:"
+
orderNo
+
"
没有
找到对应的任务"
);
finishedOrderTasks
(
cacheOrder
);
//
finishedOrderTasks(cacheOrder);
throw
new
ValidateException
(
"
"
,
"单据
无可执行的任务"
);
throw
new
ValidateException
(
"
smfcore.order.out.noTask"
,
"工单
无可执行的任务"
);
}
}
cacheOrder
.
setTaskReelCount
(
taskReelCount
);
taskService
.
batchSave
(
dataLogList
);
cacheOrder
.
setStatus
(
LITEORDER_STATUS
.
TAILS
);
cacheOrder
.
setTaskReelCount
(
dataLogList
.
size
());
liteOrderManager
.
save
(
cacheOrder
);
liteOrderManager
.
save
(
cacheOrder
);
liteOrderMap
.
put
(
cacheOrder
.
getOrderNo
(),
cacheOrder
);
liteOrderMap
.
put
(
cacheOrder
.
getOrderNo
(),
cacheOrder
);
log
.
info
(
"生成工单"
+
orderNo
+
"任务结束,数量为:"
+
taskReelCount
);
log
.
info
(
"生成工单"
+
orderNo
+
"任务结束,数量为:"
+
dataLogList
.
size
()
);
}
}
...
@@ -2122,10 +2226,10 @@ public class LiteOrderCache {
...
@@ -2122,10 +2226,10 @@ public class LiteOrderCache {
}
}
p
rivate
List
<
String
>
getHoldPosIdList
(
LiteOrder
cacheOrder
)
{
p
ublic
List
<
String
>
getHoldPosIdList
(
LiteOrder
cacheOrder
)
{
//如果是hold的,判断有没有符合的条件
//如果是hold的,判断有没有符合的条件
List
<
String
>
holdPosIdList
=
new
ArrayList
<>();
List
<
String
>
holdPosIdList
=
new
ArrayList
<>();
/*
for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) {
for
(
LiteOrderItem
orderItem
:
cacheOrder
.
getOrderItems
())
{
String
warehouseCode
=
StringUtils
.
isNotEmpty
(
orderItem
.
getSrcWarehouse
())
?
orderItem
.
getSrcWarehouse
()
:
orderItem
.
getWarehouseCode
();
String
warehouseCode
=
StringUtils
.
isNotEmpty
(
orderItem
.
getSrcWarehouse
())
?
orderItem
.
getSrcWarehouse
()
:
orderItem
.
getWarehouseCode
();
...
@@ -2143,10 +2247,36 @@ public class LiteOrderCache {
...
@@ -2143,10 +2247,36 @@ public class LiteOrderCache {
}
}
}
}
}
}
}
*/
}
return
holdPosIdList
;
return
holdPosIdList
;
}
}
public
List
<
StoragePos
>
getHoldPosList
(
LiteOrder
cacheOrder
)
{
//如果是hold的,判断有没有符合的条件
List
<
StoragePos
>
holdPosList
=
new
ArrayList
<>();
for
(
LiteOrderItem
orderItem
:
cacheOrder
.
getOrderItems
())
{
String
warehouseCode
=
StringUtils
.
isNotEmpty
(
orderItem
.
getSrcWarehouse
())
?
orderItem
.
getSrcWarehouse
()
:
orderItem
.
getWarehouseCode
();
List
<
FetchHoldInfoResult
>
resultList
=
LuxsanApi
.
fetchHoldInfo
(
new
FetchHoldInfoRequest
(
CommonUtil
.
plantCode
,
warehouseCode
,
orderItem
.
getPn
()));
if
(
resultList
!=
null
&&
!
resultList
.
isEmpty
())
{
List
<
String
>
palletIdList
=
resultList
.
stream
().
map
(
FetchHoldInfoResult:
:
getPALLET_ID
).
collect
(
Collectors
.
toList
());
List
<
Criteria
>
orCriterialList
=
Lists
.
newArrayList
();
orCriterialList
.
add
(
Criteria
.
where
(
"barcode.barcode"
).
in
(
palletIdList
));
orCriterialList
.
add
(
Criteria
.
where
(
"barcode.palletId"
).
in
(
palletIdList
));
Criteria
c
=
new
Criteria
().
orOperator
(
orCriterialList
);
List
<
StoragePos
>
posList
=
storagePosManager
.
findByQuery
(
new
Query
(
c
));
if
(
posList
!=
null
&&
!
posList
.
isEmpty
())
{
for
(
StoragePos
pos
:
posList
)
{
holdPosList
.
add
(
pos
);
}
}
}
}
return
holdPosList
;
}
private
List
<
StoragePos
>
findTargetPos
(
List
<
StoragePos
>
numbers
,
int
targetNum
)
{
private
List
<
StoragePos
>
findTargetPos
(
List
<
StoragePos
>
numbers
,
int
targetNum
)
{
numbers
.
sort
((
a
,
b
)
->
Integer
.
valueOf
(
b
.
getBarcode
().
getQty
()).
compareTo
(
Integer
.
valueOf
(
a
.
getBarcode
().
getQty
())));
numbers
.
sort
((
a
,
b
)
->
Integer
.
valueOf
(
b
.
getBarcode
().
getQty
()).
compareTo
(
Integer
.
valueOf
(
a
.
getBarcode
().
getQty
())));
//System.out.println(numbers);
//System.out.println(numbers);
...
...
src/main/java/com/neotel/smfcore/custom/luxsan/api/LuxsanApi.java
查看文件 @
0f5ffa5
...
@@ -1175,6 +1175,44 @@ public class LuxsanApi extends DefaultSmfApiListener {
...
@@ -1175,6 +1175,44 @@ public class LuxsanApi extends DefaultSmfApiListener {
}
}
public
static
String
ticketGbPick
(
TicketPickPostRequest
request
)
{
log
.
info
(
"半成品仓,单据转库备料:ticketGbPick接口请求参数为:"
+
JSON
.
toJSONString
(
request
)
+
",地址为:"
+
ticketGbPickUrl
);
String
result
=
""
;
try
{
String
resultStr
=
HttpHelper
.
postJson
(
ticketGbPickUrl
,
request
);
log
.
info
(
"半成品仓,单据转库备料:ticketGbPick接口返回为:"
+
resultStr
);
LuxsanApiResult
apiResult
=
JSONObject
.
parseObject
(
resultStr
,
LuxsanApiResult
.
class
);
if
(
LuxsanApiEnum
.
ERROR
.
equals
(
apiResult
.
getMSGTY
()))
{
result
=
apiResult
.
getMSGTY
();
}
}
catch
(
ApiException
e
)
{
e
.
printStackTrace
();
result
=
e
.
getMessage
();
}
return
result
;
}
public
static
String
ticketGbPost
(
TicketGbPostRequest
request
)
{
log
.
info
(
"半成品仓,单据转库过账:ticketGbPost接口请求参数为:"
+
JSON
.
toJSONString
(
request
)
+
",地址为:"
+
ticketGbPostUrl
);
String
result
=
""
;
try
{
String
resultStr
=
HttpHelper
.
postJson
(
ticketGbPostUrl
,
request
);
log
.
info
(
"半成品仓,单据转库过账:ticketGbPost接口返回为:"
+
resultStr
);
LuxsanApiResult
apiResult
=
JSONObject
.
parseObject
(
resultStr
,
LuxsanApiResult
.
class
);
if
(
LuxsanApiEnum
.
ERROR
.
equals
(
apiResult
.
getMSGTY
()))
{
result
=
apiResult
.
getMSGTY
();
}
}
catch
(
ApiException
e
)
{
e
.
printStackTrace
();
result
=
e
.
getMessage
();
}
return
result
;
}
@Override
@Override
public
void
outTaskStatusChange
(
String
outNotifyUrl
,
DataLog
task
)
{
public
void
outTaskStatusChange
(
String
outNotifyUrl
,
DataLog
task
)
{
//pickingIssue(new PickingIssueRequest());
//pickingIssue(new PickingIssueRequest());
...
@@ -1505,4 +1543,19 @@ public class LuxsanApi extends DefaultSmfApiListener {
...
@@ -1505,4 +1543,19 @@ public class LuxsanApi extends DefaultSmfApiListener {
public
void
setManualPalletUrl
(
String
url
)
{
public
void
setManualPalletUrl
(
String
url
)
{
LuxsanApi
.
manualPalletUrl
=
url
;
LuxsanApi
.
manualPalletUrl
=
url
;
}
}
public
static
String
ticketGbPickUrl
;
@Value
(
"${api.ticketGbPick}"
)
public
void
setTicketGbPickUrl
(
String
url
)
{
LuxsanApi
.
ticketGbPickUrl
=
url
;
}
public
static
String
ticketGbPostUrl
;
@Value
(
"${api.ticketGbPost}"
)
public
void
setTicketGbPostUrl
(
String
url
)
{
LuxsanApi
.
ticketGbPostUrl
=
url
;
}
}
}
src/main/java/com/neotel/smfcore/custom/luxsan/api/bean/request/TicketGbPostRequest.java
0 → 100644
查看文件 @
0f5ffa5
package
com
.
neotel
.
smfcore
.
custom
.
luxsan
.
api
.
bean
.
request
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
@Data
@AllArgsConstructor
public
class
TicketGbPostRequest
{
private
String
PLANT_CODE
;
private
String
TICKET_CODE
;
}
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/bean/TicketOut.java
0 → 100644
查看文件 @
0f5ffa5
package
com
.
neotel
.
smfcore
.
custom
.
luxsan
.
factory_c
.
wipstor
.
bean
;
import
lombok.Data
;
import
java.util.List
;
@Data
public
class
TicketOut
{
private
String
ticket
;
private
boolean
isHold
;
private
List
<
String
>
boxList
;
}
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/controller/AgvDeviceController.java
查看文件 @
0f5ffa5
...
@@ -146,18 +146,6 @@ public class AgvDeviceController {
...
@@ -146,18 +146,6 @@ public class AgvDeviceController {
if
(!
task
.
isOdn
())
{
if
(!
task
.
isOdn
())
{
task
.
setStatus
(
statusStr
);
task
.
setStatus
(
statusStr
);
taskService
.
updateFinishedTask
(
task
);
taskService
.
updateFinishedTask
(
task
);
String
checkType
=
LiteorderCheckType
.
TICKET_TRANSFER_CHECKOUT
+
""
;
if
(
checkType
.
equals
(
task
.
getSourceType
())){
TicketPickPostData
data
=
new
TicketPickPostData
(
task
.
getTicketCode
(),
task
.
getTicketItem
(),
Arrays
.
asList
(
task
.
getCartonId
()));
String
result
=
LuxsanApi
.
ticketPickPost
(
new
TicketPickPostRequest
(
CommonUtil
.
plantCode
,
task
.
getTicketCode
(),
"SWC"
,
Arrays
.
asList
(
data
)));
if
(
StringUtils
.
isEmpty
(
result
))
{
Barcode
barcode
=
barcodeManager
.
findByBarcode
(
task
.
getBarcode
());
if
(
barcode
!=
null
)
{
barcode
.
setWarehouseCode
(
task
.
getWarehouseCode
());
barcodeManager
.
save
(
barcode
);
}
}
}
}
}
}
else
{
}
else
{
task
.
setStatus
(
statusStr
);
task
.
setStatus
(
statusStr
);
...
...
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/controller/BoxTransferController.java
查看文件 @
0f5ffa5
...
@@ -10,6 +10,9 @@ import com.neotel.smfcore.core.barcode.service.po.Barcode;
...
@@ -10,6 +10,9 @@ import com.neotel.smfcore.core.barcode.service.po.Barcode;
import
com.neotel.smfcore.core.device.enums.OP
;
import
com.neotel.smfcore.core.device.enums.OP
;
import
com.neotel.smfcore.core.device.enums.OP_STATUS
;
import
com.neotel.smfcore.core.device.enums.OP_STATUS
;
import
com.neotel.smfcore.core.device.util.DataCache
;
import
com.neotel.smfcore.core.device.util.DataCache
;
import
com.neotel.smfcore.core.order.LiteOrderCache
;
import
com.neotel.smfcore.core.order.service.manager.ILiteOrderManager
;
import
com.neotel.smfcore.core.order.service.po.LiteOrder
;
import
com.neotel.smfcore.core.storage.service.manager.IStoragePosManager
;
import
com.neotel.smfcore.core.storage.service.manager.IStoragePosManager
;
import
com.neotel.smfcore.core.storage.service.po.Storage
;
import
com.neotel.smfcore.core.storage.service.po.Storage
;
import
com.neotel.smfcore.core.storage.service.po.StoragePos
;
import
com.neotel.smfcore.core.storage.service.po.StoragePos
;
...
@@ -18,6 +21,7 @@ import com.neotel.smfcore.core.system.service.po.DataLog;
...
@@ -18,6 +21,7 @@ import com.neotel.smfcore.core.system.service.po.DataLog;
import
com.neotel.smfcore.core.system.util.TaskService
;
import
com.neotel.smfcore.core.system.util.TaskService
;
import
com.neotel.smfcore.custom.luxsan.api.LuxsanApi
;
import
com.neotel.smfcore.custom.luxsan.api.LuxsanApi
;
import
com.neotel.smfcore.custom.luxsan.api.bean.request.PalletUpdateRequest
;
import
com.neotel.smfcore.custom.luxsan.api.bean.request.PalletUpdateRequest
;
import
com.neotel.smfcore.custom.luxsan.api.bean.request.TicketGbPostRequest
;
import
com.neotel.smfcore.custom.luxsan.api.bean.request.TicketPickPostData
;
import
com.neotel.smfcore.custom.luxsan.api.bean.request.TicketPickPostData
;
import
com.neotel.smfcore.custom.luxsan.api.bean.request.TicketPickPostRequest
;
import
com.neotel.smfcore.custom.luxsan.api.bean.request.TicketPickPostRequest
;
import
com.neotel.smfcore.custom.luxsan.factory_c.common.util.CommonUtil
;
import
com.neotel.smfcore.custom.luxsan.factory_c.common.util.CommonUtil
;
...
@@ -55,6 +59,12 @@ public class BoxTransferController {
...
@@ -55,6 +59,12 @@ public class BoxTransferController {
@Autowired
@Autowired
private
IDataLogManager
dataLogManager
;
private
IDataLogManager
dataLogManager
;
@Autowired
private
LiteOrderCache
liteOrderCache
;
@Autowired
private
ILiteOrderManager
liteOrderManager
;
@ApiOperation
(
"料箱从一个库位移到另外一个库位"
)
@ApiOperation
(
"料箱从一个库位移到另外一个库位"
)
@RequestMapping
(
"/boxToOtherPos"
)
@RequestMapping
(
"/boxToOtherPos"
)
@AnonymousAccess
@AnonymousAccess
...
@@ -156,13 +166,30 @@ public class BoxTransferController {
...
@@ -156,13 +166,30 @@ public class BoxTransferController {
taskService
.
updateFinishedTask
(
task
);
taskService
.
updateFinishedTask
(
task
);
}
}
if
(
OP_STATUS
.
FINISHED
.
name
().
equals
(
statusStr
))
{
if
(
OP_STATUS
.
FINISHED
.
name
().
equals
(
statusStr
))
{
Barcode
barcode
=
barcodeManager
.
findByBarcode
(
task
.
getBarcode
());
//判断是否为单据转库的,如果是调用转库接口
String
checkType
=
LiteorderCheckType
.
TICKET_TRANSFER_CHECKOUT
+
""
;
if
(
checkType
.
equals
(
task
.
getSourceType
())){
log
.
info
(
task
.
getBarcode
()+
"为单据转库的料箱,单据号为:"
+
task
.
getSourceName
());
TicketPickPostData
data
=
new
TicketPickPostData
(
task
.
getTicketCode
(),
task
.
getTicketItem
(),
Arrays
.
asList
(
task
.
getCartonId
()));
TicketPickPostRequest
request
=
new
TicketPickPostRequest
(
CommonUtil
.
plantCode
,
task
.
getTicketCode
(),
"SWC"
,
Arrays
.
asList
(
data
));
String
result
=
LuxsanApi
.
ticketGbPick
(
request
);
log
.
info
(
task
.
getBarcode
()+
"单据转库发料结果为:"
+
result
);
if
(
StringUtils
.
isNotEmpty
(
result
)){
return
ResultBean
.
newErrorResult
(-
1
,
""
,
task
.
getBarcode
()+
"转库失败,目的库位为:"
+
task
.
getWarehouseCode
()+
"单据号为:"
+
task
.
getSourceName
());
}
}
task
.
setStatus
(
statusStr
);
task
.
setStatus
(
statusStr
);
taskService
.
moveTaskToFinished
(
task
);
taskService
.
moveTaskToFinished
(
task
);
taskService
.
updateFinishedTask
(
task
);
taskService
.
updateFinishedTask
(
task
);
String
targetPos
=
task
.
getExtraDataMap
(
"targetPos"
).
toString
();
String
targetPos
=
task
.
getExtraDataMap
(
"targetPos"
).
toString
();
StoragePos
pos
=
storagePosManager
.
getByPosName
(
targetPos
);
StoragePos
pos
=
storagePosManager
.
getByPosName
(
targetPos
);
Storage
storage
=
dataCache
.
getStorageById
(
pos
.
getStorageId
());
Storage
storage
=
dataCache
.
getStorageById
(
pos
.
getStorageId
());
Barcode
barcode
=
barcodeManager
.
findByBarcode
(
task
.
getBarcode
());
DataLog
dataLog
=
new
DataLog
(
storage
,
barcode
,
pos
);
DataLog
dataLog
=
new
DataLog
(
storage
,
barcode
,
pos
);
dataLog
.
setType
(
OP
.
PUT_IN
);
dataLog
.
setType
(
OP
.
PUT_IN
);
...
@@ -170,20 +197,43 @@ public class BoxTransferController {
...
@@ -170,20 +197,43 @@ public class BoxTransferController {
dataLog
.
setOperator
(
SecurityUtils
.
getLoginUsername
()+
"手动移库位"
);
dataLog
.
setOperator
(
SecurityUtils
.
getLoginUsername
()+
"手动移库位"
);
dataLog
.
setCartonId
(
barcode
.
getPalletId
());
dataLog
.
setCartonId
(
barcode
.
getPalletId
());
dataLogManager
.
save
(
dataLog
);
dataLogManager
.
save
(
dataLog
);
boxInPos
(
dataLog
);
boxInPos
(
dataLog
,
task
.
getWarehouseCode
());
//如果是单据转库的时候,判断工单是否已经关闭
if
(
checkType
.
equals
(
task
.
getSourceType
())){
String
sourceName
=
task
.
getSourceName
();
LiteOrder
liteOrder
=
liteOrderCache
.
getLiteOrder
(
sourceName
);
if
(
liteOrder
==
null
){
liteOrder
=
liteOrderManager
.
findByOrderNo
(
sourceName
);
}
if
(
liteOrder
!=
null
){
log
.
info
(
task
.
getBarcode
()+
"找到的单据号为:"
+
sourceName
+
",单据是否关闭:"
+
liteOrder
.
isClosed
());
if
(
liteOrder
.
isClosed
()){
log
.
info
(
task
.
getBarcode
()+
"为单据号:"
+
sourceName
+
"为最后一箱,调用单据转库过账"
);
String
result
=
LuxsanApi
.
ticketGbPost
(
new
TicketGbPostRequest
(
CommonUtil
.
plantCode
,
sourceName
));
log
.
info
(
task
.
getBarcode
()+
"调用单据转库过账,单据号为:"
+
sourceName
+
"展示过账结果为:"
+
result
);
if
(
StringUtils
.
isEmpty
(
result
)){
return
ResultBean
.
newErrorResult
(-
1
,
""
,
task
.
getBarcode
()+
"为单据转库最后一箱,单据号为:"
+
sourceName
+
",过账失败:"
+
result
);
}
}
}
}
}
}
}
}
return
ResultBean
.
newOkResult
(
""
);
return
ResultBean
.
newOkResult
(
""
);
}
}
private
void
boxInPos
(
DataLog
queueTask
){
private
void
boxInPos
(
DataLog
queueTask
,
String
warehouseCode
){
Barcode
barcode
=
barcodeManager
.
findByBarcode
(
queueTask
.
getBarcode
());
Barcode
barcode
=
barcodeManager
.
findByBarcode
(
queueTask
.
getBarcode
());
//已完成,加入库存,并且从完成队列中清除
//已完成,加入库存,并且从完成队列中清除
StoragePos
storagePos
=
storagePosManager
.
get
(
queueTask
.
getPosId
());
StoragePos
storagePos
=
storagePosManager
.
get
(
queueTask
.
getPosId
());
if
(
barcode
!=
null
)
{
if
(
barcode
!=
null
)
{
if
(
StringUtils
.
isNotEmpty
(
warehouseCode
))
{
barcode
.
setWarehouseCode
(
warehouseCode
);
}
barcode
.
setUsedCount
(
barcode
.
getUsedCount
()
+
1
);
barcode
.
setUsedCount
(
barcode
.
getUsedCount
()
+
1
);
barcode
.
setPutInTime
(
System
.
currentTimeMillis
(),
true
);
barcode
.
setPutInTime
(
System
.
currentTimeMillis
(),
true
);
barcode
.
setInOpor
(
""
);
barcode
.
setInOpor
(
""
);
...
...
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/controller/LineController.java
查看文件 @
0f5ffa5
...
@@ -298,6 +298,10 @@ public class LineController {
...
@@ -298,6 +298,10 @@ public class LineController {
soureId
=
dataLog
.
getSourceId
();
soureId
=
dataLog
.
getSourceId
();
sourceName
=
dataLog
.
getSourceName
();
sourceName
=
dataLog
.
getSourceName
();
if
(!
dataLog
.
isFinished
()){
if
(!
dataLog
.
isFinished
()){
if
(!
dataLog
.
isOutFromPos
()){
finishedOutTask
(
dataLog
);
dataLog
.
setOutFromPos
(
true
);
}
dataLog
.
setStatus
(
OP_STATUS
.
OUT_ON_LINE
.
name
());
dataLog
.
setStatus
(
OP_STATUS
.
OUT_ON_LINE
.
name
());
taskService
.
moveTaskToFinished
(
dataLog
);
taskService
.
moveTaskToFinished
(
dataLog
);
taskService
.
updateFinishedTask
(
dataLog
);
taskService
.
updateFinishedTask
(
dataLog
);
...
...
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/controller/TakeOutController.java
查看文件 @
0f5ffa5
package
com
.
neotel
.
smfcore
.
custom
.
luxsan
.
factory_c
.
wipstor
.
controller
;
package
com
.
neotel
.
smfcore
.
custom
.
luxsan
.
factory_c
.
wipstor
.
controller
;
import
com.alibaba.fastjson.JSON
;
import
com.neotel.smfcore.common.bean.ResultBean
;
import
com.neotel.smfcore.common.bean.ResultBean
;
import
com.neotel.smfcore.common.exception.ValidateException
;
import
com.neotel.smfcore.common.exception.ValidateException
;
import
com.neotel.smfcore.common.utils.StringUtils
;
import
com.neotel.smfcore.common.utils.StringUtils
;
import
com.neotel.smfcore.core.barcode.service.po.Barcode
;
import
com.neotel.smfcore.core.order.LiteOrderCache
;
import
com.neotel.smfcore.core.order.LiteOrderCache
;
import
com.neotel.smfcore.core.order.service.manager.ILiteOrderManager
;
import
com.neotel.smfcore.core.order.service.manager.ILiteOrderManager
;
import
com.neotel.smfcore.core.order.service.po.LiteOrder
;
import
com.neotel.smfcore.core.order.service.po.LiteOrder
;
import
com.neotel.smfcore.core.order.service.po.LiteOrderItem
;
import
com.neotel.smfcore.core.order.service.po.LiteOrderItem
;
import
com.neotel.smfcore.core.storage.service.manager.IStoragePosManager
;
import
com.neotel.smfcore.core.storage.service.po.StoragePos
;
import
com.neotel.smfcore.core.system.service.po.DataLog
;
import
com.neotel.smfcore.core.system.util.TaskService
;
import
com.neotel.smfcore.custom.luxsan.api.LuxsanApi
;
import
com.neotel.smfcore.custom.luxsan.api.LuxsanApi
;
import
com.neotel.smfcore.custom.luxsan.api.bean.request.FetchMoveTicketRequest
;
import
com.neotel.smfcore.custom.luxsan.api.bean.request.FetchMoveTicketRequest
;
import
com.neotel.smfcore.custom.luxsan.api.bean.result.FetchMoveTicketResult
;
import
com.neotel.smfcore.custom.luxsan.api.bean.result.FetchMoveTicketResult
;
import
com.neotel.smfcore.custom.luxsan.factory_c.rawstor.bean.dto.FetchMoveTicketDto
;
import
com.neotel.smfcore.custom.luxsan.factory_c.rawstor.bean.dto.FetchMoveTicketDto
;
import
com.neotel.smfcore.custom.luxsan.factory_c.common.util.CommonUtil
;
import
com.neotel.smfcore.custom.luxsan.factory_c.common.util.CommonUtil
;
import
com.neotel.smfcore.custom.luxsan.factory_c.wipstor.bean.TicketOut
;
import
com.neotel.smfcore.custom.luxsan.factory_c.wipstor.util.TicketUtil
;
import
com.neotel.smfcore.custom.luxsan.factory_c.wipstor.util.TicketUtil
;
import
com.neotel.smfcore.security.annotation.AnonymousAccess
;
import
com.neotel.smfcore.security.annotation.AnonymousAccess
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.mongodb.core.query.Criteria
;
import
org.springframework.data.mongodb.core.query.Query
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.bind.annotation.RestController
;
...
@@ -36,6 +46,12 @@ public class TakeOutController {
...
@@ -36,6 +46,12 @@ public class TakeOutController {
@Autowired
@Autowired
private
ILiteOrderManager
liteOrderManager
;
private
ILiteOrderManager
liteOrderManager
;
@Autowired
private
IStoragePosManager
storagePosManager
;
@Autowired
private
TaskService
taskService
;
@ApiOperation
(
"拉取单据信息"
)
@ApiOperation
(
"拉取单据信息"
)
@RequestMapping
(
"/fetchTicket"
)
@RequestMapping
(
"/fetchTicket"
)
@AnonymousAccess
@AnonymousAccess
...
@@ -51,17 +67,23 @@ public class TakeOutController {
...
@@ -51,17 +67,23 @@ public class TakeOutController {
@ApiOperation
(
"单据出库"
)
@ApiOperation
(
"单据出库"
)
@RequestMapping
(
"/ticketOut"
)
@RequestMapping
(
"/ticketOut"
)
@AnonymousAccess
@AnonymousAccess
public
ResultBean
ticketOut
(
String
ticket
,
boolean
isHold
)
{
public
synchronized
ResultBean
ticketOut
(
@RequestBody
TicketOut
ticketOut
)
{
log
.
info
(
"半成品仓单据出库:"
+
ticket
);
String
ticket
=
ticketOut
.
getTicket
();
boolean
isHold
=
ticketOut
.
isHold
();
List
<
String
>
boxList
=
ticketOut
.
getBoxList
();
log
.
info
(
"半成品仓261&931单据领用:"
+
ticket
+
",是否hold:"
+
isHold
+
",传入的料箱号为:"
+
JSON
.
toJSONString
(
boxList
));
if
(
StringUtils
.
isEmpty
(
ticket
))
{
throw
new
ValidateException
(
"smfcore.valueCanotNull"
,
"{0}不能为空"
,
new
String
[]{
"单据号"
});
}
if
(
StringUtils
.
isNotEmpty
(
liteOrderCache
.
hasExecutingOrder
()))
{
if
(
StringUtils
.
isNotEmpty
(
liteOrderCache
.
hasExecutingOrder
()))
{
//throw new ValidateException("","有正在执行的工单,不允许恢复");
//throw new ValidateException("","有正在执行的工单,不允许恢复");
return
ResultBean
.
newErrorResult
(-
1
,
""
,
"有正在执行的工单"
+
liteOrderCache
.
hasExecutingOrder
()
+
",请确认"
);
return
ResultBean
.
newErrorResult
(-
1
,
""
,
"有正在执行的工单"
+
liteOrderCache
.
hasExecutingOrder
()
+
",请确认"
);
}
}
if
(
StringUtils
.
isEmpty
(
ticket
))
{
throw
new
ValidateException
(
"smfcore.valueCanotNull"
,
"{0}不能为空"
,
new
String
[]{
"单据号"
});
}
//1.判断单据是否存在
//1.判断单据是否存在
LiteOrder
liteOrder
=
liteOrderCache
.
getOrderSortItems
(
ticket
);
LiteOrder
liteOrder
=
liteOrderCache
.
getOrderSortItems
(
ticket
);
if
(
liteOrder
==
null
)
{
if
(
liteOrder
==
null
)
{
...
@@ -70,7 +92,66 @@ public class TakeOutController {
...
@@ -70,7 +92,66 @@ public class TakeOutController {
liteOrder
=
liteOrderManager
.
createWithItems
(
liteOrder
);
liteOrder
=
liteOrderManager
.
createWithItems
(
liteOrder
);
liteOrderCache
.
addOrderToMap
(
liteOrder
);
liteOrderCache
.
addOrderToMap
(
liteOrder
);
}
}
liteOrderCache
.
wipTicketOut
(
ticket
,
isHold
);
List
<
String
>
holdPosIdList
=
liteOrderCache
.
getHoldPosIdList
(
liteOrder
);
if
(
isHold
){
if
(
holdPosIdList
==
null
||
holdPosIdList
.
isEmpty
()){
return
ResultBean
.
newErrorResult
(-
1
,
""
,
ticket
+
"没有获取到Hold的料箱信息"
);
}
}
//获取箱子信息
List
<
StoragePos
>
storagePosList
=
new
ArrayList
<>();
if
(
boxList
!=
null
&&
!
boxList
.
isEmpty
())
{
for
(
String
palletId
:
boxList
)
{
if
(
StringUtils
.
isEmpty
(
palletId
)){
return
ResultBean
.
newErrorResult
(-
1
,
""
,
"请核实传入的栈板id是否为空"
);
}
//判断在不在库
StoragePos
pos
=
storagePosManager
.
findOne
(
new
Query
(
Criteria
.
where
(
"barcode.palletId"
).
is
(
palletId
)));
if
(
pos
==
null
)
{
return
ResultBean
.
newErrorResult
(-
1
,
""
,
palletId
+
"不在库位中,请核实"
);
}
//判断有没有任务
Barcode
barcode
=
pos
.
getBarcode
();
List
<
DataLog
>
allTasks
=
taskService
.
getAllTasks
();
for
(
DataLog
dataLog
:
allTasks
)
{
if
(
barcode
.
getBarcode
().
equals
(
dataLog
.
getBarcode
())
&&
!
dataLog
.
isFinished
()
&&
!
dataLog
.
isCancel
())
{
return
ResultBean
.
newErrorResult
(-
1
,
""
,
palletId
+
"有正在执行的任务,请核实,料箱号为:"
+
barcode
.
getBarcode
());
}
}
//判断输入的箱子,是否为当前工单所需要的
boolean
hasSame
=
false
;
for
(
LiteOrderItem
orderItem
:
liteOrder
.
getOrderItems
())
{
if
(
barcode
.
getPartNumber
().
equals
(
orderItem
.
getPn
())
||
barcode
.
getPn
().
equals
(
orderItem
.
getPn
()))
{
if
(
StringUtils
.
isNotBlank
(
barcode
.
getWarehouseCode
()))
{
if
(
barcode
.
getWarehouseCode
().
equals
(
orderItem
.
getWarehouseCode
()))
{
hasSame
=
true
;
break
;
}
}
}
}
if
(!
hasSame
)
{
return
ResultBean
.
newErrorResult
(-
1
,
""
,
palletId
+
"不符合当前odn的料号与库别,料箱号为:"
+
barcode
.
getBarcode
());
}
//判断有没有hold
if
(
isHold
){
if
(
holdPosIdList
!=
null
&&
!
holdPosIdList
.
isEmpty
())
{
if
(!
holdPosIdList
.
contains
(
pos
.
getId
()))
{
return
ResultBean
.
newErrorResult
(-
1
,
""
,
palletId
+
"不是hold的,料箱号为:"
+
palletId
);
}
}
}
storagePosList
.
add
(
pos
);
}
}
liteOrderCache
.
wipTicketOut
(
ticket
,
isHold
,
storagePosList
);
return
ResultBean
.
newOkResult
(
""
);
return
ResultBean
.
newOkResult
(
""
);
}
}
}
}
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/controller/WipStorCheckOutController.java
查看文件 @
0f5ffa5
...
@@ -193,7 +193,7 @@ public class WipStorCheckOutController {
...
@@ -193,7 +193,7 @@ public class WipStorCheckOutController {
List
<
DataLog
>
allTasks
=
taskService
.
getAllTasks
();
List
<
DataLog
>
allTasks
=
taskService
.
getAllTasks
();
for
(
DataLog
dataLog
:
allTasks
)
{
for
(
DataLog
dataLog
:
allTasks
)
{
if
(
b
ox
.
startsWith
(
dataLog
.
getBarcode
())
&&
!
dataLog
.
isFinished
()
&&
!
dataLog
.
isCancel
())
{
if
(
b
arcode
.
getBarcode
().
equals
(
dataLog
.
getBarcode
())
&&
!
dataLog
.
isFinished
()
&&
!
dataLog
.
isCancel
())
{
return
ResultBean
.
newErrorResult
(-
1
,
""
,
box
+
"有正在执行的任务,请核实"
);
return
ResultBean
.
newErrorResult
(-
1
,
""
,
box
+
"有正在执行的任务,请核实"
);
}
}
}
}
...
...
src/main/java/com/neotel/smfcore/custom/luxsan/factory_c/wipstor/kafka/service/KafkaService.java
查看文件 @
0f5ffa5
...
@@ -6,9 +6,12 @@ import com.neotel.smfcore.core.barcode.enums.BARCODE_STATUS;
...
@@ -6,9 +6,12 @@ import com.neotel.smfcore.core.barcode.enums.BARCODE_STATUS;
import
com.neotel.smfcore.core.device.enums.OP
;
import
com.neotel.smfcore.core.device.enums.OP
;
import
com.neotel.smfcore.core.device.enums.OP_STATUS
;
import
com.neotel.smfcore.core.device.enums.OP_STATUS
;
import
com.neotel.smfcore.core.device.util.DataCache
;
import
com.neotel.smfcore.core.device.util.DataCache
;
import
com.neotel.smfcore.core.equipment.bean.EquipStatusBean
;
import
com.neotel.smfcore.core.storage.service.manager.IStoragePosManager
;
import
com.neotel.smfcore.core.storage.service.manager.IStoragePosManager
;
import
com.neotel.smfcore.core.storage.service.po.Storage
;
import
com.neotel.smfcore.core.storage.service.po.Storage
;
import
com.neotel.smfcore.core.system.service.manager.IDataLogManager
;
import
com.neotel.smfcore.core.system.service.manager.IDataLogManager
;
import
com.neotel.smfcore.core.system.util.EquipStatusUtil
;
import
com.neotel.smfcore.custom.luxsan.factory_c.wipstor.kafka.bean.Heartbeat
;
import
com.neotel.smfcore.custom.luxsan.factory_c.wipstor.kafka.bean.MachineParameter
;
import
com.neotel.smfcore.custom.luxsan.factory_c.wipstor.kafka.bean.MachineParameter
;
import
com.neotel.smfcore.custom.luxsan.factory_c.wipstor.kafka.bean.MachineParameterData
;
import
com.neotel.smfcore.custom.luxsan.factory_c.wipstor.kafka.bean.MachineParameterData
;
import
com.neotel.smfcore.custom.luxsan.factory_c.wipstor.kafka.config.KafkaConfig
;
import
com.neotel.smfcore.custom.luxsan.factory_c.wipstor.kafka.config.KafkaConfig
;
...
@@ -92,7 +95,18 @@ public class KafkaService {
...
@@ -92,7 +95,18 @@ public class KafkaService {
log
.
info
(
"结束推送原材料仓tower数据"
);
log
.
info
(
"结束推送原材料仓tower数据"
);
}
}
//@Scheduled(fixedRate = 1000 * 10)
public
void
sendHeartbeat
()
{
Heartbeat
heartbeat
=
new
Heartbeat
();
String
dateStr
=
DateUtil
.
format
(
new
Date
(),
"yyyy-MM-dd HH:mm:ss.SSS"
);
heartbeat
.
setOccurrenceTime
(
dateStr
);
heartbeat
.
setMachineID
(
StorageNameConfig
.
semiFinishedTower
);
heartbeat
.
setTopicType
(
KafkaConfig
.
HEARTBEAT_TOPIC
);
String
statusStr
=
JSON
.
toJSONString
(
heartbeat
);
log
.
info
(
"出料口主题为:"
+
KafkaConfig
.
HEARTBEAT_TOPIC
+
"内容为:"
+
statusStr
);
ListenableFuture
future
=
kafkaTemplate
.
send
(
KafkaConfig
.
HEARTBEAT_TOPIC
,
statusStr
);
log
.
info
(
"出料口返回结果为:"
+
JSON
.
toJSONString
(
future
));
}
public
int
getTodayInOutCount
(
List
<
String
>
storageIdList
,
int
type
)
{
public
int
getTodayInOutCount
(
List
<
String
>
storageIdList
,
int
type
)
{
Query
q
=
new
Query
();
Query
q
=
new
Query
();
...
...
src/main/resources/config/application-21088prod.yml
查看文件 @
0f5ffa5
...
@@ -181,3 +181,9 @@ api:
...
@@ -181,3 +181,9 @@ api:
batchCheckReel
:
http://10.68.27.68:8001/Npm/CheckReelBatch
batchCheckReel
:
http://10.68.27.68:8001/Npm/CheckReelBatch
fetchReel
:
http://10.68.30.22:8082/api/mlb/FetchReel
fetchReel
:
http://10.68.30.22:8082/api/mlb/FetchReel
#半成品仓单据转库备料
ticketGbPick
:
http://10.68.30.22:8082/api/mlb/TicketGbPick
#半成品仓单据转库过账
ticketGbPost
:
http://10.68.30.22:8082/api/mlb/TicketGbPost
src/main/resources/config/application-21088test.yml
查看文件 @
0f5ffa5
...
@@ -180,4 +180,10 @@ api:
...
@@ -180,4 +180,10 @@ api:
#批量禁用料
#批量禁用料
batchCheckReel
:
http://10.68.27.68:8001/Npm/CheckReelBatch
batchCheckReel
:
http://10.68.27.68:8001/Npm/CheckReelBatch
fetchReel
:
http://10.42.220.171:8082/api/mlb/FetchReel
\ No newline at end of file
\ No newline at end of file
fetchReel
:
http://10.42.220.171:8082/api/mlb/FetchReel
#半成品仓单据转库备料
ticketGbPick
:
http://10.42.220.171:8082/api/mlb/TicketGbPick
#半成品仓单据转库过账
ticketGbPost
:
http://10.42.220.171:8082/api/mlb/TicketGbPost
\ No newline at end of file
\ No newline at end of file
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论