using ButcherFactory.BO; using ButcherFactory.BO.LocalBL; using ButcherFactory.BO.Utils; using ButcherFactory.Controls; using ButcherFactory.Dialogs; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace ButcherFactory.SegmentStockUp_ { public partial class SegmentStockUpForm : FormTemplate, IWithRoleForm { #region IWithRoleForm public List RoleName { get { return new List { (short)设备类别.销售备货 }; } } public Form Generate() { return this; } #endregion DateTime sendTime = DateTime.Today; BindingList mainList; BindingList detailList; BindingList finishList; List allMain; List allDetail; List alreadyList; Thread syncStockdNumber; Thread refreshFromServer; Thread loadBindTask;//onetime public SegmentStockUpForm() { InitializeComponent(); finishList = new BindingList(); allMain = new List(); allDetail = new List(); alreadyList = new List(); // dataPicker.Text = sendTime.ToString("yyyy-MM-dd"); uScanPanel1.AfterScan += uScanPanel1_AfterScan; this.FormClosing += delegate { AbortTask(); }; } void AbortTask() { if (loadBindTask != null && loadBindTask.IsAlive) loadBindTask.Abort(); if (syncStockdNumber != null && syncStockdNumber.IsAlive) syncStockdNumber.Abort(); if (refreshFromServer != null && refreshFromServer.IsAlive) refreshFromServer.Abort(); } protected override void OnLoad(EventArgs e) { StartTask(); base.OnLoad(e); } void StartTask() { allDetail = SegmentStockUpBL.GetLocalList(sendTime); loadBindTask = new Thread(LoadBind); loadBindTask.Start(); syncStockdNumber = new Thread(SyncStockdNumber); syncStockdNumber.Start(); refreshFromServer = new Thread(RefreshFromServer); refreshFromServer.Start(); } private void LoadBind() { var mainList = SegmentStockUpBL.GetSaleOutStoreList(sendTime); var appendAlready = SegmentStockUpBL.SyncAlreadyNumber(mainList.Select(x => x.DetailID), null); ReBind(mainList, appendAlready); } object _lock = new object(); //loadBind,Refresh, taskMain,taskAlready,Scan void ReBind(List mainList, List appendAlready) { lock (_lock) { AppendData(mainList, appendAlready); var needRefresh = PrepareFinishList(); if (needRefresh) BindFinishGrid(); } } void AppendData(List mainList, List appendAlready) { if (mainList.Any()) allMain = mainList; foreach (var item in appendAlready) { var first = alreadyList.FirstOrDefault(x => x.DetailID == item.DetailID); if (first == null) { first = item; alreadyList.Add(item); } else if (first.MaxID < item.MaxID) { first.MaxID = item.MaxID; first.UnitNum = (first.UnitNum ?? 0) + (item.UnitNum ?? 0); first.SecondNumber = (first.SecondNumber ?? 0) + (item.SecondNumber ?? 0); } else continue; //局部更新 if (!mainList.Any()) UpdateMainInfo(first); } //全量更新 if (mainList.Any()) { foreach (var item in alreadyList) UpdateMainInfo(item); } } void UpdateMainInfo(AlreadyStockUp item) { var mainFirst = allMain.FirstOrDefault(x => x.DetailID == item.DetailID); if (mainFirst != null) { mainFirst.StandardPic = item.StandardPic; mainFirst.SUnitNum = item.UnitNum; mainFirst.SSecondNumber = item.SecondNumber; } } //返回是否需要更新Grid; bool PrepareFinishList() { var old = finishList.ToList(); var append = new List(); finishList = new BindingList(); var idx = 0; foreach (var item in allMain.GroupBy(x => x.DeliverGoodsLine_Name).Where(x => x.All(y => y.Finishd))) { var detail = new DeliverGoodsLineTemp(); detail.RowIndex = ++idx; detail.Name = item.Key; detail.UnitNum = item.Sum(x => x.UnitNum ?? 0); detail.SecondNumber = item.Sum(x => x.SecondNumber ?? 0); detail.SUnitNum = item.Sum(x => x.SUnitNum ?? 0); detail.SSecondNumber = item.Sum(x => x.SSecondNumber ?? 0); if (!old.Any(x => x.Name == item.Key)) { idx--; append.Add(detail); } else finishList.Insert(0, detail); } foreach (var item in append) { item.RowIndex = ++idx; finishList.Insert(0, item); } if (old.Count != finishList.Count) return true; return old.Except(finishList).Count() != 0; } void BindFinishGrid() { this.Invoke(new Action(() => { finishGrid.DataSource = finishList; if (finishList.Any()) finishGrid.Rows[0].Selected = true; finishGrid.Refresh(); })); } private void SyncStockdNumber() { while (true) { Thread.Sleep(2000); IEnumerable tags = new List(); long? maxID = null; if (alreadyList.Any()) maxID = alreadyList.Max(x => x.MaxID); else tags = allMain.Select(x => x.DetailID); if (maxID.HasValue || tags.Any()) { var temp = SegmentStockUpBL.SyncAlreadyNumber(tags, maxID); if (temp.Any()) { ReBind(new List(), temp); } } } } private void RefreshFromServer() { while (true) { Thread.Sleep(2 * 60 * 1000); var temp = SegmentStockUpBL.GetSaleOutStoreList(sendTime); if (temp.Any()) { ReBind(temp, new List()); } } } void uScanPanel1_AfterScan() { var code = uScanPanel1.TextBox.Text; if (string.IsNullOrEmpty(code)) return; if (allDetail.Any(x => x.BarCode == code)) { InfoBox.Show("错误", "条码已使用过", Color.Green, 1, this); return; } var info = SegmentStockUpBL.StockUpScan(code); if (info == null) { InfoBox.Show("错误", "条码未入库", Color.Blue, 1, this); return; } InsertDetail(info); } void InsertDetail(Tuple scan) { var saleOutStore = allMain.FirstOrDefault(x => !x.Finishd && x.Goods_Code == scan.Item1); if (saleOutStore == null) { InfoBox.Show("提示", "没有订单", Color.Red, 1, this); return; } var detail = new SegmentStockUp(); detail.BarCode = uScanPanel1.TextBox.Text; detail.Date = sendTime; detail.DetailID = saleOutStore.DetailID; detail.DeliverGoodsLine_Name = saleOutStore.DeliverGoodsLine_Name; detail.Goods_Name = saleOutStore.Goods_Name; //detail.BillID = saleOutStore.BillID; detail.UnitNumber = scan.Item2; detail.StandardPic = scan.Item3; if (detail.UnitNumber.HasValue && saleOutStore.Rate.HasValue) detail.SecondNumber = detail.UnitNumber * saleOutStore.Rate; else detail.SecondNumber = 1; var number =saleOutStore.UnitNum ; if (!detail.StandardPic) number = saleOutStore.SecondNumber; var already = alreadyList.FirstOrDefault(x => x.DetailID == detail.DetailID); if (already == null) already = new AlreadyStockUp() { DetailID = detail.DetailID };//StandardPic = detail.StandardPic var back = SegmentStockUpBL.Insert(detail, already, number.Value); if (back == null) { InfoBox.Show("提示", "网络错误!", Color.Red, 1, this); return; } if (back.State == -1) { InfoBox.Show("提示", "条码已使用过", Color.Green, 1, this); return; } back.StandardPic = detail.StandardPic; back.DetailID = detail.DetailID; if (back.State == 0) { ReBind(new List(), new List { back }); InsertDetail(scan); return; } if (back.State != 1) { InfoBox.Show("提示", "未知状态" + back.State, Color.Green, 1, this); return; } ReBind(new List(), new List { back }); allDetail.Add(detail); if (printCk.Checked) { var last = allMain.Where(x => x.Goods_Name == saleOutStore.Goods_Name && x.DeliverGoodsLine_Name == saleOutStore.DeliverGoodsLine_Name) .Sum(x => ((x.UnitNum ?? 0) - (x.SUnitNum ?? 0)) < 0 ? 0 : ((x.UnitNum ?? 0) - (x.SUnitNum ?? 0))); if (last < 0) last = 0; SegmentStockUpPrint.Print(detail, last, saleOutStore); } var hasUnFinish = allMain.Where(x => x.Customer_Name == saleOutStore.Customer_Name).Any(x => !x.Finishd); if (!hasUnFinish) InfoBox.Show("提示", string.Format("{0} 备货完成", saleOutStore.Customer_Name), Color.Green, 1, this); BindMainGrid(saleOutStore); } void BindMainGrid(SaleOutStoreInfo saleOutStore) { var main = new List(); foreach (var g in allMain.Where(x => x.Goods_Name == saleOutStore.Goods_Name).GroupBy(x => x.DeliverGoodsLine_Name)) { var item = new SaleOutStoreInfo(); var f = g.First(); main.Add(item); item.DeliverGoodsLine_Name = g.Key; item.Goods_Name = f.Goods_Name; item.Goods_Spec = f.Goods_Spec; item.SecondNumber = g.Sum(x => x.SecondNumber ?? 0); item.UnitNum = g.Sum(x => x.UnitNum ?? 0); item.SSecondNumber = g.Sum(x => x.SSecondNumber ?? 0); item.SUnitNum = g.Sum(x => x.SUnitNum ?? 0); } mainList = new BindingList(main.OrderBy(x => x.Finishd).ToList()); mainGridView.DataSource = mainList; mainGridView.Refresh(); BindDetail(main.Where(x => x.DeliverGoodsLine_Name == saleOutStore.DeliverGoodsLine_Name).First()); } void BindDetail(SaleOutStoreInfo first) { //if (first != null) //{ driveLineLbl.Text = first.DeliverGoodsLine_Name; goodsLbl.Text = first.Goods_Name; dhNumberLbl.Text = string.Format("{0:#0.##}", first.SecondNumber); dhUnitNumLbl.Text = string.Format("{0:#0.##}", first.UnitNum); bhNumberLbl.Text = string.Format("{0:#0.##}", first.SSecondNumber); bhUnitNumLbl.Text = string.Format("{0:#0.##}", first.SUnitNum); var detail = allDetail.Where(x => x.DeliverGoodsLine_Name == first.DeliverGoodsLine_Name && x.Goods_Name == first.Goods_Name).OrderByDescending(x => x.ID); detailList = new BindingList(detail.ToList()); //} //else //{ // driveLineLbl.Text = string.Empty; // goodsLbl.Text = string.Empty; // dhNumberLbl.Text = string.Empty; // dhUnitNumLbl.Text = string.Empty; // bhNumberLbl.Text = string.Empty; // bhUnitNumLbl.Text = string.Empty; // detailList = new BindingList(); //} detailGridView.DataSource = detailList; detailGridView.Refresh(); } private void refresh_Click(object sender, EventArgs e) { AbortTask(); StartTask(); //SegmentStockUpPrint.Print(new SegmentStockUp { DeliverGoodsLine_Name = "莱阳线商品线", Date = DateTime.Today, BarCode = "260912011201810160800008" }, 123.5m, ""); } //private void dataPicker_Click(object sender, EventArgs e) //{ // var cs = new CalendarSelecter(); // if (cs.ShowDialog() == true) // { // sendTime = cs.Result; // dataPicker.Text = sendTime.ToString("yyyy-MM-dd"); // } //} private void mainGridView_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex < 0) return; var item = mainGridView.CurrentRow.DataBoundItem as SaleOutStoreInfo; BindDetail(item); } private void mainGridView_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e) { DataGridViewRow dgrSingle = mainGridView.Rows[e.RowIndex]; var v = (bool)dgrSingle.Cells["D_Finishd"].Value; if (v) { dgrSingle.DefaultCellStyle.BackColor = Color.YellowGreen; } } private void colorButton1_Click(object sender, EventArgs e) { var detail = new SegmentStockUp() { DeliverGoodsLine_Name = "青岛龙钰聚祥万福批发部", Date = DateTime.Today, BarCode="260912011201905120100005" }; var last = 5.234m; var saleOutStore = new SaleOutStoreInfo() { Customer_Name = "青岛市大客户", SendQueue = 51 }; SegmentStockUpPrint.Print(detail, last, saleOutStore); } } class DeliverGoodsLineTemp { public string Name { get; set; } public int RowIndex { get; set; } public decimal? SecondNumber { get; set; } public decimal? UnitNum { get; set; } public decimal? SSecondNumber { get; set; } public decimal? SUnitNum { get; set; } public override bool Equals(object obj) { var tag = obj as DeliverGoodsLineTemp; return tag.Name == this.Name && tag.UnitNum == this.UnitNum && tag.SecondNumber == this.SecondNumber && tag.SUnitNum == this.SUnitNum && tag.SSecondNumber == this.SSecondNumber; } public override int GetHashCode() { var hc1 = Name.GetHashCode(); var hc2 = UnitNum.GetHashCode(); var hc3 = SecondNumber.GetHashCode(); var hc4 = SUnitNum.GetHashCode(); var hc5 = SSecondNumber.GetHashCode(); return hc1 ^ hc2 ^ hc3 ^ hc4 ^ hc5; } } }