using System;
|
|
using HH.WCS.Mobox3.AnGang.AppStart;
|
using HH.WCS.Mobox3.AnGang.Consts;
|
using HH.WCS.Mobox3.AnGang.Helper;
|
using HH.WCS.Mobox3.AnGang.Helpers;
|
using HH.WCS.Mobox3.AnGang.Models;
|
|
using Newtonsoft.Json;
|
|
using static HH.WCS.Mobox3.AnGang.Dtos.Request.ErpRequest;
|
using static HH.WCS.Mobox3.AnGang.Dtos.Request.MoboxRequest;
|
using static HH.WCS.Mobox3.AnGang.Dtos.Response.MoboxResponse;
|
|
namespace HH.WCS.Mobox3.AnGang.Services {
|
public class MoboxService {
|
|
/// <summary>
|
/// 产品入库(PDA)
|
/// </summary>
|
/// <param name="model"></param>
|
/// <returns></returns>
|
internal static SimpleResult Inbound(InboundInfo model) {
|
LogHelper.Info("触发API:产品入库(PDA)" + JsonConvert.SerializeObject(model), "API");
|
var db = DbHelper.GetDbClient();
|
var startLoc = new TN_Location();
|
|
try {
|
// 起点位置必须:为空、无锁、启用、属于收发区域
|
startLoc = db.Queryable<TN_Location>().
|
First(a => a.S_CODE == model.StartLoc
|
&& a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y"
|
&& a.S_AREA_CODE == AreaCode.收发区);
|
|
if (startLoc == null) {
|
return BuildSimpleResult(1, $"起点位置{model.StartLoc}不存在!");
|
}
|
|
// 容器 ID 和 物料 ID 未指定,由系统直接生成
|
var cntID = Guid.NewGuid().ToString("D");
|
var CgId = Guid.NewGuid().ToString("D");
|
|
// 初始是没有绑定信息的,先将起点位置与容器绑定,容器与物料绑定
|
var cntLoc = new TN_Loc_Container() {
|
S_LOC_CODE = startLoc.S_CODE,
|
S_CNTR_CODE = cntID,
|
};
|
var cgCnt = new TN_CG_Detail() {
|
S_ITEM_CODE = CgId,
|
S_CNTR_CODE = cntID,
|
};
|
|
var endLoc = "0"; // 假的默认终点地址
|
|
// 指定货位排号(不能为空、空字符串或空格)
|
if (model.Row != null && model.Row.Trim() != "") {
|
endLoc = model.Row; // 用排号字符串当做假地址
|
if (!int.TryParse(model.Row.Trim(), out int row)) {
|
return BuildSimpleResult(2, $"{model.Row} 不合法:无法转成整数类型");
|
}
|
// 货架排号只能是 0 - 8
|
if (row <= 0 || row > 8) {
|
return BuildSimpleResult(2, $"货架号 {model.Row} 必须是1-8之间的整数");
|
}
|
}
|
|
// 无论是否选择终点货架,都等到称重之后再计算终点货位
|
using (var trans = db.Ado.UseTran()) {
|
if (db.Insertable<TN_Loc_Container>(cntLoc).ExecuteCommand() > 0
|
&& db.Insertable<TN_CG_Detail>(cgCnt).ExecuteCommand() > 0) {
|
//创建产品入库任务:创建搬送任务,起点终点容器
|
if (WCSHelper.CreateTask(startLoc.S_CODE, endLoc, TaskName.产品入库, 3, cntID)) {
|
//如果操作TN_Location会造成死锁
|
LocationHelper.LockLoc(startLoc.S_CODE, 2);//起点出库锁,
|
//LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁
|
|
trans.CommitTran();
|
|
return BuildSimpleResult(0, $"生成 产品入库 成功,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc} ,终点货位未指定");
|
}
|
else {
|
trans.RollbackTran();
|
|
return BuildSimpleResult(5, $"生成 产品入库 失败,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc} ,终点货位未指定");
|
}
|
}
|
else {
|
return BuildSimpleResult(6, $"插入表数据失败");
|
}
|
}
|
}
|
catch (Exception ex) {
|
return BuildSimpleResult(1, $"发生了异常:{ex.Message}");
|
}
|
}
|
|
/// <summary>
|
/// PDA选择终点货位
|
/// </summary>
|
/// <param name="model"></param>
|
/// <returns></returns>
|
internal static SimpleResult SelectLocation(SelectLocationInfo model) {
|
LogHelper.Info("触发API:PDA选择终点货位" + JsonConvert.SerializeObject(model), "API");
|
var db = DbHelper.GetDbClient();
|
|
try {
|
// 任务号存在:终点货架和终点位置为空,且任务为产品入库(PDA)
|
//var task = db.Queryable<TN_Task>().First(a => a.S_EQ_NO == model.forklift_no && a.S_END_AREA == "HJQ" && a.S_END_LOC == "0" && a.S_TYPE == "产品入库(PDA)");
|
var task = db.Queryable<TN_Task>()
|
.Where(a => a.S_B_STATE == "取货完成" && a.S_TYPE == TaskName.产品入库)
|
.OrderBy(a => a.T_CREATE, SqlSugar.OrderByType.Desc).First();
|
|
if (task == null) {
|
return BuildSimpleResult(2, $"当前不存在状态为 取货完成 的 产品入库 任务");
|
}
|
|
if (task.S_END_LOC != null && task.S_END_LOC != "0") {
|
return BuildSimpleResult(3, $"该任务已有终点");
|
}
|
|
var cgDetail = db.Queryable<TN_CG_Detail>()
|
.Where(a => a.S_CNTR_CODE == task.S_CNTR_CODE).First();
|
|
if (cgDetail == null) {
|
return BuildSimpleResult(4, $"托盘物料不存在");
|
}
|
|
var endLoc = new TN_Location();
|
if (cgDetail.F_QTY > 1500) {
|
// 重量超过1.5t,需要选择1-3层货架
|
endLoc = db.Queryable<TN_Location>().First(
|
a => a.S_CODE == model.endLoc && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.N_CURRENT_NUM == 0 && a.N_LAYER <= 3 && a.S_AREA_CODE == AreaCode.货架区);
|
}
|
else if (cgDetail.F_QTY > 0) {
|
endLoc = db.Queryable<TN_Location>().First(
|
a => a.S_CODE == model.endLoc && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.N_CURRENT_NUM == 0 && a.S_AREA_CODE == AreaCode.货架区);
|
}
|
else {
|
return BuildSimpleResult(5, $"物料重量信息不合法:{cgDetail.F_QTY}");
|
}
|
|
// 没有符合条件的货位
|
if (endLoc == null) {
|
return BuildSimpleResult(6, $"货位{model.endLoc}不存在,或不满足称重放置要求");
|
}
|
|
// 修改任务终点为PDA指定终点
|
task.S_END_LOC = endLoc.S_CODE;
|
|
using (var trans = db.Ado.UseTran()) {
|
if (db.Updateable<TN_Task>(task).UpdateColumns(a => a.S_END_LOC).ExecuteCommand() > 0) {
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁
|
trans.CommitTran();
|
|
return BuildSimpleResult(0, $"任务{task.S_CODE}修改成功,修改终点位置为{endLoc.S_CODE}");
|
}
|
else {
|
trans.RollbackTran();
|
|
return BuildSimpleResult(7, $"任务{task.S_CODE}修改失败,修改终点位置为{endLoc.S_CODE}");
|
}
|
}
|
}
|
catch (Exception ex) {
|
return BuildSimpleResult(1, $"发生了异常:{ex.Message}");
|
}
|
}
|
|
/// <summary>
|
/// 产品部分出库(WMS)
|
/// </summary>
|
/// <param name="model"></param>
|
/// <returns></returns>
|
internal static SimpleResult PartOutbound(PartOutboundInfo model) {
|
LogHelper.Info("触发API:产品部分出库(WMS)" + JsonConvert.SerializeObject(model), "API");
|
var db = DbHelper.GetDbClient();
|
|
try {
|
// 起点位置:货架(有货、没有锁、已启用)
|
var startLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y");
|
|
if (startLoc == null) {
|
return BuildSimpleResult(2, $"起点位置 {model.startLoc} 不存在或不具备取货要求");
|
}
|
|
var locCtnrRel = db.Queryable<TN_Loc_Container>().First(a => a.S_LOC_CODE == model.startLoc);
|
|
if (locCtnrRel == null) {
|
return BuildSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可出库的物料");
|
}
|
|
var endLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == AreaCode.收发区);
|
|
if (endLoc == null) {
|
return BuildSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件");
|
}
|
|
using (var trans = db.Ado.UseTran()) {
|
// 解绑:起点货位与待搬运容器(不需要手动deleteable操作,内部会自动操作的)
|
if (WCSHelper.CreateTask(startLoc.S_CODE, endLoc.S_CODE, TaskName.产品部分出库, 3, locCtnrRel.S_CNTR_CODE))//创建搬送任务,起点终点容器
|
{//如果操作TN_Location会造成死锁
|
LocationHelper.LockLoc(startLoc.S_CODE, 2);//起点出库锁,
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁
|
|
trans.CommitTran();
|
return BuildSimpleResult(0, $"生成 产品部分出库 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}");
|
}
|
else {
|
trans.RollbackTran();
|
return BuildSimpleResult(5, $"生成 产品部分出库 失败,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}");
|
}
|
}
|
}
|
catch (Exception ex) {
|
return BuildSimpleResult(1, $"发生了异常:{ex.Message}");
|
}
|
}
|
|
/// <summary>
|
/// 产品部分回库(WMS)
|
/// </summary>
|
/// <param name="model"></param>
|
/// <returns></returns>
|
internal static SimpleResult PartInbound(PartInboundInfo model) {
|
LogHelper.Info("触发API:产品部分回库(WMS)" + JsonConvert.SerializeObject(model), "API");
|
var db = DbHelper.GetDbClient();
|
|
try {
|
// 起点位置:取放货区(有货物、没有锁、已启用)
|
var startLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == AreaCode.收发区);
|
if (startLoc == null) {
|
return BuildSimpleResult(2, $"起点位置 {model.startLoc} 不符合回库条件");
|
}
|
|
var locCtnrRel = db.Queryable<TN_Loc_Container>().First(a => a.S_LOC_CODE == model.startLoc);
|
if (locCtnrRel == null) {
|
return BuildSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可回库的物料");
|
}
|
|
// 终点位置:货架(没有货物,没有锁)
|
var endLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y");
|
if (endLoc == null) {
|
return BuildSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件");
|
}
|
|
using (var trans = db.Ado.UseTran()) {
|
// 解绑:起点货位与待搬运容器(不需要手动deleteable操作,内部会自动操作的)
|
if (WCSHelper.CreateTask(startLoc.S_CODE, endLoc.S_CODE, "产品部分入库(WMS)", 3, locCtnrRel.S_CNTR_CODE))//创建搬送任务,起点终点容器
|
{//如果操作TN_Location会造成死锁
|
LocationHelper.LockLoc(startLoc.S_CODE, 2);//起点出库锁,
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁
|
|
trans.CommitTran();
|
return BuildSimpleResult(0, $"生成 产品部分回库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}");
|
}
|
else {
|
trans.RollbackTran();
|
return BuildSimpleResult(5, $"生成 产品部分回库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}");
|
}
|
}
|
}
|
catch (Exception ex) {
|
return BuildSimpleResult(1, $"发生了异常:{ex.Message}");
|
}
|
}
|
|
/// <summary>
|
/// 盘点理货出库(WMS)
|
/// </summary>
|
/// <param name="model"></param>
|
/// <returns></returns>
|
internal static SimpleResult CheckOutbound(CheckOutboundInfo model) {
|
LogHelper.Info("触发API:盘点理货出库(WMS)" + JsonConvert.SerializeObject(model), "API");
|
var db = DbHelper.GetDbClient();
|
|
try {
|
// 起点位置:取放货区(有货物、没有锁、已启用)
|
var startLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == AreaCode.收发区);
|
if (startLoc == null) {
|
return BuildSimpleResult(2, $"起点位置 {model.startLoc} 不符合出库条件");
|
}
|
|
var locCtnrRel = db.Queryable<TN_Loc_Container>().First(a => a.S_LOC_CODE == model.startLoc);
|
if (locCtnrRel == null) {
|
return BuildSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可回库的物料");
|
}
|
|
// 终点位置:货架(没有货物,没有锁)
|
var endLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y");
|
if (endLoc == null) {
|
return BuildSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件");
|
}
|
|
using (var trans = db.Ado.UseTran()) {
|
// 解绑:起点货位与待搬运容器(不需要手动deleteable操作,内部会自动操作的)
|
if (WCSHelper.CreateTask(startLoc.S_CODE, endLoc.S_CODE, "盘点理货出库(WMS)", 3, locCtnrRel.S_CNTR_CODE))//创建搬送任务,起点终点容器
|
{//如果操作TN_Location会造成死锁
|
LocationHelper.LockLoc(startLoc.S_CODE, 2);//起点出库锁,
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁
|
|
trans.CommitTran();
|
return BuildSimpleResult(0, $"生成 盘点理货出库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}");
|
}
|
else {
|
trans.RollbackTran();
|
return BuildSimpleResult(5, $"生成 盘点理货出库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}");
|
}
|
}
|
}
|
catch (Exception ex) {
|
return BuildSimpleResult(1, $"发生了异常:{ex.Message}");
|
}
|
}
|
|
/// <summary>
|
/// 盘点理货回库(WMS)
|
/// </summary>
|
/// <param name="model"></param>
|
/// <returns></returns>
|
internal static SimpleResult CheckInbound(CheckInboundInfo model) {
|
LogHelper.Info("触发API:盘点理货回库(WMS)" + JsonConvert.SerializeObject(model), "API");
|
var db = DbHelper.GetDbClient();
|
|
try {
|
// 起点位置:取放货区(有货物、没有锁、已启用)
|
var startLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == AreaCode.收发区);
|
if (startLoc == null) {
|
return BuildSimpleResult(2, $"起点位置 {model.startLoc} 不符合回库条件");
|
}
|
|
var locCtnrRel = db.Queryable<TN_Loc_Container>().First(a => a.S_LOC_CODE == model.startLoc);
|
if (locCtnrRel == null) {
|
return BuildSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可回库的物料");
|
}
|
|
// 终点位置:货架(没有货物,没有锁)
|
var endLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y");
|
if (endLoc == null) {
|
return BuildSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件");
|
}
|
|
using (var trans = db.Ado.UseTran()) {
|
// 解绑:起点货位与待搬运容器(不需要手动deleteable操作,内部会自动操作的)
|
if (WCSHelper.CreateTask(startLoc.S_CODE, endLoc.S_CODE, "盘点理货回库(WMS)", 3, locCtnrRel.S_CNTR_CODE))//创建搬送任务,起点终点容器
|
{//如果操作TN_Location会造成死锁
|
LocationHelper.LockLoc(startLoc.S_CODE, 2);//起点出库锁,
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁
|
|
trans.CommitTran();
|
return BuildSimpleResult(0, $"生成 盘点理货回库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}");
|
}
|
else {
|
trans.RollbackTran();
|
return BuildSimpleResult(5, $"生成 盘点理货回库(WMS) 成功,容器号{locCtnrRel.S_CNTR_CODE},起点{startLoc.S_CODE},终点{endLoc.S_CODE}");
|
}
|
}
|
}
|
catch (Exception ex) {
|
return BuildSimpleResult(1, $"发生了异常:{ex.Message}");
|
}
|
}
|
}
|
}
|