using Rhea.Common;
|
using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Globalization;
|
using System.Linq;
|
using System.Text;
|
using System.Text.RegularExpressions;
|
|
namespace Tiger.Business.WMS
|
{
|
/// <summary>
|
/// 条码基类
|
/// </summary>
|
public class Barcode
|
{
|
public Barcode(string metaSn)
|
{
|
SetAnalysisRule();
|
Analyse(MetaSn = metaSn);
|
}
|
|
/// <summary>
|
/// 条码(解析后的条码)
|
/// </summary>
|
private List<BarcodeAnalysis> Analyses { get; set; } = new();
|
/// <summary>
|
/// 条码(解析后的条码)
|
/// </summary>
|
public string SN { get; set; }
|
/// <summary>
|
/// 元条码(扫描到的条码)
|
/// </summary>
|
public string MetaSn { get; set; }
|
/// <summary>
|
/// 条码类型
|
/// </summary>
|
public Types Type { get; set; }
|
/// <summary>
|
/// 物料编码
|
/// </summary>
|
public ItemTypes ItemType { get; set; }
|
/// <summary>
|
/// 物料编码
|
/// </summary>
|
public string ItemCode { get; set; }
|
/// <summary>
|
/// 物料名称
|
/// </summary>
|
public string ItemName { get; set; }
|
/// <summary>
|
/// 生产日期编码
|
/// </summary>
|
public string DateCode { get; set; }
|
/// <summary>
|
/// 生产日期
|
/// </summary>
|
public string ProdDateStr { get; set; }
|
/// <summary>
|
/// 生产日期
|
/// </summary>
|
public DateTime? ProdDate { get => BarcodeAnalysis.GetDateTime(ProdDateStr) ?? BarcodeAnalysis.GetDateTime(PrintDateStr); }
|
/// <summary>
|
/// 打印日期
|
/// </summary>
|
public string PrintDateStr { get; set; }
|
/// <summary>
|
/// 供应商代码
|
/// </summary>
|
public string SupplierCode { get; set; }
|
/// <summary>
|
/// 批次号
|
/// </summary>
|
public string LotNo { get; set; }
|
/// <summary>
|
/// 组织代码
|
/// </summary>
|
public string Organization { get; set; }
|
/// <summary>
|
/// 订单号
|
/// </summary>
|
public string OrderNo { get; set; }
|
/// <summary>
|
/// 订单行号
|
/// </summary>
|
public string OrderLine { get; set; }
|
/// <summary>
|
/// 制造商/代工厂料号
|
/// </summary>
|
public string OEMItemCode { get; set; }
|
/// <summary>
|
/// 流水码
|
/// </summary>
|
public string SerialNoStr { get; set; }
|
/// <summary>
|
/// 流水码
|
/// </summary>
|
public int? SerialNo { get => BarcodeAnalysis.GetSerialNo(SerialNoStr); }
|
|
/// <summary>
|
/// 单位
|
/// </summary>
|
public string Unit { get; set; }
|
|
/// <summary>
|
/// 数量
|
/// </summary>
|
public string QtyStr { get; set; }
|
/// <summary>
|
/// 数量
|
/// </summary>
|
public decimal? Qty { get => Convert.ToDecimal(BarcodeAnalysis.GetDouble(QtyStr)); }
|
|
/// <summary>
|
/// 毛重
|
/// </summary>
|
public string GrossWeightStr { get; set; }
|
/// <summary>
|
/// 毛重
|
/// </summary>
|
public double? GrossWeight { get => BarcodeAnalysis.GetDouble(GrossWeightStr); }
|
/// <summary>
|
/// 仓库
|
/// </summary>
|
public string Warehouse { get; set; }
|
/// <summary>
|
/// 储位
|
/// </summary>
|
public string Location { get; set; }
|
|
/// <summary>
|
/// 条码分析异常信息
|
/// </summary>
|
public Exception AnalyseException { get; set; }
|
/// <summary>
|
/// 条码是否分析异常
|
/// </summary>
|
public bool IsException { get => !AnalyseException.IsNullOrEmpty(); }
|
|
/// <summary>
|
/// 条码是否合法
|
/// </summary>
|
public bool IsRegular { get => Type != Types.Illegal; }
|
|
/// <summary>
|
/// 条码是否原材料条码
|
/// </summary>
|
public bool IsMaterialSN { get => !(new List<ItemTypes>() { ItemTypes.RawMaterial }).Contains(ItemType); }
|
|
/// <summary>
|
/// 标签重打流水码字符
|
/// </summary>
|
public string ReprintNoStr { get; set; }
|
/// <summary>
|
/// 标签重打流水码
|
/// </summary>
|
public int? ReprintNo => BarcodeAnalysis.GetReprintNo(ReprintNoStr);
|
/// <summary>
|
/// 标签重打一级业务编码
|
/// </summary>
|
public string ReprintBizCode1 { get; set; }
|
/// <summary>
|
/// 标签重打二级业务编码
|
/// </summary>
|
public string ReprintBizCode2 { get; set; }
|
/// <summary>
|
/// 是否重打标签
|
/// </summary>
|
public bool IsReprintSn => SN.Contains("_");
|
|
/// <summary>
|
/// 是否截料重打标签
|
/// </summary>
|
public bool IsCutSn => ReprintBizCode1 == "C";
|
|
/// <summary>
|
/// 是否退料重打标签
|
/// </summary>
|
public bool IsReturnSn => ReprintBizCode1 == "T";
|
/// <summary>
|
/// 是否二维码
|
/// </summary>
|
public bool IsQRCode => MetaSn.Contains(",");
|
|
|
public enum Types
|
{
|
/// <summary>
|
/// 非法条码
|
/// </summary>
|
[Description("非法条码")]
|
Illegal,
|
/// <summary>
|
/// 唯一ID
|
/// </summary>
|
[Description("最小包装标签")]
|
MiniPackage,
|
/// <summary>
|
/// 中包标签
|
/// </summary>
|
[Description("内包装标签")]
|
InnerPackage,
|
/// <summary>
|
/// 外包标签
|
/// </summary>
|
[Description("外包装标签")]
|
OuterPackage,
|
/// <summary>
|
/// 栈板条码
|
/// </summary>
|
[Description("栈板条码")]
|
Pallet,
|
/// <summary>
|
/// 其他标签条码
|
/// </summary>
|
[Description("其他标签")]
|
Other,
|
}
|
|
public enum ItemTypes
|
{
|
[Description("未知类型")]
|
Unknown,
|
[Description("湿敏元件")]
|
HumidityMaterial,
|
[Description("半成品")]
|
SemiProduct,
|
[Description("SMT半成品")]
|
SmtSemiProduct,
|
[Description("DIP半成品")]
|
DipSemiProduct,
|
[Description("成品")]
|
Product,
|
[Description("PCB")]
|
PCB,
|
[Description("辅料")]
|
SubsidiaryMaterial,
|
[Description("原材料")]
|
RawMaterial,
|
}
|
|
/// <summary>
|
/// 设置条码分析验证规则
|
/// </summary>
|
public void SetAnalysisRule()
|
{
|
Analyses.Clear();
|
Analyses.Add(new YadaBarcode());
|
//Analyses.Add(new BarcodeAnalysis());
|
}
|
|
/// <summary>
|
/// 条码分析
|
/// </summary>
|
/// <param name="metaSn"></param>
|
public void Analyse(string metaSn)
|
{
|
SN = metaSn;
|
Type = Types.Illegal;
|
ItemType = ItemTypes.Unknown;
|
AnalyseException = null;
|
try
|
{
|
foreach (var rule in Analyses)
|
{
|
var result = rule.Analyse(this);
|
if (result.IsSuccessed)
|
{
|
break;
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
AnalyseException = ex;
|
}
|
}
|
|
/// <summary>
|
/// 是否与传入的条码相同的生产日期
|
/// </summary>
|
/// <param name="sn"></param>
|
/// <returns></returns>
|
public bool IsSameProdDate(string sn)
|
{
|
return (ProdDate ?? DateTime.MaxValue).Date == ((new Barcode(sn)).ProdDate ?? DateTime.MinValue).Date;
|
}
|
|
/// <summary>
|
/// 是否小于等于传入的条码的生产日期
|
/// </summary>
|
/// <param name="sn"></param>
|
/// <returns></returns>
|
public bool IsPriorProdDate(string sn)
|
{
|
return (ProdDate ?? DateTime.MaxValue).Date <= ((new Barcode(sn)).ProdDate ?? DateTime.MinValue).Date;
|
}
|
|
///// <summary>
|
///// 条码分析
|
///// </summary>
|
///// <param name="metaSn"></param>
|
//public void Analyse(string metaSn)
|
//{
|
// SN = metaSn;
|
// Type = Types.Illegal;
|
// ItemType = ItemTypes.Unknown;
|
// AnalyseException = null;
|
// try
|
// {
|
// if (!string.IsNullOrEmpty(SN))
|
// {
|
// string[] parts = (metaSn ?? "").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
|
// if (parts.Length > 1 && parts.Any(q => q.StartsWith("S")))
|
// {
|
// foreach (var part in parts.OrderBy(q => q.FirstOrDefault()))
|
// {
|
// var param = part.First().ToString().ToUpper();
|
// var content = part.Substring(1);
|
// switch (param)
|
// {
|
// case "S"://PAG ID (SN)
|
// var snParts = (content ?? "").Split(new string[] { "_" }, StringSplitOptions.RemoveEmptyEntries);
|
// SN = content;
|
// Type = Types.Other;
|
// if (SN.StartsWith("C") && SN.Length > 14)
|
// {
|
// SupplierCode = SN.Substring(1, 5);
|
// PrintDateStr = SN.Substring(6, 8);
|
// SerialNoStr = SN.Substring(14);
|
// if (ProdDate != null && SerialNo != null)
|
// {
|
// Type = Types.Middle;
|
// ItemType = ItemTypes.RawMaterial;
|
// }
|
// }
|
// else if (SN.StartsWith("P") && SN.Length > 14)
|
// {
|
// SupplierCode = SN.Substring(1, 5);
|
// PrintDateStr = SN.Substring(6, 8);
|
// SerialNoStr = SN.Substring(14);
|
// if (ProdDate != null && SerialNo != null)
|
// {
|
// Type = Types.Outer;
|
// ItemType = ItemTypes.RawMaterial;
|
// }
|
// }
|
// else if (SN.Length > 13)
|
// {
|
// SupplierCode = SN.Substring(0, 5);
|
// PrintDateStr = SN.Substring(5, 8);
|
// SerialNoStr = SN.Substring(13);
|
// if (ProdDate != null && SerialNo != null)
|
// {
|
// Type = Types.Small;
|
// ItemType = ItemTypes.RawMaterial;
|
// }
|
// }
|
// //是否重打判断
|
// if(snParts.Count() >1 && snParts[1].Length > 2)
|
// {
|
// ReprintBizCode1 = snParts[1][0].ToString();
|
// ReprintBizCode2 = snParts[1][1].ToString();
|
// ReprintNoStr = snParts[1].Substring(2);
|
// }
|
// break;
|
// case "V"://送货单号
|
// OrderNo = content;
|
// break;
|
// case "P"://物料编码
|
// ItemCode = content;
|
// break;
|
// case "N"://物料编码
|
// ItemName = content;
|
// break;
|
// case "Q"://物料数量
|
// QtyStr = content;
|
// break;
|
// case "U"://物料单位
|
// Unit = content;
|
// break;
|
// case "M"://制造商料号
|
// OEMItemCode = content;
|
// break;
|
// case "D"://生产日期
|
// DateCode = content;
|
// ProdDateStr = content;
|
// break;
|
// case "L"://生产批次
|
// LotNo = content;
|
// break;
|
// case "G"://物料毛重
|
// GrossWeightStr = content;
|
// break;
|
// default:
|
// break;
|
// }
|
// }
|
// }
|
// else if(SN.Length > 10)
|
// {
|
// var snParts = (SN ?? "").Split(new string[] { "_" }, StringSplitOptions.RemoveEmptyEntries);
|
// Type = Types.Other;
|
// if (SN.StartsWith("C") && SN.Length > 14)
|
// {
|
// SupplierCode = SN.Substring(1, 5);
|
// PrintDateStr = SN.Substring(6, 8);
|
// SerialNoStr = SN.Substring(14);
|
// if (ProdDate != null && SerialNo != null)
|
// {
|
// Type = Types.Middle;
|
// ItemType = ItemTypes.RawMaterial;
|
// }
|
// }
|
// else if (SN.StartsWith("P") && SN.Length > 14)
|
// {
|
// SupplierCode = SN.Substring(1, 5);
|
// PrintDateStr = SN.Substring(6, 8);
|
// SerialNoStr = SN.Substring(14);
|
// if (ProdDate != null && SerialNo != null)
|
// {
|
// Type = Types.Outer;
|
// ItemType = ItemTypes.RawMaterial;
|
// }
|
// }
|
// else if (SN.Length > 13)
|
// {
|
// SupplierCode = SN.Substring(0, 5);
|
// PrintDateStr = SN.Substring(5, 8);
|
// SerialNoStr = SN.Substring(13);
|
// if (ProdDate != null && SerialNo != null)
|
// {
|
// Type = Types.Small;
|
// ItemType = ItemTypes.RawMaterial;
|
// }
|
// }
|
// //是否重打判断
|
// if (snParts.Count() > 1 && snParts[1].Length > 2)
|
// {
|
// ReprintBizCode1 = snParts[1][0].ToString();
|
// ReprintBizCode2 = snParts[1][1].ToString();
|
// ReprintNoStr = snParts[1].Substring(2);
|
// }
|
// }
|
// }
|
// }
|
// catch (Exception ex)
|
// {
|
// AnalyseException = ex;
|
// }
|
//}
|
|
///// <summary>
|
///// 根据字符串返回流水号
|
///// </summary>
|
///// <param name="str"></param>
|
///// <returns></returns>
|
//private int? GetSerialNo(string str)
|
//{
|
// int serialNo;
|
// try
|
// {
|
// serialNo = Convert.ToInt32(new Regex(@"[^\d]*").Replace(str, ""));
|
// }
|
// catch
|
// {
|
// return null;
|
// }
|
// return serialNo;
|
//}
|
|
///// <summary>
|
///// 根据字符串返回重打流水号
|
///// </summary>
|
///// <param name="str"></param>
|
///// <returns></returns>
|
//private int? GetReprintNo(string str)
|
//{
|
// int qty;
|
// try
|
// {
|
// qty = Convert.ToInt32(str, 16);
|
// }
|
// catch
|
// {
|
// return null;
|
// }
|
// return qty;
|
//}
|
|
///// <summary>
|
///// 根据字符串返回数量
|
///// </summary>
|
///// <param name="str"></param>
|
///// <returns></returns>
|
//private int? GetInt32(string str)
|
//{
|
// int qty;
|
// try
|
// {
|
// qty = Convert.ToInt32(str);
|
// }
|
// catch
|
// {
|
// return null;
|
// }
|
// return qty;
|
//}
|
|
///// <summary>
|
///// 根据字符串返回数量
|
///// </summary>
|
///// <param name="str"></param>
|
///// <returns></returns>
|
//private double? GetDouble(string str)
|
//{
|
// double qty;
|
// try
|
// {
|
// qty = Convert.ToDouble(str);
|
// }
|
// catch
|
// {
|
// return null;
|
// }
|
// return qty;
|
//}
|
|
///// <summary>
|
///// 根据日期编码返回生产日期
|
///// </summary>
|
///// <param name="dateStr"></param>
|
///// <returns></returns>
|
//public static DateTime? GetDateTime(string dateStr)
|
//{
|
// DateTime proddate;
|
// dateStr = dateStr ?? "";
|
// if (dateStr.Length == 8)
|
// {
|
// try
|
// {
|
// //年月日
|
// proddate = DateTime.ParseExact(dateStr, "yyyyMMdd", new CultureInfo("zh-CN", true));
|
// }
|
// catch
|
// {
|
// return null;
|
// }
|
// }
|
// else if (dateStr.Length == 6)
|
// {
|
// try
|
// {
|
// //年月日
|
// proddate = DateTime.ParseExact(dateStr, "yyMMdd", new CultureInfo("zh-CN", true));
|
// }
|
// catch
|
// {
|
// try
|
// {
|
// //年周
|
// var firstDate = Convert.ToDateTime(dateStr.Substring(0, 4) + "-1-1");
|
// int weekNum = Convert.ToInt32(dateStr.Substring(4, 2));
|
|
// int daysOffset = DayOfWeek.Monday - firstDate.DayOfWeek;
|
// DateTime firstSunday = firstDate.AddDays(daysOffset);
|
// var calendar = CultureInfo.CurrentCulture.Calendar;
|
// int firstWeek = calendar.GetWeekOfYear(firstDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
|
// if (firstWeek <= 1)
|
// {
|
// weekNum -= 1;
|
// }
|
// proddate = firstSunday.AddDays(weekNum * 7 - 1);
|
// if (proddate.Year < firstDate.Year)
|
// {
|
// proddate = firstDate;
|
// }
|
// if (proddate.Year > firstDate.Year)
|
// {
|
// proddate = firstDate.AddYears(1).AddDays(-1);
|
// }
|
// }
|
// catch
|
// {
|
// try
|
// {
|
// //年月
|
// proddate = DateTime.ParseExact(dateStr, "yyyyMM", new CultureInfo("zh-CN", true));
|
// }
|
// catch
|
// {
|
// try
|
// {
|
// proddate = Convert.ToDateTime(dateStr);
|
// }
|
// catch
|
// {
|
// //proddate = DateTime.Now;
|
// return null;
|
// }
|
// }
|
// }
|
// }
|
// }
|
// else if (dateStr.Length == 4)
|
// {
|
// try
|
// {
|
// //年周
|
// var firstDate = DateTime.ParseExact(dateStr.Substring(0, 2), "yy", CultureInfo.CurrentCulture);
|
// int weekNum = Convert.ToInt32(dateStr.Substring(2, 2));
|
|
// int daysOffset = DayOfWeek.Monday - firstDate.DayOfWeek;
|
// DateTime firstSunday = firstDate.AddDays(daysOffset);
|
// var calendar = CultureInfo.CurrentCulture.Calendar;
|
// int firstWeek = calendar.GetWeekOfYear(firstDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
|
// if (firstWeek <= 1)
|
// {
|
// weekNum -= 1;
|
// }
|
// proddate = firstSunday.AddDays(weekNum * 7 - 1);
|
// if (proddate.Year < firstDate.Year)
|
// {
|
// proddate = firstDate;
|
// }
|
// if (proddate.Year > firstDate.Year)
|
// {
|
// proddate = firstDate.AddYears(1).AddDays(-1);
|
// }
|
// }
|
// catch
|
// {
|
// try
|
// {
|
// //年月
|
// proddate = DateTime.ParseExact(dateStr, "yyMM", new CultureInfo("zh-CN", true));
|
// }
|
// catch
|
// {
|
// try
|
// {
|
// //年
|
// proddate = DateTime.ParseExact(dateStr, "yyyy", new CultureInfo("zh-CN", true));
|
// }
|
// catch
|
// {
|
// try
|
// {
|
// proddate = Convert.ToDateTime(dateStr);
|
// }
|
// catch
|
// {
|
// //无法识别则使用当前时间
|
// //proddate = DateTime.Now;
|
// return null;
|
// }
|
// }
|
// }
|
// }
|
// }
|
// else
|
// {
|
// try
|
// {
|
// proddate = Convert.ToDateTime(dateStr);
|
// }
|
// catch
|
// {
|
// //proddate = DateTime.Now;
|
// return null;
|
// }
|
// }
|
// return proddate;
|
//}
|
|
///// <summary>
|
///// 是否与传入的条码相同的生产日期
|
///// </summary>
|
///// <param name="sn"></param>
|
///// <returns></returns>
|
//public bool IsSameProdDate(string sn)
|
//{
|
// return (ProdDate ?? DateTime.MaxValue).Date == ((new Barcode(sn)).ProdDate ?? DateTime.MinValue).Date;
|
//}
|
|
///// <summary>
|
///// 是否小于等于传入的条码的生产日期
|
///// </summary>
|
///// <param name="sn"></param>
|
///// <returns></returns>
|
//public bool IsPriorProdDate(string sn)
|
//{
|
// return (ProdDate ?? DateTime.MaxValue).Date <= ((new Barcode(sn)).ProdDate ?? DateTime.MinValue).Date;
|
//}
|
|
///// <summary>
|
///// 是否非法条码
|
///// </summary>
|
///// <param name="sn"></param>
|
///// <returns></returns>
|
//public static bool IsIllegal(string sn)
|
//{
|
// return !new Barcode(sn).IsRegular;
|
//}
|
|
///// <summary>
|
///// 获取条码类型
|
///// </summary>
|
///// <param name="sn"></param>
|
///// <returns></returns>
|
//public static Types GetType(string sn)
|
//{
|
// return new Barcode(sn).Type;
|
//}
|
|
///// <summary>
|
///// 判断是否重打的条码
|
///// </summary>
|
///// <param name="sn"></param>
|
///// <returns></returns>
|
//public static bool IsReprint(string sn)
|
//{
|
// return new Barcode(sn).IsReprintSn;
|
//}
|
}//endClass
|
}
|