shgx_tz_mom/ZR.Service/mes/wms/WmPolishInventoryService.cs
2024-10-29 17:35:57 +08:00

647 lines
26 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Linq;
using System.Threading.Tasks;
using Aliyun.OSS;
using Infrastructure;
using Infrastructure.Attribute;
using Infrastructure.Extensions;
using JinianNet.JNTemplate;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Newtonsoft.Json.Linq;
using SqlSugar;
using ZR.Common;
using ZR.Model;
using ZR.Model.MES.qc.DTO;
using ZR.Model.MES.wms;
using ZR.Model.MES.wms.Dto;
using ZR.Model.System;
using ZR.Repository;
using ZR.Service.mes.qc;
using ZR.Service.mes.wms.IService;
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>
public PagedInfo<WmPolishInventoryDto> GetList(WmPolishInventoryQueryDto parm)
{
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())
.OrderBy(it => it.Partnumber)
.ToPage<WmPolishInventory, WmPolishInventoryDto>(parm);
if (response.Result.Count > 0)
{
foreach (WmPolishInventoryDto item in response.Result)
{
// 获取物料信息
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;
// 获取实际库存
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;
}
}
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();
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,
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 DoWmPolishRetrieval(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 * -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();
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,
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;
}
// 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);
// 更新盘点时间
DateTime dateTime = DateTime.Now.ToLocalTime();
// 构建导出数据
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,
= dateTime,
= 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
{
// 盘点时间
DateTime? checkTime = Context
.Queryable<WmPolishInventory>()
.Where(it => it.Status == 1)
.Select(it => it.CreatedTime)
.First() ?? new DateTime(2024, 10, 19, 0, 0, 0);
CommonFQCService commonFQCService = new();
// 获取报表数据
// 抛光计算后库存 = 盘点库存 + 产线抛光 + 后道反抛 + GP12反抛 - 抛光投入
return commonFQCService.GetBatchPolishPartRealStock(partnumbers, checkTime.Value);
}
catch (Exception e)
{
throw;
}
}
/// <summary>
/// 导入数据
/// </summary>
/// <param name="importData"></param>
/// <returns></returns>
public (string, object, object) ImportExcel(List<WmPolishInventoryExportDto> importList)
{
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)
.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) // 其余插入
.WhereColumns(it => it.Partnumber)//如果不是主键可以这样实现多字段it=>new{it.x1,it.x2}
.ToStorage();
// 清空全部
var result = x.AsInsertable.ExecuteCommand();//不存在则插入;
var result2 = x.AsUpdateable.IgnoreColumns(it => new { it.Id }).ExecuteCommand();//存在则修改;
var result3 = x.AsDeleteable.ExecuteCommand(); //盘点数为0的删除;
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);
//输出统计
Console.WriteLine(msg);
//输出错误信息
foreach (var item in x.ErrorList)
{
Console.WriteLine("零件异常:" + item.Item.Partnumber + " : " + item.StorageMessage);
}
return (msg, x.ErrorList, x.IgnoreList);
}
}
}