shgx_tz_mom/ZR.Service/mes/wms/WmPolishInventoryService.cs

733 lines
29 KiB
C#
Raw Normal View History

using System;
2024-11-18 20:13:49 +08:00
using System.Drawing;
2024-10-25 19:01:06 +08:00
using System.Linq;
using System.Threading.Tasks;
using Aliyun.OSS;
2024-10-29 17:35:32 +08:00
using Infrastructure;
using Infrastructure.Attribute;
2024-10-25 19:01:06 +08:00
using Infrastructure.Extensions;
2024-10-29 17:35:32 +08:00
using JinianNet.JNTemplate;
2024-10-25 19:01:06 +08:00
using Microsoft.AspNetCore.DataProtection.KeyManagement;
2024-11-18 20:13:49 +08:00
using Microsoft.AspNetCore.Http.HttpResults;
2024-10-25 19:01:06 +08:00
using Newtonsoft.Json.Linq;
using SqlSugar;
2024-10-29 17:35:32 +08:00
using ZR.Common;
using ZR.Model;
2024-10-25 19:01:06 +08:00
using ZR.Model.MES.qc.DTO;
using ZR.Model.MES.wms;
using ZR.Model.MES.wms.Dto;
2024-10-29 17:35:32 +08:00
using ZR.Model.System;
using ZR.Repository;
2024-10-25 19:01:06 +08:00
using ZR.Service.mes.qc;
using ZR.Service.mes.wms.IService;
2024-10-25 19:01:06 +08:00
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace ZR.Service.mes.wms
{
/// <summary>
/// 工艺路线-抛光 库存表Service业务层处理
/// </summary>
[AppService(
ServiceType = typeof(IWmPolishInventoryService),
ServiceLifetime = LifeTime.Transient
)]
public class WmPolishInventoryService
: BaseService<WmPolishInventory>,
IWmPolishInventoryService
{
/// <summary>
/// 查询工艺路线-抛光 库存表列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
2024-11-18 20:13:49 +08:00
public WmPolishInventoryTableDto GetList(WmPolishInventoryQueryDto parm)
{
2024-11-18 20:13:49 +08:00
var list = Context
.Queryable<WmMaterial>()
.LeftJoin<WmPolishInventory>((m, p) => m.Partnumber == p.Partnumber)
.Distinct()
//.GroupBy((m, p) => p.Partnumber)
.WhereIF(
!string.IsNullOrEmpty(parm.Description),
(m, p) => m.Description.Contains(parm.Description)
)
.WhereIF(
!string.IsNullOrEmpty(parm.Partnumber),
(m, p) => m.Partnumber.Contains(parm.Partnumber)
)
.Where((m, p) => m.Status == 1)
.Where((m, p) => m.Type == 1)
.WhereIF(parm.Status > -1, (m, p) => p.Status == parm.Status)
.WhereIF(parm.Type > 0, (m, p) => p.Type == parm.Type)
.OrderBy((m, p) => m.Description)
.Select(
(m, p) =>
new WmPolishInventoryDto
{
RealQuantity = 0,
Color = m.Color,
Specification = m.Specification,
Description = m.Description,
Id = p.Id,
BlankNum = p.BlankNum,
Partnumber = p.Partnumber,
Quantity = p.Quantity,
MaxNum = p.MaxNum,
MinNum = p.MinNum,
WarnNum = p.WarnNum,
Type = p.Type,
Status = p.Status,
Remark = p.Remark,
CreatedBy = p.CreatedBy,
CreatedTime = p.CreatedTime,
UpdatedBy = p.UpdatedBy,
UpdatedTime = p.UpdatedTime,
}
)
.ToList();
foreach (WmPolishInventoryDto item in list)
{
// 获取实际库存
List<string> partnumbers = new()
{
item.Partnumber
};
Dictionary<string, int> dict = GetBatchPolishRealPartNum(partnumbers);
item.RealQuantity = dict.TryGetValue(item.Partnumber, out int value) ? value : 0;
}
list = list.Where(it => it.RealQuantity != 0 || it.Quantity != 0)
.Where(it => !string.IsNullOrEmpty(it.Partnumber))
.DistinctBy(it => it.Partnumber)
.ToList();
int total = list.Count;
// 仓库总盘点零件数
int StocktakingTotal =
Context.Queryable<WmPolishInventory>().Sum(it => it.Quantity) ?? 0;
// 仓库当前查询盘点零件数
int QuantitySum = list.Sum(it => it.Quantity) ?? 0;
// 仓库当前查询实际零件数
int RealQuantitySum = list.Sum(it => it.RealQuantity);
WmPolishInventoryTableDto response = new()
{
Total = total,
StocktakingTotal = StocktakingTotal,
QuantitySum = QuantitySum,
RealQuantitySum = RealQuantitySum,
Result = list.Skip((parm.PageNum - 1)* parm.PageSize).Take(parm.PageSize).ToList(),
};
return response;
//TODO 历史查询
/*List<string> partnumberByDescription = new();
if (parm != null && !string.IsNullOrEmpty(parm.Description))
{
partnumberByDescription = Context
.Queryable<WmMaterial>()
.Where(it => it.Description.Contains(parm.Description))
.Select(it => it.Partnumber)
.ToList();
}
var predicate = Expressionable
.Create<WmPolishInventory>()
.AndIF(
!string.IsNullOrEmpty(parm.Description),
it => partnumberByDescription.Contains(it.Partnumber)
)
.AndIF(
!string.IsNullOrEmpty(parm.Partnumber),
it => it.Partnumber.Contains(parm.Partnumber)
)
.AndIF(parm.Status > -1, it => it.Status == parm.Status)
.AndIF(parm.Type > 0, it => it.Type == parm.Type);
var response = Queryable()
.Where(predicate.ToExpression())
2024-11-15 18:51:05 +08:00
.OrderByDescending(it => it.Quantity)
.ToPage<WmPolishInventory, WmPolishInventoryDto>(parm);
if (response.Result.Count > 0)
{
foreach (WmPolishInventoryDto item in response.Result)
{
2024-10-25 19:01:06 +08:00
// 获取物料信息
WmMaterial material = Context
.Queryable<WmMaterial>()
.Where(it => it.Partnumber == item.Partnumber)
.Where(it => it.Type == 1)
.Where(it => it.Status == 1)
.First();
if (material == null)
{
item.Description = "此零件号不在物料清单内!";
continue;
}
item.Color = material.Color;
item.Specification = material.Specification;
item.Description = !string.IsNullOrEmpty(material.Description)
? material.Description
: material.ProductName;
2024-10-29 17:35:32 +08:00
// 获取实际库存
List<string> partnumbers = new List<string>();
partnumbers.Add(item.Partnumber);
Dictionary<string, int> dict = GetBatchPolishRealPartNum(partnumbers);
item.RealQuantity = dict.TryGetValue(item.Partnumber, out int value)? value : 0;
}
}
2024-11-18 20:13:49 +08:00
return response;*/
}
/// <summary>
/// 获取详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public WmPolishInventory GetInfo(string Id)
{
var response = Queryable().Where(x => x.Id == Id).First();
return response;
}
/// <summary>
/// 添加工艺路线-抛光 库存表
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public WmPolishInventory AddWmPolishInventory(WmPolishInventory model)
{
return Context.Insertable(model).ExecuteReturnEntity();
}
/// <summary>
/// 修改工艺路线-抛光 库存表
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int UpdateWmPolishInventory(WmPolishInventory model)
{
//var response = Update(w => w.Id == model.Id, it => new WmPolishInventory()
//{
// BlankNum = model.BlankNum,
// Partnumber = model.Partnumber,
// Quantity = model.Quantity,
// MaxNum = model.MaxNum,
// MinNum = model.MinNum,
// WarnNum = model.WarnNum,
// Type = model.Type,
// Status = model.Status,
// Remark = model.Remark,
// CreatedBy = model.CreatedBy,
// CreatedTime = model.CreatedTime,
// UpdatedBy = model.UpdatedBy,
// UpdatedTime = model.UpdatedTime,
//});
//return response;
return Update(model, true);
}
/// <summary>
/// 零件号下拉查询
/// </summary>
/// <param name="query">零件号或描述</param>
/// <returns></returns>
public List<WmMaterialSelectOptions> GetMaterialSelectOption(string query)
{
var predicate = Expressionable
.Create<WmMaterial>()
.Or(it => it.Partnumber.Contains(query))
.Or(it => it.Description.Contains(query))
.Or(it => it.ProductName.Contains(query))
.And(it => it.Type == 1)
.And(it => it.Status == 1);
List<WmMaterialSelectOptions> options = Context
.Queryable<WmMaterial>()
.Where(predicate.ToExpression())
.Select(
(it) =>
new WmMaterialSelectOptions
{
Key = it.Id,
Label = "[ " + it.Partnumber + " ] " + it.Description,
Value = it.Partnumber
}
)
.ToList();
return options;
}
/// <summary>
/// 新增抛光仓库操作记录
/// </summary>
/// <param name="fkInventoryId">抛光仓库主键</param>
/// <param name="code">同批功能识别编号</param>
/// <param name="partnumber">零件号</param>
/// <param name="type">类别</param>
/// <param name="changeQuantity">操作数字</param>
/// <param name="remark">备注</param>
/// <param name="createdBy">创建人</param>
/// <returns></returns>
public int AddPolishRecord(
string fkInventoryId,
string code,
string partnumber,
int type,
int? changeQuantity,
DateTime? actionTime,
string remark,
string createdBy
)
{
WmPolishRecord newPolishRecord =
new()
{
Id = SnowFlakeSingle.Instance.NextId().ToString(),
FkInventoryId = fkInventoryId,
Code = code,
Partnumber = partnumber,
BlankNum = "",
ChangeType = type,
ChangeQuantity = changeQuantity ?? 0,
ActionTime = actionTime,
Status = 1,
Remark = remark,
CreatedBy = createdBy,
CreatedTime = DateTime.Now.ToLocalTime(),
UpdatedBy = createdBy,
UpdatedTime = DateTime.Now.ToLocalTime(),
};
return Context.Insertable(newPolishRecord).ExecuteCommand();
}
public int DoWmPolishWarehousing(WmPolishInventory parm)
{
try
{
Context.Ado.BeginTran();
// 零件号检查
string partnumber = parm.Partnumber;
/*WmMaterial material = Context
.Queryable<WmMaterial>()
.Where(it => it.Partnumber == partnumber)
.Where(it => it.Type == 1)
.Where(it => it.Status == 1)
.First();
if (material == null)
{
Context.Ado.RollbackTran();
throw new Exception("零件号在物料清单未查到,请到物料清单新增零件号记录");
}*/
// 检查是否存在库中
WmPolishInventory polishInventory = Context
.Queryable<WmPolishInventory>()
.Where(it => it.Partnumber == partnumber)
.Where(it => it.Type == parm.Type)
.Where(it => it.Status == 1)
.First();
if (polishInventory == null)
{
// 为空则新增库
WmPolishInventory newWmPolishInventory =
new()
{
Id = SnowFlakeSingle.Instance.NextId().ToString(),
BlankNum = "",
Partnumber = partnumber,
Type = parm.Type,
Quantity = parm.Quantity,
MaxNum = 0,
MinNum = 0,
WarnNum = 0,
Status = 1,
Remark = "系统自动创建库",
CreatedBy = parm.CreatedBy,
CreatedTime = DateTime.Now.ToLocalTime(),
UpdatedBy = parm.CreatedBy,
UpdatedTime = DateTime.Now.ToLocalTime(),
};
WmPolishInventory addWmPolishInventory = Context
.Insertable(newWmPolishInventory)
.ExecuteReturnEntity();
string code = !string.IsNullOrEmpty(parm.WorkOrder)
? parm.WorkOrder
: SnowFlakeSingle.Instance.NextId().ToString();
2024-07-26 17:34:01 +08:00
string remark = "初次创建仓库,新增入库数据 " + parm.Remark;
int successNum = AddPolishRecord(
addWmPolishInventory.Id,
code,
partnumber,
1,
parm.Quantity,
parm.ActionTime,
remark,
parm.CreatedBy
);
if (successNum == 0)
{
Context.Ado.RollbackTran();
throw new Exception("入库日志添加失败");
}
}
else
{
polishInventory.Quantity += parm.Quantity;
int updateNum = Context.Updateable(polishInventory).ExecuteCommand();
if (updateNum == 0)
{
Context.Ado.RollbackTran();
throw new Exception("修改抛光仓库数据失败");
}
// 已有则新增记录
string code = SnowFlakeSingle.Instance.NextId().ToString();
int successNum = AddPolishRecord(
polishInventory.Id,
code,
partnumber,
1,
parm.Quantity,
parm.ActionTime,
2024-07-26 17:34:01 +08:00
parm.Remark,
parm.CreatedBy
);
if (successNum == 0)
{
Context.Ado.RollbackTran();
throw new Exception("入库日志添加失败");
}
}
Context.Ado.CommitTran();
return 1;
}
catch (Exception e)
{
Context.Ado.RollbackTran();
throw new Exception(e.Message);
}
}
2024-07-26 17:34:01 +08:00
public int DoWmPolishRetrieval(WmPolishInventory parm)
{
try
{
Context.Ado.BeginTran();
// 零件号检查
string partnumber = parm.Partnumber;
/*WmMaterial material = Context
2024-07-26 17:34:01 +08:00
.Queryable<WmMaterial>()
.Where(it => it.Partnumber == partnumber)
.Where(it => it.Type == 1)
.Where(it => it.Status == 1)
.First();
if (material == null)
{
Context.Ado.RollbackTran();
throw new Exception("零件号在物料清单未查到,请到物料清单新增零件号记录");
}*/
2024-07-26 17:34:01 +08:00
// 检查是否存在库中
WmPolishInventory polishInventory = Context
.Queryable<WmPolishInventory>()
.Where(it => it.Partnumber == partnumber)
.Where(it => it.Type == parm.Type)
.Where(it => it.Status == 1)
.First();
if (polishInventory == null)
{
// 为空则新增库
WmPolishInventory newWmPolishInventory =
new()
{
Id = SnowFlakeSingle.Instance.NextId().ToString(),
BlankNum = "",
Partnumber = partnumber,
Type = parm.Type,
Quantity = parm.Quantity * -1,
MaxNum = 0,
MinNum = 0,
WarnNum = 0,
Status = 1,
Remark = "系统自动创建库",
CreatedBy = parm.CreatedBy,
CreatedTime = DateTime.Now.ToLocalTime(),
UpdatedBy = parm.CreatedBy,
UpdatedTime = DateTime.Now.ToLocalTime(),
};
WmPolishInventory addWmPolishInventory = Context
.Insertable(newWmPolishInventory)
.ExecuteReturnEntity();
string code = !string.IsNullOrEmpty(parm.WorkOrder)
? parm.WorkOrder
: SnowFlakeSingle.Instance.NextId().ToString();
2024-07-26 17:34:01 +08:00
string remark = "初次创建仓库,新增手动出库数据" + parm.Remark;
int successNum = AddPolishRecord(
addWmPolishInventory.Id,
code,
partnumber,
2,
parm.Quantity,
parm.ActionTime,
remark,
parm.CreatedBy
);
if (successNum == 0)
{
Context.Ado.RollbackTran();
throw new Exception("出库日志添加失败");
}
}
else
{
polishInventory.Quantity -= parm.Quantity;
int updateNum = Context.Updateable(polishInventory).ExecuteCommand();
if (updateNum == 0)
{
Context.Ado.RollbackTran();
throw new Exception("修改抛光仓库零件数失败");
}
// 已有则新增记录
string code = SnowFlakeSingle.Instance.NextId().ToString();
int successNum = AddPolishRecord(
polishInventory.Id,
code,
partnumber,
2,
parm.Quantity,
parm.ActionTime,
parm.Remark,
parm.CreatedBy
);
if (successNum == 0)
{
Context.Ado.RollbackTran();
throw new Exception("出库日志添加失败");
}
}
Context.Ado.CommitTran();
return 1;
}
catch (Exception e)
{
Context.Ado.RollbackTran();
throw new Exception(e.Message);
}
}
public int DoWmPolishStocktaking(WmPolishInventory parm)
{
if (parm.Quantity < 0)
{
throw new Exception("修改的零件数小于0");
}
try
{
Context.Ado.BeginTran();
// 检查是否存在库中
WmPolishInventory polishInventory = Context
.Queryable<WmPolishInventory>()
.Where(it => it.Id == parm.Id)
.Where(it => it.Status == 1)
.First();
if (polishInventory == null)
{
Context.Ado.RollbackTran();
throw new Exception("盘点记录不存在" + parm.Id);
}
Context.Updateable(parm).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommand();
// 已有则新增记录
string code = !string.IsNullOrEmpty(parm.WorkOrder)
? parm.WorkOrder
: SnowFlakeSingle.Instance.NextId().ToString();
int successNum = AddPolishRecord(
parm.Id,
code,
parm.Partnumber,
3,
parm.Quantity,
parm.ActionTime,
2024-07-26 17:34:01 +08:00
parm.Remark,
parm.CreatedBy
);
if (successNum == 0)
{
Context.Ado.RollbackTran();
throw new Exception("盘点日志添加失败");
}
Context.Ado.CommitTran();
return successNum;
}
catch (Exception e)
{
Context.Ado.RollbackTran();
throw new Exception(e.Message);
}
}
// 获取仓库零件数量
public int GetPartNumber()
{
return Context
.Queryable<WmPolishInventory>()
.Where(it => it.Status == 1)
.Sum(it => it.Quantity) ?? 0;
}
2024-10-25 19:01:06 +08:00
// Util 获取物料清单,不包含毛坯
public List<WmMaterial> GetWmMaterialList(string partnumber)
{
// 获取物料信息
return Context
.Queryable<WmMaterial>()
.WhereIF(
!string.IsNullOrEmpty(partnumber),
it => it.Partnumber.Contains(partnumber)
)
.Where(it => !string.IsNullOrEmpty(it.Partnumber))
.Where(it => it.Type == 1)
.Where(it => it.Status == 1)
.Distinct()
.OrderBy(it => it.Description)
.ToList();
}
// 获取Excel导出数据
public List<WmPolishInventoryExportDto> GetExportList(WmPolishInventoryQueryDto parm)
{
try
{
List<WmMaterial> materials = GetWmMaterialList(parm.Partnumber);
// 获取所有partnumber列表
List<string> partnumbers = materials
.Where(it => !string.IsNullOrEmpty(it.Partnumber))
.Select(it => it.Partnumber)
.Distinct()
.ToList();
// 批量获取盘点数和现有库存
Dictionary<string, object> stockNumbers = GetBatchPolishStockPartNum(partnumbers);
Dictionary<string, int> realNumbers = GetBatchPolishRealPartNum(partnumbers);
2024-10-29 17:35:32 +08:00
// 更新盘点时间
DateTime dateTime = DateTime.Now.ToLocalTime();
2024-10-25 19:01:06 +08:00
// 构建导出数据
List<WmPolishInventoryExportDto> exportDto = materials
.Select(it =>
{
bool found1 = stockNumbers.TryGetValue(it.Partnumber, out object value1);
int stockNumber = found1 && value1 != null ? Convert.ToInt32(value1) : 0;
bool found2 = realNumbers.TryGetValue(it.Partnumber, out int realNumber);
return new WmPolishInventoryExportDto
{
= it.Partnumber,
= it.Color,
= it.Specification,
= it.Description,
2024-10-29 17:35:32 +08:00
= dateTime,
2024-10-25 19:01:06 +08:00
= stockNumber,
= found2 ? realNumber : 0,
};
})
.ToList();
return exportDto;
}
catch (Exception e)
{
throw;
}
}
// Util 获取指定抛光库零件盘点库存
public Dictionary<string, object> GetBatchPolishStockPartNum(List<string> partnumbers)
{
return Context
.Queryable<WmPolishInventory>()
.Where(it => partnumbers.Contains(it.Partnumber))
.GroupBy(it => it.Partnumber)
.ToDictionary(g => g.Partnumber, g => SqlFunc.AggregateSum(g.Quantity) ?? 0);
}
// Util 获取指定抛光库零件加报表后库存
public Dictionary<string, int> GetBatchPolishRealPartNum(List<string> partnumbers)
{
try
{
// 盘点时间
2024-11-18 20:13:49 +08:00
DateTime? checkTime =
Context
.Queryable<WmPolishInventory>()
.Where(it => it.Status == 1)
.Select(it => it.CreatedTime)
2024-11-20 16:35:02 +08:00
.First() ?? new DateTime(2024, 11, 16, 12, 0, 0);
2024-10-25 19:01:06 +08:00
CommonFQCService commonFQCService = new();
// 获取报表数据
// 抛光计算后库存 = 盘点库存 + 产线抛光 + 后道反抛 + GP12反抛 - 抛光投入
2024-11-15 18:51:05 +08:00
return commonFQCService.GetBatchPolishPartRealStock(partnumbers, checkTime.Value);
2024-10-25 19:01:06 +08:00
}
catch (Exception e)
{
throw;
}
}
2024-10-29 17:35:32 +08:00
/// <summary>
/// 导入数据
/// </summary>
/// <param name="importData"></param>
/// <returns></returns>
public (string, object, object) ImportExcel(List<WmPolishInventoryExportDto> importList)
{
2024-11-18 20:13:49 +08:00
List<WmPolishInventory> wmPolishInventorylist = importList
.Select(it => new WmPolishInventory
{
Id = SnowFlakeSingle.Instance.NextId().ToString(),
Type = 1,
Status = 1,
MaxNum = 0,
MinNum = 0,
WarnNum = 0,
CreatedBy = "页面导入",
Remark = "EXCEL 盘点导入",
CreatedTime = it. ?? DateTime.Now.ToLocalTime(),
Partnumber = it.,
Quantity = it.
})
.ToList();
var x = Context
.Storageable(wmPolishInventorylist)
2024-10-29 17:35:32 +08:00
.SplitError(x => x.Item.Partnumber.IsEmpty(), "零件号不能为空")
.SplitError(x => x.Item.Quantity.IsEmpty(), "盘点数不能为空")
.SplitUpdate(it => it.Any()) // 数据库存在更新
.SplitDelete(it => it.Item.Quantity == 0) //盘点数为0的不导入
.SplitInsert(it => true) // 其余插入
2024-11-18 20:13:49 +08:00
.WhereColumns(it => it.Partnumber) //如果不是主键可以这样实现多字段it=>new{it.x1,it.x2}
2024-10-29 17:35:32 +08:00
.ToStorage();
// 清空全部
2024-11-18 20:13:49 +08:00
var result = x.AsInsertable.ExecuteCommand(); //不存在则插入;
var result2 = x.AsUpdateable.IgnoreColumns(it => new { it.Id }).ExecuteCommand(); //存在则修改;
2024-10-29 17:35:32 +08:00
var result3 = x.AsDeleteable.ExecuteCommand(); //盘点数为0的删除;
2024-11-18 20:13:49 +08:00
string msg = string.Format(
" 插入{0} 更新{1} 错误数据{2} 不计算数据{3} 删除数据{4} 总共{5}",
x.InsertList.Count,
x.UpdateList.Count,
x.ErrorList.Count,
x.IgnoreList.Count,
x.DeleteList.Count,
x.TotalList.Count
);
//输出统计
2024-10-29 17:35:32 +08:00
Console.WriteLine(msg);
2024-11-18 20:13:49 +08:00
//输出错误信息
2024-10-29 17:35:32 +08:00
foreach (var item in x.ErrorList)
{
Console.WriteLine("零件异常:" + item.Item.Partnumber + " : " + item.StorageMessage);
}
return (msg, x.ErrorList, x.IgnoreList);
}
}
}