using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Text; using WMS.Web.Core; using WMS.Web.Core.Help; using WMS.Web.Core.Internal.Results; using WMS.Web.Domain.Values; namespace WMS.Web.Domain.Entitys { /// /// erp出库任务单 /// [Serializable] [Table("t_erp_outstock_task")] public class OutStockTask : EntityBase { public OutStockTask() { } /// /// 主键 订单编号 /// [Column("Id")] public override int Id { get; set; } /// /// 单据编号 /// [Column("BillNo")] public string BillNo { get; set; } /// /// 发货组织 /// [Column("DeliveryOrgId")] public int DeliveryOrgId { get; set; } /// /// 组织编码 /// [Column("OrgCode")] public string OrgCode { get; set; } /// /// 收货客户 /// [Column("ReceiptCustomerId")] public int ReceiptCustomerId { get; set; } /// /// 仓库ID /// [Column("StockCode")] public string StockCode { get; set; } = ""; /// /// 单据状态 /// [Column("Status")] public OutStockStatus Status { get; set; } = OutStockStatus.Wait; /// /// 单据类型 /// [Column("Type")] public OutStockType Type { get; set; } = OutStockType.Sal; /// /// 操作人 /// [Column("OperatorId")] public int? OperatorId { get; set; } /// /// 操作时间 /// [Column("OperateTime")] public DateTime? OperateTime { get; set; } /// /// 出库人 /// [Column("OutStockId")] public int? OutStockId { get; set; } /// /// 出库时间 /// [Column("OutStockTime")] public DateTime? OutStockTime { get; set; } /// /// 创建时间(erp那边的创建时间) /// [Column("CreateTime")] public DateTime? CreateTime { get; set; } /// /// 在wms最新数据修改时间 /// [Column("WmsUpdateTime")] public DateTime WmsUpdateTime { get; set; } = DateTime.Now; /// /// 明细 /// public List Details = new List(); public void Create(OutStockType type, string stockCode, string orgCode, int deliveryOrgId, int receiptCustomerId, DateTime createTime) { this.Type = type; this.StockCode = stockCode; this.OrgCode = orgCode; this.DeliveryOrgId = deliveryOrgId; this.ReceiptCustomerId = receiptCustomerId; this.CreateTime = createTime; } /// /// 出库 反写 任务单(返回 这个物料下面的来源单号出了多少数量) /// /// /// /// public Result> OutStock(string materialNumber, decimal qty, int outStockId) { if (this.Status == OutStockStatus.Already) return Result>.ReFailure(ResultCodes.OutStockTaskAlready); if (this.Status == OutStockStatus.Repeal) return Result>.ReFailure(ResultCodes.OutStockTaskRepeal); var detail = this.Details.FirstOrDefault(f => f.MaterialNumber == materialNumber); if (detail == null) return Result>.ReFailure(ResultCodes.OrderNoData); if ((detail.AccruedQty - detail.RealityQty) < qty) return Result>.ReFailure(ResultCodes.OutStockQtyError); List<(int erpDetailId, decimal qty)> resList = new List<(int erpDetailId, decimal qty)>(); var mQty = qty; foreach (var d in detail.ErpDetails) { if ((d.AccruedQty - d.RealityQty) >= mQty) { d.RealityQty += qty; resList.Add((d.Erp_DetailId, mQty)); break;//本次出库数量已经分配完毕 调出循环 } else { //代表这一个来源单号对应的物料 能全部出掉,并且还有剩余 进行下一个来源单的出货 var cQty = d.AccruedQty - d.RealityQty;//本次出货数量 mQty -= cQty; d.RealityQty = d.AccruedQty; resList.Add((d.Erp_DetailId, cQty)); } } if (detail.RealityQty <= 0) detail.OutStockBeginTime = DateTime.Now; //全部出库完成 if (detail.AccruedQty == (detail.RealityQty + qty)) detail.OutStockEndTime = DateTime.Now; detail.RealityQty = detail.RealityQty + qty; this.OutStockId = outStockId; this.OutStockTime = DateTime.Now; GenerateStatus(); return Result>.ReSuccess(resList); } /// /// 自动验证出库状态 /// public void GenerateStatus() { if (this.Status == OutStockStatus.Repeal) return; var details = this.Details.Where(w => w.IsRepeal != true).ToList(); if (details.Where(w => w.RealityQty <= 0).Count() == details.Count()) this.Status = OutStockStatus.Wait; else if (details.Where(w => w.RealityQty >= w.AccruedQty).Count() == details.Count()) this.Status = OutStockStatus.Already; else this.Status = OutStockStatus.Part; } /// /// 生成单据号 /// public void GenerateNo() { //用户手动输入了 就不自动生成了 if (!string.IsNullOrEmpty(this.BillNo)) return; if (this.Id.ToString().Length >= 8) { this.BillNo = "CKRW" + this.Id.ToString(); return; } string idStr = this.Id.ToString(); while (true) { idStr = "0" + idStr; if (idStr.Length >= 8) break; } //this.Number = CNSpellTranslator.GetFirstSpell(this.Name) + idStr; this.BillNo = "CKRW" + idStr; } /// /// 作废 /// public void Repeal(int creatorId, List ids) { this.OperatorId = creatorId; this.OperateTime = DateTime.Now; foreach (var d in this.Details.Where(w => ids.Contains(w.Id))) { d.IsRepeal = true; } //如果明细全部作废,则单据状态作废 if (this.Details.Where(w => w.IsRepeal == true).Count() == this.Details.Count()) this.Status = OutStockStatus.Repeal; GenerateStatus(); } /// /// 反作废 /// public void NoRepeal(int creatorId, List ids) { this.OperatorId = 0; this.OperateTime = null; foreach (var d in this.Details.Where(w => ids.Contains(w.Id))) { d.IsRepeal = false; } var details = this.Details.Where(w => w.IsRepeal != true).ToList(); if (details.Where(w => w.RealityQty <= 0).Count() == details.Count()) this.Status = OutStockStatus.Wait; else if (details.Where(w => w.RealityQty >= w.AccruedQty).Count() == details.Count()) this.Status = OutStockStatus.Already; else this.Status = OutStockStatus.Part; } /// /// 合并 /// /// /// /// public Result Merge(List list, int creatorId) { if (list.Count() <= 1) return Result.ReFailure(ResultCodes.MergeNumberError); // 符合合并数据逻辑:出库状态为”待拣货”+出库类型为:销售出库+发货组织一致+收货客户一致+发货仓库一致 if (list.Where(w => w.Status != OutStockStatus.Wait).Any()) return Result.ReFailure(ResultCodes.MergeStatusError); if (list.Where(w => w.Type != OutStockType.Sal).Any()) return Result.ReFailure(ResultCodes.MergeStatusError); if (list.GroupBy(g => g.DeliveryOrgId).Count() > 1) return Result.ReFailure(ResultCodes.MergeStatusError); if (list.GroupBy(g => g.ReceiptCustomerId).Count() > 1) return Result.ReFailure(ResultCodes.MergeStatusError); if (list.GroupBy(g => g.OrgCode).Count() > 1) return Result.ReFailure(ResultCodes.MergeStatusError); var details = list.SelectMany(s => s.Details).ToList().Clone(); if (list.GroupBy(g => g.StockCode).Count() > 1) return Result.ReFailure(ResultCodes.MergeStatusError); List details_new = new List(); //清空数据绑定 foreach (var d in details) { d.Id = 0; d.Fid = 0; var detail_new = details_new.FirstOrDefault(f => f.MaterialNumber == d.MaterialNumber); if (detail_new != null) { detail_new.AccruedQty += d.AccruedQty;//应出数量累加 detail_new.Remark = detail_new.Remark + "\r\n" + d.Remark; foreach (var erpd in d.ErpDetails) { var cd = erpd.Clone(); cd.Id = 0; cd.DetailId = 0; detail_new.ErpDetails.Add(cd); } } else { foreach (var erpd in d.ErpDetails) { erpd.Id = 0; erpd.DetailId = 0; } details_new.Add(d); } } this.CreateTime = list.Max(o => o.CreateTime);//取最新的时间 this.OperatorId = creatorId; this.OperateTime = DateTime.Now; this.Status = OutStockStatus.Wait; this.DeliveryOrgId = list.First().DeliveryOrgId; this.ReceiptCustomerId = list.First().ReceiptCustomerId; this.StockCode = list.First().StockCode; this.OrgCode = list.First().OrgCode; this.Type = OutStockType.Sal; this.Details = details_new; return Result.ReSuccess(); } } }