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;
|
|
using WinFormControl;
|
|
|
|
namespace ButcherFactory.SegmentStockUp_
|
|
{
|
|
public partial class SegmentStockUpForm : FormTemplate, IWithRoleForm
|
|
{
|
|
#region IWithRoleForm
|
|
public List<short> RoleName
|
|
{
|
|
get { return new List<short> { (short)设备类别.销售备货 }; }
|
|
}
|
|
|
|
public Form Generate()
|
|
{
|
|
return this;
|
|
}
|
|
#endregion
|
|
|
|
Tuple<string, long> selectedCustomer;
|
|
|
|
DateTime sendTime = DateTime.Today;
|
|
SegmentStockUpConfig config;
|
|
|
|
BindingList<SaleOutStoreInfo> mainList;
|
|
BindingList<SegmentStockUp> detailList;
|
|
BindingList<DeliverGoodsLineTemp> finishList;
|
|
|
|
List<SaleOutStoreInfo> allMain;
|
|
List<SegmentStockUp> allDetail;
|
|
List<AlreadyStockUp> alreadyList;
|
|
|
|
Thread syncStockdNumber;
|
|
Thread refreshFromServer;
|
|
Thread loadBindTask;//onetime
|
|
List<long> mLineGroupIds = new List<long>();
|
|
|
|
public SegmentStockUpForm()
|
|
{
|
|
config = XmlUtil.DeserializeFromFile<SegmentStockUpConfig>();
|
|
InitializeComponent();
|
|
finishList = new BindingList<DeliverGoodsLineTemp>();
|
|
allMain = new List<SaleOutStoreInfo>();
|
|
allDetail = new List<SegmentStockUp>();
|
|
alreadyList = new List<AlreadyStockUp>();
|
|
// 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)
|
|
{
|
|
BindDeliverLineGroup(false);
|
|
downWeightBox.Text = string.Format("{0:#0.######}", config.AllowDownWeight);
|
|
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<SaleOutStoreInfo> mainList, List<AlreadyStockUp> appendAlready)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
AppendData(mainList, appendAlready);
|
|
var needRefresh = PrepareFinishList();
|
|
|
|
if (needRefresh)
|
|
BindFinishGrid();
|
|
}
|
|
}
|
|
|
|
void AppendData(List<SaleOutStoreInfo> mainList, List<AlreadyStockUp> 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 = false;// item.StandardPic;
|
|
mainFirst.SUnitNum = item.UnitNum;
|
|
mainFirst.SSecondNumber = item.SecondNumber;
|
|
mainFirst.DownFloat = config.AllowDownWeight;
|
|
}
|
|
}
|
|
|
|
//返回是否需要更新Grid;
|
|
bool PrepareFinishList()
|
|
{
|
|
var old = finishList.ToList();
|
|
var append = new List<DeliverGoodsLineTemp>();
|
|
finishList = new BindingList<DeliverGoodsLineTemp>();
|
|
var idx = 0;
|
|
foreach (var item in allMain.GroupBy(x => x.Customer_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<long> tags = new List<long>();
|
|
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<SaleOutStoreInfo>(), temp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void RefreshFromServer()
|
|
{
|
|
while (true)
|
|
{
|
|
Thread.Sleep(2 * 60 * 1000);
|
|
var temp = SegmentStockUpBL.GetSaleOutStoreList(sendTime);
|
|
if (temp.Any())
|
|
{
|
|
ReBind(temp, new List<AlreadyStockUp>());
|
|
}
|
|
}
|
|
}
|
|
|
|
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<string, decimal?, bool> scan)
|
|
{
|
|
SaleOutStoreInfo saleOutStore;
|
|
if (selectedCustomer != null)
|
|
saleOutStore = allMain.FirstOrDefault(x => x.Customer_Name == selectedCustomer.Item1 && !x.Finishd && x.Goods_Code == scan.Item1);
|
|
else
|
|
saleOutStore = allMain.FirstOrDefault(x => mLineGroupIds.Contains(x.DeliverLineGroup_ID ?? 0) && !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.Customer_Name = saleOutStore.Customer_Name;
|
|
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 = 0m;
|
|
if (saleOutStore.StockUpBySecondNum)
|
|
number = saleOutStore.SecondNumber ?? 0;
|
|
else
|
|
number = (saleOutStore.UnitNum ?? 0) - (config.AllowDownWeight ?? 0);
|
|
//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, saleOutStore.StockUpBySecondNum);
|
|
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<SaleOutStoreInfo>(), new List<AlreadyStockUp> { back });
|
|
InsertDetail(scan);
|
|
return;
|
|
}
|
|
if (back.State != 1)
|
|
{
|
|
InfoBox.Show("提示", "未知状态" + back.State, Color.Green, 1, this);
|
|
return;
|
|
}
|
|
ReBind(new List<SaleOutStoreInfo>(), new List<AlreadyStockUp> { back });
|
|
allDetail.Add(detail);
|
|
|
|
if (printCk.Checked)
|
|
{
|
|
var last = 0m;
|
|
// 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<SaleOutStoreInfo>();
|
|
foreach (var g in allMain.Where(x => x.Goods_Name == saleOutStore.Goods_Name).GroupBy(x => x.Customer_Name))
|
|
{
|
|
var item = new SaleOutStoreInfo();
|
|
var f = g.First();
|
|
main.Add(item);
|
|
item.Customer_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);
|
|
item.DownFloat = config.AllowDownWeight;
|
|
item.StockUpBySecondNum = f.StockUpBySecondNum;
|
|
item.FinishAssign = f.FinishAssign;
|
|
}
|
|
mainList = new BindingList<SaleOutStoreInfo>(main.OrderBy(x => x.Finishd).ToList());
|
|
|
|
mainGridView.DataSource = mainList;
|
|
mainGridView.Refresh();
|
|
BindDetail(main.Where(x => x.Customer_Name == saleOutStore.Customer_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.Customer_Name == first.Customer_Name && x.Goods_Name == first.Goods_Name).OrderByDescending(x => x.ID);
|
|
detailList = new BindingList<SegmentStockUp>(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<SegmentStockUp>();
|
|
//}
|
|
detailGridView.DataSource = detailList;
|
|
detailGridView.Refresh();
|
|
}
|
|
|
|
private void refresh_Click(object sender, EventArgs e)
|
|
{
|
|
AbortTask();
|
|
StartTask();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
private void label2_Click(object sender, EventArgs e)
|
|
{
|
|
var dialog = new SelectCustomerDialog();
|
|
if (dialog.ShowDialog() == DialogResult.OK)
|
|
{
|
|
selectedCustomer = dialog.Result;
|
|
if (selectedCustomer == null)
|
|
label2.Text = "请选择";
|
|
else
|
|
label2.Text = selectedCustomer.Item1;
|
|
}
|
|
}
|
|
|
|
private void downWeightBox_Click(object sender, EventArgs e)
|
|
{
|
|
var pad = new NumberPad();
|
|
if (pad.ShowDialog() == true)
|
|
{
|
|
decimal? weight = null;
|
|
if (!string.IsNullOrEmpty(pad.Result))
|
|
{
|
|
decimal v;
|
|
if (decimal.TryParse(pad.Result, out v))
|
|
weight = v;
|
|
else
|
|
throw new Exception("输入错误");
|
|
}
|
|
downWeightBox.Text = string.Format("{0:#0.######}", weight);
|
|
config.AllowDownWeight = weight;
|
|
XmlUtil.SerializerObjToFile(config);
|
|
}
|
|
}
|
|
|
|
private void lineGroupSetBtn_Click(object sender, EventArgs e)
|
|
{
|
|
new DeliverLineGroupSelectDialog().ShowDialog();
|
|
BindDeliverLineGroup(true);
|
|
}
|
|
|
|
Color color = Color.FromArgb(105, 105, 105);
|
|
Color selectColor = Color.FromArgb(250, 120, 24);
|
|
void BindDeliverLineGroup(bool loadNew)
|
|
{
|
|
flowLayoutPanel1.Controls.Clear();
|
|
mLineGroupIds.Clear();
|
|
if (loadNew)
|
|
config = XmlUtil.DeserializeFromFile<SegmentStockUpConfig>();
|
|
foreach (var item in config.LineGroup)
|
|
{
|
|
var btn = new ColorButton() { Width = 150, Height = 60, Text = item.Name, Tag = item, Font = new Font("宋体", 14), Margin = new Padding(30) };
|
|
btn.BackColor = color;
|
|
btn.Click += DeliverLineBtn_Click;
|
|
flowLayoutPanel1.Controls.Add(btn);
|
|
}
|
|
}
|
|
|
|
private void DeliverLineBtn_Click(object sender, EventArgs e)
|
|
{
|
|
var btn = sender as ColorButton;
|
|
var item = (DeliverLineGroup)btn.Tag;
|
|
var first = mLineGroupIds.FirstOrDefault(x => x == item.ID);
|
|
if (first == 0)
|
|
{
|
|
mLineGroupIds.Add(item.ID);
|
|
btn.BackColor = selectColor;
|
|
}
|
|
else
|
|
{
|
|
mLineGroupIds.Remove(item.ID);
|
|
btn.BackColor = color;
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|