You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

692 lines
26 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Admin.Core.IRepository;
using Admin.Core.IService;
using Admin.Core.Model;
using System.Threading.Tasks;
using System.Linq;
using System;
using Admin.Core.Model.ViewModels;
using log4net;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using Admin.Core.PlcServer;
using System.Data;
using SqlSugar;
using System.Numerics;
using System.Text;
using NPOI.POIFS.FileSystem;
using System.Linq.Expressions;
namespace Admin.Core.Service
{
public class Hw_WarehouseServices : BaseServices<Hw_Warehouse>, IHw_WarehouseServices
{
private static readonly log4net.ILog log = LogManager.GetLogger(typeof(Hw_WarehouseServices));
private readonly IBaseRepository<Hw_Warehouse> _dal;
private readonly IHw_WarehouseRepository _wareHouse;
private readonly IHw_WareHouse_SubRepository _wareHouse_Sub;
private readonly IHw_FeedReportRepository _feed;
private readonly IHw_BarrelRepository _barrel;
private readonly Ixl_materialRepository _materialRepository;
private readonly Ixl_recipeRepository _recipeRepository;
private readonly ILR_weighRepository _lrWeighRepository;
private readonly Ixl_planRepository _planRepository;//小料计划
private readonly IXLPlan_weightRepository _XLPlan_weightRepository;
public Hw_WarehouseServices(IBaseRepository<Hw_Warehouse> dal, IHw_WarehouseRepository wareHouse,
IHw_WareHouse_SubRepository wareHouse_Sub, IHw_FeedReportRepository feed,
IHw_BarrelRepository barrel, Ixl_materialRepository materialRepository,
Ixl_recipeRepository recipeRepository, ILR_weighRepository lrWeighRepository, Ixl_planRepository planRepository, IXLPlan_weightRepository IXLPlan_weightRepository, IXLPlan_weightRepository xLPlan_weightRepository)
{
this._dal = dal;
base.BaseDal = dal;
_wareHouse = wareHouse;
_wareHouse_Sub = wareHouse_Sub;
_feed = feed;
_barrel = barrel;
_materialRepository = materialRepository;
_recipeRepository = recipeRepository;
_lrWeighRepository = lrWeighRepository;
_planRepository = planRepository;
_XLPlan_weightRepository = xLPlan_weightRepository;
}
#region 扫描桶二维码,获取绑定的小料配方物料
/// <summary>
/// 扫描桶二维码,获取绑定的小料配方
/// </summary>
/// <param name="kettleBarCode">反应釜</param>
/// <param name="planId">计划Id</param>
/// <param name="code">料桶Id</param>
/// <returns></returns>
public async Task<BarrelView> GetXlInfo(string kettleBarCode, string planId, string code)
{
List<MaterialView> list = new List<MaterialView>();
List<MaterialView> materList = new List<MaterialView>();
try
{
Hw_Barrel hw = await _barrel.FirstAsync(d => d.IsEnable == "是" && d.BarCode == code);
if (hw == null) { return null; }
var recipe = await _recipeRepository.FirstAsync(d => d.Recipe_Verify == 1 && d.ID == hw.MaterialID);
if (recipe == null) { return null; }
var materialList = await _lrWeighRepository.QueryAsync(d => d.Plan_ID == hw.PlanId && d.Recipe_ID == recipe.ID);
if (materialList.Count() == 0) { return null; }
foreach (var material in materialList)
{
MaterialView childView = new MaterialView();
childView.MaterialID = material.Material_ID;
var mat = await _materialRepository.FirstAsync(d => d.ID.Equals(material.Material_ID));
if (materialList == null) { continue; }
childView.MaterialBarCode = mat.Material_code;
childView.MaterialName = material.Material_Name;
childView.Weight = material.Real_Weight;
childView.Error = material.Real_Error;
childView.MatchOrNot = 0;
list.Add(childView);
}
var kettle = await _dal.FirstAsync(d => d.BarCode.Equals(kettleBarCode));
var subList = await _wareHouse_Sub.QueryAsync(d => d.MainId == kettle.ID && d.PId.Equals(planId) &&d.MaterialType.Contains("尾料"));
foreach (var check in list)
{
MaterialView childView = new MaterialView();
childView.MaterialID = check.MaterialID;
var mat = await _materialRepository.FirstAsync(d => d.ID.Equals(check.MaterialID));
childView.MaterialBarCode = mat.Material_code;
childView.MaterialName = check.MaterialName;
var pList = subList.Where(d => d.Material_Code.Equals(check.MaterialBarCode));
if (pList == null)
{
childView.MatchOrNot = 0;
materList.Add(childView);
continue;
}
foreach (var item in pList)
{
decimal? maxValue = item.SetWeight + item.SetError;
decimal? minValue = item.SetWeight - item.SetError;
if (minValue <= check.Weight && check.Weight <= maxValue)
{
childView.Weight = check.Weight;
childView.Error = check.Error;
childView.MatchOrNot = 1;
}
else
{
childView.Weight = check.Weight;
childView.Error = check.Error;
childView.MatchOrNot = 0;
}
}
materList.Add(childView);
}
BarrelView view = new BarrelView()
{
BarrelID = hw.BarrelID,
BarrelName = hw.BarrelName,
BarCode = hw.BarCode,
child = materList
};
return view;
}
catch (Exception ex)
{
log.Error(ex.Message);
return null;
}
}
#endregion
#region GetNextSerialNum 获取下一个可用的序号SerialNum 规则:同机台、同日期、同班次 计划号最后2位的最大值加1
/// <summary>
/// 获取下一个可用的序号
/// </summary>
/// <param name="planDate">计划生产日期</param>
/// <returns>返回可用的序号</returns>
public int GetNextSerialNumAsync()
{
string strSql = "SELECT MAX(Plan_Serial) FROM xl_plan";
Expression<Func<xl_plan, bool>> exp = s1 => true;
Expression<Func<xl_plan, object>> order = (x) => x.Plan_Serial;
var result = _planRepository.Query(exp,order,false).First();
if (result == null)
{
return 1;
}
else
{
return Convert.ToInt32(result.Plan_Serial) + 1;
}
}
public int GetNextSerialNumFromLRPlan(DateTime planDate)
{
string strSql = "SELECT MAX(RIGHT(Plan_Id,2)) FROM LR_plan WHERE LEFT(Plan_Id,8) = @PlanDate";
string ss = String.Format("{0:yyyyMMdd}", planDate);
SugarParameter[] parameters = new SugarParameter[]
{
new SugarParameter($"@PlanDate", String.Format("{0:yyyyMMdd}", planDate))
};
var result = _planRepository.ExecSql(strSql, parameters);
if (result == null)
{
return 1;
}
else
{
return Convert.ToInt32(result) + 1;
}
}
#endregion
/// <summary>
/// 获取下一个可用的计划号 (6位日期、2位机台、1位班次、1位网络/本机、2位流水)
/// </summary>
/// <param name="equipCode">机台号</param>
/// <param name="planDate">计划生产日期</param>
/// <param name="shiftID">班次</param>
/// <returns>返回生成的12位计划号</returns>
public static string GenerateNextPlanIDNew(DateTime planDate, int shiftID, int sNum)
{
string code = "01";
return String.Format("{0:yyyyMMdd}{1}{2}", planDate, code, shiftID) + FillZero(sNum.ToString(), 2);
}
#region "按字符串位数补0"
/// <summary>
/// 按字符串位数补0
/// </summary>
/// <param name="CharTxt">字符串</param>
/// <param name="CharLen">字符长度</param>
/// <returns></returns>
public static string FillZero(string CharTxt, int CharLen)
{
if (CharTxt.Length < CharLen)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < CharLen - CharTxt.Length; i++)
{
sb.Append("0");
}
sb.Append(CharTxt);
return sb.ToString();
}
else
{
return CharTxt;
}
}
#endregion
public async Task<bool> InsertXLPlanInfo(DateTime planDate, string recipeGUID, string batch, string productName)
{
try
{
int shiftID = 1;
//根据配方编号查询
var recipe = await _recipeRepository.FirstAsync(d => d.Recipe_Verify == 1 && d.ID == recipeGUID);
if (recipe == null)
{
recipe.ID = recipeGUID;
recipe.Recipe_Name = recipeGUID;
recipe.Version = "1";
}
int rtPlanSNum = GetNextSerialNumAsync(); //xl_plan序号
//int lrPlanSNum = GetNextSerialNumFromLRPlan(planDate); //LR_Plan序号
string planID = GenerateNextPlanIDNew(planDate, shiftID, rtPlanSNum); //计划号hlcs0929
xl_plan xl_plan = new xl_plan()
{
Equip_Code = "01",
Dosing_Id = 0,
Plan_Id = planID,
Batch = batch,
ProductName= productName,
Plan_Serial = rtPlanSNum,
Recipe_ID = recipe.ID,
Recipe_Code = recipe.ID,
Recipe_Name = recipe.Recipe_Name,
Version = recipe.Version,
Mixer_Line = "0",
Recipe_Type = 0,
Shift_Id = "1",
Shift_Class = "0",
Plan_Num = 1,
Real_Num = 0,
Duration_Time = 0,
Plan_State = 5,
Plan_StateText = "未启动",
Plan_Date = DateTime.Now.ToString("yyyy-mm-dd"),
IF_FLAG = 1,
};
var result = await _planRepository.Add(xl_plan);
if (result == 1)
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
return false;
}
return false;
}
#region 根据传入的二维码、计划Id 查询反应釜下所有的物料
/// <summary>
/// 根据传入的二维码、计划Id 查询反应釜下所有的物料
/// </summary>
/// <param name="code">反应釜二维码</param>
/// <param name="planId">计划Id</param>
/// <returns></returns>
public async Task<WarehouseView> QueryByCode(string code, string planId)
{
List<HwWareHouseSubView> list = new List<HwWareHouseSubView>();
try
{
Hw_Warehouse wh = await _wareHouse.FirstAsync(d => d.BarCode == code);
if (wh == null) return null;
var sub = await _wareHouse_Sub.QueryAsync(d => d.MainId == wh.ID&& d.PId== planId&&(d.MaterialType.Contains("整包")|| d.MaterialType.Contains("尾料")));
if (sub.Count == 0) return null;
sub.ForEach(sub =>
{
HwWareHouseSubView view = new HwWareHouseSubView();
view.ID = sub.ID;
view.MainId = sub.MainId;
view.PId = sub.PId;
view.ProductName = sub.ProductName;
view.MaterialID = sub.MaterialID;
view.Material_Code = sub.Material_Code;
view.MaterialName = sub.MaterialName;
view.BinId = sub.BinId;
view.MaterialType = sub.MaterialType;
view.SetWeight = sub.SetWeight- sub.Tare;//设置重量减去皮重
view.SetError = sub.SetError;
view.Tare = sub.Tare;
list.Add(view);
});
WarehouseView warehouseView = new WarehouseView()
{
ID = wh.ID,
Name = wh.Name,
BarCode = wh.BarCode,
Children = list
};
return warehouseView;
}
catch (Exception ex)
{
log.Error(ex.Message);
return null;
}
}
#endregion
#region 更新PLC状态
public async Task<string> RealWeightInfo(string WeightNo)
{
string WeightInfo = "";
try
{
string name = string.Empty;
if (string.IsNullOrEmpty(WeightNo))
{
log.Error("点位名称为空!");
return "点位名称为空!";
}
switch (WeightNo)
{
case "1":
name = "DB104.DBW132";
break;
case "2":
name = "DB109.DBW134";
break;
case "3":
name = "DB104.DBW136";
break;
case "4":
name = "DB104.DBW138";
break;
case "5":
name = "DB104.DBW140";
break;
case "6":
name = "DB104.DBW142";
break;
case "7":
name = "DB104.DBW144";
break;
case "8":
name = "DB104.DBW146";
break;
case "9":
name = "DB104.DBW148";
break;
case "10":
name = "DB104.DBW150";
break;
case "11":
name = "DB104.DBW152";
break;
case "12":
name = "DB104.DBW154";
break;
case "13":
name = "DB104.DBW156";
break;
case "14":
name = "DB104.DBW158";
break;
case "15":
name = "DB104.DBW160";
break;
case "16":
name = "DB104.DBW162";
break;
default:
break;
}
var s7 = PlcConnect.Instance;
var result = s7.ReadInt16(name);//反应釜点位
log.Error($"读取重量:{result.IsSuccess},返回信息:{result.Message}");
if (result.IsSuccess)
{
return (result.Content / 1000).ToString();
}
else
{
log.Error(result.Message+",读取失败!");
return WeightNo+"称,读取失败!";
}
//return WeightInfo;
}
catch (Exception ex)
{
log.Error(ex.Message);
return WeightInfo;
}
}
public async Task<List<XLPlanWeightView>> GetPlanWeightInfo()
{
try
{
List<XLPlanWeightView> XLPlanWeightView = await _XLPlan_weightRepository.GetPlanWeightList();
if (XLPlanWeightView != null)
{
return XLPlanWeightView;
}
return XLPlanWeightView;
}
catch (Exception ex)
{
return null;
}
}
/// <summary>
/// 投料口开/投料口关
/// </summary>
/// <param name="Kcode">投料釜条码</param>
/// <param name="state">状态 0:关闭 1:开启</param>
/// <returns></returns>
public async Task<bool> UpdatePlcState(string Kcode, int state)
{
List<Hw_WareHouse_Sub> subList = null;
Hw_Warehouse wh = null;
string name = string.Empty;
wh = await _wareHouse.FirstAsync(d => d.BarCode == Kcode);
if (wh == null) return false;
#region 反应釜工位信号
//反应釜工位报警
switch (wh.ID)
{
case 1:
name = "DB109.DBW4.0";
break;
case 2:
name = "DB109.DBW10.0";
break;
case 3:
name = "DB109.DBW16.0";
break;
case 4:
name = "DB109.DBW22.0";
break;
case 5:
name = "DB109.DBW28.0";
break;
case 6:
name = "DB109.DBW34.0";
break;
case 7:
name = "DB109.DBW40.0";
break;
case 8:
name = "DB109.DBW46.0";
break;
case 9:
name = "DB109.DBW52.0";
break;
case 10:
name = "DB109.DBW58.0";
break;
case 11:
name = "DB109.DBW64.0";
break;
case 12:
name = "DB109.DBW70.0";
break;
case 13:
name = "DB109.DBW76.0";
break;
case 14:
name = "DB109.DBW82.0";
break;
case 15:
name = "DB109.DBW88.0";
break;
default:
break;
}
#endregion
if (string.IsNullOrEmpty(name))
{
log.Error("点位名称为空!");
return false;
}
var s7 = PlcConnect.Instance;
var result = s7.Write(name, short.Parse(state.ToString()));//反应釜点位
log.Error($"反应釜开启点位状态:{result.IsSuccess},返回信息:{result.Message}");
if (result.IsSuccess)
{
return result.IsSuccess;
}
else
{
log.Error("反应釜写入点位失败!");
return result.IsSuccess;
}
return true;
}
/// <summary>
/// 更新PLC状态
/// </summary>
/// <param name="view">本次验证状态 1开启0关闭</param>
/// <returns></returns>
public async Task<bool> UpdatePlcState(KettleView view)
{
List<Hw_WareHouse_Sub> subList = null;
List<Hw_FeedReport> report = new List<Hw_FeedReport>();
Hw_Warehouse wh = null;
string message = string.Empty;
string name = string.Empty;
#region 反应釜工位信号
//反应釜工位报警
switch (view.Station)
{
case 1:
name = "DB109.DBW4.0";
break;
case 2:
name = "DB109.DBW10.0";
break;
case 3:
name = "DB109.DBW16.0";
break;
case 4:
name = "DB109.DBW22.0";
break;
case 5:
name = "DB109.DBW28.0";
break;
case 6:
name = "DB109.DBW34.0";
break;
case 7:
name = "DB109.DBW40.0";
break;
case 8:
name = "DB109.DBW46.0";
break;
case 9:
name = "DB109.DBW52.0";
break;
case 10:
name = "DB109.DBW58.0";
break;
case 11:
name = "DB109.DBW64.0";
break;
case 12:
name = "DB109.DBW70.0";
break;
case 13:
name = "DB109.DBW76.0";
break;
case 14:
name = "DB109.DBW82.0";
break;
case 15:
name = "DB109.DBW88.0";
break;
default:
break;
}
#endregion
try
{
log.Info("开始投料");
#region 记录数据
//同时记录该扫码到数据库中
wh = await _wareHouse.FirstAsync(d => d.BarCode == view.KCode);
if (wh == null) return false;
subList = await _wareHouse_Sub.QueryAsync(d => d.MainId == wh.ID);
if (subList.Count == 0) return false;
log.Info("开启模式");
if (view.State == 1)
{
message = "开启";
}
if (view.State == 0)
{
message = "关闭";
}
if (string.IsNullOrEmpty(message))
{
log.Error("传递状态为空!");
return false;
}
foreach (var item in view.Child)
{
Hw_FeedReport hw = new Hw_FeedReport()
{
WID = wh.ID,
PlanId = view.PlanId,
WName = wh.Name,
WCode = wh.BarCode,
MaterialId = item.MatCode,
MaterialName = item.MatName,
MCode = item.MatCode,
MType = item.MatType,
IsTrue = message,
CreateTime = DateTime.Now,
WholePackage = item.WholePackage.Trim()
};
report.Add(hw);
}
await _feed.AddAsync(report);
if (string.IsNullOrEmpty(name))
{
log.Error("点位名称为空!");
return false;
}
var s7 = PlcConnect.Instance;
var result = s7.Write(name,short.Parse(view.State.ToString()));//反应釜点位
log.Error($"反应釜开启点位状态:{result.IsSuccess},返回信息:{result.Message}");
if (result.IsSuccess)
{
if (view.State == 1)
{
foreach (var item in view.Child.Where(d=>d.MatType== "散装"))
{
}
}
return result.IsSuccess;
}
else
{
log.Error("反应釜写入点位失败!");
return result.IsSuccess;
}
#endregion
}
catch (Exception ex)
{
log.Error($"异常:{ex.Message}");
return false;
}
}
#endregion
#region 获取所有计划号
/// <summary>
/// 获取所有计划号
/// </summary>
/// <returns></returns>
public async Task<List<string>> GetWarehousePlan(string code)
{
Hw_Warehouse wh = await _wareHouse.FirstAsync(d=>d.BarCode== code.Trim());
if (wh==null) return null;
var list = await _wareHouse_Sub.QueryAsync(d=>d.MainId== wh.ID);
var planList = (from d in list
select d.PId).Distinct();
return planList.ToList();
}
#endregion
}
}