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();
}
}
}