Files
WMS-Api/src/WMS.Web.Domain/Entitys/OutStockTask.cs
18942506660 8903f86d60 修复bug
2023-12-27 11:58:13 +08:00

261 lines
9.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// erp出库任务单
/// </summary>
[Serializable]
[Table("t_erp_outstock_task")]
public class OutStockTask : EntityBase
{
public OutStockTask() { }
/// <summary>
/// 主键 订单编号
/// </summary>
[Column("Id")]
public override int Id { get; set; }
/// <summary>
/// 单据编号
/// </summary>
[Column("BillNo")]
public string BillNo { get; set; }
/// <summary>
/// 发货组织
///</summary>
[Column("DeliveryOrgId")]
public int DeliveryOrgId { get; set; }
/// <summary>
/// 组织编码
///</summary>
[Column("OrgCode")]
public string OrgCode { get; set; }
/// <summary>
/// 收货客户
///</summary>
[Column("ReceiptCustomerId")]
public int ReceiptCustomerId { get; set; }
/// <summary>
/// 仓库ID
///</summary>
[Column("StockCode")]
public string StockCode { get; set; } = "";
/// <summary>
/// 单据状态
/// </summary>
[Column("Status")]
public OutStockStatus Status { get; set; } = OutStockStatus.Wait;
/// <summary>
/// 单据类型
/// </summary>
[Column("Type")]
public OutStockType Type { get; set; } = OutStockType.Sal;
/// <summary>
/// 操作人
/// </summary>
[Column("OperatorId")]
public int? OperatorId { get; set; }
/// <summary>
/// 操作时间
/// </summary>
[Column("OperateTime")]
public DateTime? OperateTime { get; set; }
/// <summary>
/// 出库人
/// </summary>
[Column("OutStockId")]
public int? OutStockId { get; set; }
/// <summary>
/// 出库时间
/// </summary>
[Column("OutStockTime")]
public DateTime? OutStockTime { get; set; }
/// <summary>
/// 创建时间erp那边的创建时间
///</summary>
[Column("CreateTime")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 明细
/// </summary>
public List<OutStockTaskDetails> Details = new List<OutStockTaskDetails>();
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;
}
/// <summary>
/// 出库 反写 任务单(返回 这个物料下面的来源单号出了多少数量)
/// </summary>
/// <param name="materialId"></param>
/// <param name="qty"></param>
/// <returns></returns>
public Result<List<(int erpDetailId, decimal qty)>> OutStock(int materialId, decimal qty, int outStockId)
{
if (this.Status == OutStockStatus.Already)
return Result<List<(int erpDetailId, decimal qty)>>.ReFailure(ResultCodes.OutStockTaskAlready);
if (this.Status == OutStockStatus.Repeal)
return Result<List<(int erpDetailId, decimal qty)>>.ReFailure(ResultCodes.OutStockTaskRepeal);
var detail = this.Details.FirstOrDefault(f => f.MaterialId == materialId);
if (detail == null) return Result<List<(int erpDetailId, decimal qty)>>.ReFailure(ResultCodes.OrderNoData);
if ((detail.AccruedQty - detail.RealityQty) < qty)
return Result<List<(int erpDetailId, decimal qty)>>.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<List<(int erpDetailId, decimal qty)>>.ReSuccess(resList);
}
/// <summary>
/// 自动验证出库状态
/// </summary>
public void GenerateStatus()
{
if (this.Status == OutStockStatus.Repeal)
return;
if (this.Details.Where(w => w.RealityQty <= 0).Count() == this.Details.Count())
this.Status = OutStockStatus.Wait;
else if (this.Details.Where(w => w.RealityQty >= w.AccruedQty).Count() == this.Details.Count())
this.Status = OutStockStatus.Already;
else
this.Status = OutStockStatus.Part;
}
/// <summary>
/// 生成单据号
/// </summary>
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;
}
/// <summary>
/// 作废
/// </summary>
public void Repeal(int creatorId)
{
this.OperatorId = creatorId;
this.OperateTime = DateTime.Now;
this.Status = OutStockStatus.Repeal;
}
/// <summary>
/// 合并
/// </summary>
/// <param name="list"></param>
/// <param name="creatorId"></param>
/// <returns></returns>
public Result Merge(List<OutStockTask> 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<OutStockTaskDetails> details_new = new List<OutStockTaskDetails>();
//清空数据绑定
foreach (var d in details)
{
d.Id = 0;
d.Fid = 0;
var detail_new = details_new.FirstOrDefault(f => f.MaterialId == d.MaterialId);
if (detail_new != null)
{
detail_new.AccruedQty += d.AccruedQty;//应出数量累加
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();
}
}
}