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 { /// /// 条码基类 /// public class Barcode { public Barcode(string metaSn) { Analyse(MetaSn = metaSn); } /// /// 条码(解析后的条码) /// public string SN { get; set; } /// /// 元条码(扫描到的条码) /// public string MetaSn { get; set; } /// /// 条码类型 /// public Types Type { get; set; } /// /// 物料编码 /// public string ItemCode { get; set; } /// /// 物料名称 /// public string ItemName { get; set; } /// /// 物料编码 /// public ItemTypes ItemType { get; set; } /// /// 生产日期编码 /// public string DateCode { get; set; } /// /// 生产日期 /// public string ProdDateStr { get; set; } /// /// 生产日期 /// public DateTime? ProdDate { get => GetDateTime(ProdDateStr) ?? GetDateTime(PrintDateStr); } /// /// 打印日期 /// public string PrintDateStr { get; set; } /// /// 供应商代码 /// public string SupplierCode { get; set; } /// /// 批次号 /// public string LotNo { get; set; } /// /// 订单号 /// public string OrderNo { get; set; } /// /// 制造商/代工厂料号 /// public string OEMItemCode { get; set; } /// /// 流水码 /// public string SerialNoStr { get; set; } /// /// 流水码 /// public int? SerialNo { get => GetSerialNo(SerialNoStr); } /// /// 单位 /// public string Unit { get; set; } /// /// 数量 /// public string QtyStr { get; set; } /// /// 数量 /// public decimal? Qty { get => Convert.ToDecimal(GetDouble(QtyStr)); } /// /// 毛重 /// public string GrossWeightStr { get; set; } /// /// 毛重 /// public double? GrossWeight { get => GetDouble(QtyStr); } /// /// 料号长度 /// public int ItemLength { get; set; } /// /// 料号长度 /// public Exception AnalyseException { get; set; } /// /// 条码是否合法 /// public bool IsRegular { get => Type != Types.Illegal; } /// /// 条码是否原材料条码 /// public bool IsMaterialSN { get => !(new List() { ItemTypes.RawMaterial }).Contains(ItemType); } /// /// 标签重打流水码字符 /// public string ReprintNoStr { get; set; } /// /// 标签重打流水码 /// public int? ReprintNo => GetReprintNo(ReprintNoStr); /// /// 标签重打一级业务编码 /// public string ReprintBizCode1 { get; set; } /// /// 标签重打二级业务编码 /// public string ReprintBizCode2 { get; set; } /// /// 是否重打标签 /// public bool IsReprintSn => SN.Contains("_"); /// /// 是否截料重打标签 /// public bool IsCutSn => ReprintBizCode1 == "C"; /// /// 是否退料重打标签 /// public bool IsReturnSn => ReprintBizCode1 == "T"; /// /// 是否二维码 /// public bool IsQRCode => MetaSn.Contains(","); public enum Types { /// /// 非法条码 /// [Description("非法条码")] Illegal, /// /// 小包标签 /// [Description("小包标签")] Small, /// /// 中包标签 /// [Description("中包标签")] Middle, /// /// 外包标签 /// [Description("外包标签")] Outer, /// /// 栈板条码 /// [Description("栈板条码")] Pallet, /// /// 成品标签条码 /// [Description("成品标签")] Product, /// /// 其他标签条码 /// [Description("其他标签")] Other, } public enum ItemTypes { [Description("未知类型")] Unknown, [Description("湿敏元件")] HumidityMaterial, [Description("SMT半成品")] SmtSemiProduct, [Description("DIP半成品")] DipSemiProduct, [Description("成品")] Product, [Description("PCB")] PCB, [Description("辅料")] SubsidiaryMaterial, [Description("原材料")] RawMaterial, } /// /// 条码分析 /// /// 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; } } /// /// 根据字符串返回流水号 /// /// /// private int? GetSerialNo(string str) { int serialNo; try { serialNo = Convert.ToInt32(new Regex(@"[^\d]*").Replace(str, "")); } catch { return null; } return serialNo; } /// /// 根据字符串返回重打流水号 /// /// /// private int? GetReprintNo(string str) { int qty; try { qty = Convert.ToInt32(str, 16); } catch { return null; } return qty; } /// /// 根据字符串返回数量 /// /// /// private int? GetInt32(string str) { int qty; try { qty = Convert.ToInt32(str); } catch { return null; } return qty; } /// /// 根据字符串返回数量 /// /// /// private double? GetDouble(string str) { double qty; try { qty = Convert.ToDouble(str); } catch { return null; } return qty; } /// /// 根据日期编码返回生产日期 /// /// /// 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; } /// /// 是否与传入的条码相同的生产日期 /// /// /// public bool IsSameProdDate(string sn) { return (ProdDate ?? DateTime.MaxValue).Date == ((new Barcode(sn)).ProdDate ?? DateTime.MinValue).Date; } /// /// 是否小于等于传入的条码的生产日期 /// /// /// public bool IsPriorProdDate(string sn) { return (ProdDate ?? DateTime.MaxValue).Date <= ((new Barcode(sn)).ProdDate ?? DateTime.MinValue).Date; } /// /// 是否非法条码 /// /// /// public static bool IsIllegal(string sn) { return !new Barcode(sn).IsRegular; } /// /// 获取条码类型 /// /// /// public static Types GetType(string sn) { return new Barcode(sn).Type; } /// /// 判断是否重打的条码 /// /// /// public static bool IsReprint(string sn) { return new Barcode(sn).IsReprintSn; } }//endClass }