public static void RunTask() { var now = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); int week = GetWeek(now); if (week == 1 || week == 3) { #region --> 今天周一或周三 var pg = DataAccessor.GetPurchasingGoodsList(TaskType.All); var goodsIdList = pg.Select(w => w.GoodsId).Distinct().ToList(); IList <GoodsInfo> goodsList = _goodsCenterSao.GetGoodsListByGoodsIds(goodsIdList).ToList(); if (goodsList.Count == 0) { return; } var dictPurchase = new Dictionary <PurchasingInfo, List <PurchasingDetailInfo> >(); var purchasingSets = new List <PurchasingGoods>(); pg = pg.Where(w => w.StockUpDay == week && w.HostingFilialeId != Guid.Empty).ToList(); var goodsDics = goodsList.ToDictionary(k => k.GoodsId, v => v); var realGoodsDics = new Dictionary <Guid, GoodsInfo>(); Dictionary <Guid, List <Guid> > goodsWithRealGoods = new Dictionary <Guid, List <Guid> >(); foreach (var warehouseIdGroup in pg.GroupBy(act => new { act.WarehouseId, act.HostingFilialeId })) { var warehouseId = warehouseIdGroup.Key.WarehouseId; var hostingFilialeId = warehouseIdGroup.Key.HostingFilialeId; var stockStatistics = WMSSao.GetStockStatisticsDtosForAuto(warehouseId, hostingFilialeId); var planPurchasingGoods1 = DataAccessor.GetAllSumPurchasingQuantity(warehouseId, hostingFilialeId).ToDictionary(k => k.GoodsID, v => v.PurchasingQuantity); foreach (var companyIdGroup in warehouseIdGroup.GroupBy(act => act.CompanyId)) { var purchaseGroupIds = companyIdGroup.Select(w => w.PurchaseGroupId).Distinct().ToList(); foreach (var purchaseGroupId in purchaseGroupIds) { //采购分组 var pgList = companyIdGroup.Where(w => w.PurchaseGroupId == purchaseGroupId).ToList(); var personResponsibles = pgList.Select(w => w.PersonResponsible).Distinct().ToList(); foreach (var personResponsible in personResponsibles) { var prList = pgList.Where(w => w.PersonResponsible == personResponsible).ToList(); if (prList.Count > 0) { foreach (var prInfo in prList.Where(ent => goodsDics.ContainsKey(ent.GoodsId))) { GoodsInfo goodsInfo = goodsDics[prInfo.GoodsId]; if (goodsInfo == null) { continue; } prInfo.GoodsName = goodsInfo.GoodsName; prInfo.GoodsCode = goodsInfo.GoodsCode; prInfo.Units = goodsInfo.Units; if (goodsInfo.ExpandInfo != null) { prInfo.PackQuantity = goodsInfo.ExpandInfo.PackCount; } List <Guid> realGoodsIdList; if (goodsWithRealGoods.ContainsKey(prInfo.GoodsId)) { realGoodsIdList = goodsWithRealGoods[prInfo.GoodsId]; } else { realGoodsIdList = _goodsCenterSao.GetRealGoodsIdsByGoodsId(prInfo.GoodsId).ToList(); if (realGoodsIdList.Count == 0) { realGoodsIdList.Add(prInfo.GoodsId); } goodsWithRealGoods.Add(prInfo.GoodsId, realGoodsIdList); } int stockUpDays = prInfo.FilingForm == 1 ? GetStockUpDays(prInfo) : prInfo.FilingTrigger; if (stockUpDays == 0) { continue; } var childGoodsSaleAll = GetChildGoodsSaleTotalByDays(realGoodsIdList, new List <Guid> { prInfo.WarehouseId }, stockUpDays, now); if (childGoodsSaleAll.Count > 0) { foreach (var sale in childGoodsSaleAll) { sale.PlanPurchasingquantity = sale.WeightedAverageSaleQuantity * stockUpDays; if (sale.PlanPurchasingquantity > 0) { //个位数0<x<=5向上取为5,个位数为6<x<=9向上取整为10 char[] temp = sale.PlanPurchasingquantity.ToString(CultureInfo.InvariantCulture).ToArray(); int unitsDigit = Convert.ToInt32(temp[temp.Length - 1]); if (unitsDigit > 0 && unitsDigit < 5) { sale.PlanPurchasingquantity += 5 - unitsDigit; } else if (unitsDigit > 5) { sale.PlanPurchasingquantity += 10 - unitsDigit; } } //计算当前的采购商品数量,包含扣除的已经采购完成和部分采购完成和赠品类型 sale.SubtractPurchasingQuantity = planPurchasingGoods1.ContainsKey(sale.GoodsId)? planPurchasingGoods1[sale.GoodsId] : 0; //计算当前仓库存货数量 sale.NonceWarehouseStockQuantity = stockStatistics.Where(ent => ent.RealGoodsId == sale.GoodsId).Sum(info => info.CurrentStock + info.UppingQuantity - info.RequireQuantity - info.SubtotalQuantity); if (prInfo.FilingForm == 2) { //2触发报备 //计算是否满足不足数量 double planQuantity = sale.WeightedAverageSaleQuantity * prInfo.Insufficient; double realityQuantity = Math.Ceiling(planQuantity - sale.SubtractPurchasingQuantity - sale.NonceWarehouseStockQuantity); if (realityQuantity <= 0) { //无需报备 continue; } } if (sale.RealityNeedPurchasingQuantity > 0) { var salesinfo = DataAccessor.GetChildGoodsSale(sale.GoodsId, warehouseId, sale.HostingFilialeId, DateTime.Now); PurchasingInfo existingPurchasingInfo = null; bool isExist = false; if (dictPurchase.Keys.Count > 0) { existingPurchasingInfo = dictPurchase.Keys.FirstOrDefault(act => act.PersonResponsible == personResponsible && act.PurchasingFilialeId == hostingFilialeId && act.WarehouseID == warehouseId && companyIdGroup.Key == act.CompanyID); } var detailList = new List <PurchasingDetailInfo>(); if (existingPurchasingInfo == null) { existingPurchasingInfo = new PurchasingInfo { PurchasingID = Guid.NewGuid(), CompanyID = companyIdGroup.Key, CompanyName = prList[0].CompanyName, WarehouseID = warehouseId, PurchasingState = (int)PurchasingState.NoSubmit, PurchasingType = (int)PurchasingType.AutoStock, PersonResponsible = personResponsible, PurchaseGroupId = purchaseGroupId, StartTime = DateTime.Now, EndTime = DateTime.MaxValue, Description = string.Format("[采购类别:{0};系统自动报备]", EnumAttribute.GetKeyName(PurchasingType.Custom)), FilialeID = hostingFilialeId, PurchasingFilialeId = hostingFilialeId }; } else { isExist = true; detailList = dictPurchase[existingPurchasingInfo]; } var purchasingDetailInfo = new PurchasingDetailInfo { PurchasingID = existingPurchasingInfo.PurchasingID, GoodsID = sale.GoodsId, GoodsName = prInfo.GoodsName, GoodsCode = prInfo.GoodsCode, Specification = sale.Specification, CompanyID = companyIdGroup.Key, Price = prInfo.Price, PlanQuantity = sale.RealityNeedPurchasingQuantity, RealityQuantity = 0, State = 0, Units = prInfo.Units, PurchasingGoodsID = Guid.NewGuid(), SixtyDaySales = salesinfo.SixtyDaySales, ThirtyDaySales = salesinfo.ThirtyDaySales, ElevenDaySales = salesinfo.ElevenDaySales, CPrice = prInfo.Price }; detailList.Add(purchasingDetailInfo); if (!realGoodsDics.ContainsKey(sale.GoodsId)) { realGoodsDics.Add(sale.GoodsId, goodsInfo); } if (detailList.Count > 0 && !isExist) { dictPurchase.Add(existingPurchasingInfo, detailList); } } } if (!purchasingSets.Any(act => act.WarehouseId == warehouseId && act.HostingFilialeId == hostingFilialeId && act.GoodsId == prInfo.GoodsId)) { purchasingSets.Add(prInfo); } } } } } } } } PurchasingPromotion(dictPurchase, realGoodsDics, purchasingSets); #endregion } }
/// <summary> /// 循环遍历子商品的销售和采购信息 /// </summary> /// <param name="p"></param> /// <param name="childGoodsSaleAll"></param> /// <param name="warehouseId"></param> /// <param name="hostingFilialeId"></param> /// <param name="avgStockDays"></param> /// <param name="nextStockDate"></param> /// <param name="taskType"></param> /// <param name="step"></param> /// <param name="nextPurchasingDate"></param> private static void OperationSaleAndPurchasing(PurchasingGoods p, IEnumerable <ChildGoodsSalePurchasing> childGoodsSaleAll, Guid warehouseId, Guid hostingFilialeId, int avgStockDays, DateTime nextStockDate, TaskType taskType, int step, DateTime nextPurchasingDate, List <ERP.SAL.WMS.StockStatisticsDTO> stocks) { //如果传过来的仓库ID是空,说明是指定仓库 if (warehouseId == Guid.Empty) { warehouseId = p.WarehouseId; } //产生一个采购单ID var purchasingId = Guid.NewGuid(); var tempPurchasingId = DataAccessor.GetSamePurchasingId(p.CompanyId, p.PersonResponsible, warehouseId, hostingFilialeId); if (tempPurchasingId != Guid.Empty) { purchasingId = tempPurchasingId; } //是否有子商品采购信息 var hasChildGoodsPurchasingInfo = false; var isException = false; string purchasingNo = DataAccessor.GetCode(BaseInfo.CodeType.PH); List <ChildGoodsSalePurchasing> childGoodsSalePurchasingList = childGoodsSaleAll.ToList(); List <Guid> goodsIdOrRealGoodsIdList = childGoodsSalePurchasingList.Select(w => w.GoodsId).Distinct().ToList(); Dictionary <Guid, GoodsInfo> dicGoods = _goodsCenterSao.GetGoodsBaseListByGoodsIdOrRealGoodsIdList(goodsIdOrRealGoodsIdList); //如果赠送方式为总数量赠送时使用 key 主商品ID value 额外赠送 var dics = new Dictionary <Guid, int>(); //循环遍历子商品的销售和采购信息 foreach (var sale in childGoodsSaleAll) { #if debug Console.WriteLine("规格:{0},销售一:{1},销售二:{2},销售三:{3},平均销售:{4},增长率:{5}", sale.Specification, sale.FirstNumberOneStockUpSale, sale.FirstNumberTwoStockUpSale, sale.FirstNumberThreeStockUpSale, sale.WeightedAverageSaleQuantity, sale.SaleInCrease); #endif //计算计划采购数量 if (taskType == TaskType.Warning) { if (step == 4) { sale.PlanPurchasingquantity = sale.WeightedAverageSaleQuantity * ((nextStockDate - DateTime.Now).Days + 1 + p.ArrivalDays); } else { sale.PlanPurchasingquantity = sale.WeightedAverageSaleQuantity * (avgStockDays + p.ArrivalDays); } } else if (taskType == TaskType.Routine) { if (step == 3) { sale.PlanPurchasingquantity = sale.WeightedAverageSaleQuantity * ((nextPurchasingDate - DateTime.Now).Days + (avgStockDays * 2) + 1 + p.ArrivalDays); } else { sale.PlanPurchasingquantity = sale.WeightedAverageSaleQuantity * ((nextStockDate - DateTime.Now).Days + 1 + p.ArrivalDays); } } //计算当前的采购商品数量,包含扣除的已经采购完成和部分采购完成和赠品类型 sale.SubtractPurchasingQuantity = DataAccessor.GetSumPurchasingQuantity(sale.GoodsId, warehouseId, hostingFilialeId); //计算当前仓库存货数量 var info = stocks.FirstOrDefault(act => act.RealGoodsId == sale.GoodsId); sale.NonceWarehouseStockQuantity = info != null ? info.CurrentStock + info.UppingQuantity - info.RequireQuantity : 0; #if debug Console.WriteLine("预计采购:{0},采购中的数量:{1},当前库存数量:{2}", sale.PlanPurchasingquantity, sale.SubtractPurchasingQuantity, sale.NonceWarehouseStockQuantity); if (sale.GoodsId == "D41FBCB0-DB51-447D-8F7C-9767D612EC2B".ToGuid()) { sale.IsNull(); } #endif //判断实际的采购数量大于零时,新增一条采购记录 if (sale.RealityNeedPurchasingQuantity > 0) { //如果是预警报备,计划采购还是到下一次周期的报备 if (taskType == TaskType.Warning) { sale.PlanPurchasingquantity = sale.WeightedAverageSaleQuantity * ((nextStockDate - DateTime.Now).Days + 1 + p.ArrivalDays); } #if debug Console.WriteLine("实际采购数量:{0}", sale.RealityNeedPurchasingQuantity); #endif //判断是否有最低库存,如果有要判断采购是否满足最低库存 var minStockQuantity = DataAccessor.GetGoodsStockMinQuantity(sale.GoodsId, p.WarehouseId); if (minStockQuantity > 0) { if (sale.RealityNeedPurchasingQuantity < minStockQuantity) { var newPlanPurchasingquantity = (minStockQuantity - sale.RealityNeedPurchasingQuantity) + sale.PlanPurchasingquantity; sale.PlanPurchasingquantity = newPlanPurchasingquantity; } } //采购数 int purchasingQuantity = 0; #region [现返] //处理原理: //赠品数量=原采购数量/(买几个+送几个)*送几个 //购买数量=原采购数量-赠品数量 int zpquantity = 0; var goodsInfo = new GoodsInfo(); if (dicGoods != null) { bool hasKey = dicGoods.ContainsKey(sale.GoodsId); if (hasKey) { goodsInfo = dicGoods.FirstOrDefault(w => w.Key == sale.GoodsId).Value; } } IList <PurchasePromotionInfo> ppList = DataAccessor.GetPurchasePromotionList(goodsInfo.GoodsId, (int)PurchasePromotionType.Back, hostingFilialeId); PurchasePromotionInfo ppInfo = ppList.FirstOrDefault(w => w.GivingCount > 0 && w.StartDate <= DateTime.Now && w.EndDate >= DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " 17:29:59")); if (ppInfo != null) { //赠品数量=原采购数量/(买几个+送几个)*送几个 zpquantity = (int)sale.RealityNeedPurchasingQuantity / (ppInfo.BuyCount + ppInfo.GivingCount) * ppInfo.GivingCount; if (zpquantity > 0) { int xfQuantity = (int)sale.RealityNeedPurchasingQuantity - zpquantity; //现返类型实际要采购多少数量 purchasingQuantity = (int)GetBoxNumber(p.PackQuantity, xfQuantity); //加入箱数采购算法计算采购数 } } else { purchasingQuantity = (int)GetBoxNumber(p.PackQuantity, (int)sale.RealityNeedPurchasingQuantity);//加入箱数采购算法计算采购数 } #endregion #region [非现返生成借记单] var addedExtra = new List <Guid>(); //借记单明细 var debitNoteDetailList = new List <DebitNoteDetailInfo>(); IList <PurchasePromotionInfo> ppList2 = DataAccessor.GetPurchasePromotionList(goodsInfo.GoodsId, (int)PurchasePromotionType.NoBack, hostingFilialeId); PurchasePromotionInfo ppInfo2 = ppList2.FirstOrDefault(w => w.GivingCount > 0 && w.StartDate <= DateTime.Now && w.EndDate >= DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " 17:29:59")); if (ppInfo2 != null) { int pQuantity = (int)sale.RealityNeedPurchasingQuantity; //赠品数量=原采购数量/买几个*送几个 int fxfzpquantity = pQuantity / ppInfo2.BuyCount * ppInfo2.GivingCount; int extra = addedExtra.Contains(goodsInfo.GoodsId) ? 0 : dics[goodsInfo.GoodsId]; if (!addedExtra.Contains(goodsInfo.GoodsId)) { addedExtra.Add(goodsInfo.GoodsId); } if (fxfzpquantity > 0 || extra > 0) { var debitNoteDetailInfo = new DebitNoteDetailInfo { PurchasingId = purchasingId, GoodsId = sale.GoodsId, GoodsName = p.GoodsName, Specification = sale.Specification, GivingCount = fxfzpquantity + extra, ArrivalCount = 0, Price = p.Price, State = 0, Amount = fxfzpquantity * p.Price, Memo = "", Id = Guid.NewGuid() }; debitNoteDetailList.Add(debitNoteDetailInfo); } if (debitNoteDetailList.Count > 0) { var debitNoteInfo = new DebitNoteInfo { PurchasingId = purchasingId, PurchasingNo = purchasingNo, CompanyId = p.CompanyId, PresentAmount = debitNoteDetailList.Sum(w => w.Amount), CreateDate = DateTime.Now, FinishDate = DateTime.MinValue, State = (int)DebitNoteState.ToPurchase, WarehouseId = p.WarehouseId, Memo = "", PersonResponsible = p.PersonResponsible, NewPurchasingId = Guid.Empty }; var dnInfo = DataAccessor.GetDebitNoteInfo(purchasingId); //是否已经有借记单 if (dnInfo != null && dnInfo.PurchasingId != Guid.Empty) //已经有借记单则修改借记单 { var dnlist = DataAccessor.GetDebitNoteDetailList(purchasingId); if (dnlist != null && dnlist.Any(act => act.GoodsId == sale.GoodsId)) { DataAccessor.UpdateDebitNoteDetail(purchasingId, sale.GoodsId, fxfzpquantity); } else { foreach (var dinfo in debitNoteDetailList) { DataAccessor.AddDebitNoteDetail(dinfo); } } } else { DataAccessor.AddPurchaseSetAndDetail(debitNoteInfo, debitNoteDetailList); } } } #endregion var purchasingGoodsId = Guid.Empty; if (tempPurchasingId != Guid.Empty) { purchasingGoodsId = DataAccessor.GetSamePurchasingGoodsId(tempPurchasingId, sale.GoodsId, sale.Specification, sale.HostingFilialeId); } if (purchasingGoodsId != Guid.Empty) { DataAccessor.UpdatePurchasingGoodsPlanQuantity(purchasingGoodsId, purchasingQuantity); if (zpquantity > 0)//如果有现反赠品则添加一条采购明细记录 { var salesinfo = DataAccessor.GetChildGoodsSale(sale.GoodsId, warehouseId, hostingFilialeId, DateTime.Now); DataAccessor.InsertPurchasingDetail(Guid.NewGuid(), (tempPurchasingId == Guid.Empty ? purchasingId : tempPurchasingId), sale.GoodsId, p.GoodsName, p.Units, p.GoodsCode, sale.Specification, p.CompanyId, 0, zpquantity, 0, 0, string.Empty, sale.WeightedAverageSaleQuantity / 30, zpquantity, p.StockingDays + p.ArrivalDays, isException, salesinfo.SixtyDaySales, salesinfo.ThirtyDaySales, (salesinfo.ElevenDaySales / 11), (int)PurchasingGoodsType.Gift); } } else { if (sale.RealityNeedPurchasingQuantity > 0) { var salesinfo = DataAccessor.GetChildGoodsSale(sale.GoodsId, warehouseId, hostingFilialeId, DateTime.Now); if (salesinfo.GoodsId != Guid.Empty) { //当前活动报备异常 if ((salesinfo.ElevenDaySales / 11) >= ((salesinfo.ThirtyDaySales / 30) * 1.8)) { isException = true; } //历史活动报备异常 if ((salesinfo.ElevenDaySales / 11) * 1.6 <= (salesinfo.ThirtyDaySales / 30) || (salesinfo.ElevenDaySales / 11) * 1.6 <= (salesinfo.SixtyDaySales / 30)) { isException = true; } } //插入具体的商品采购信息记录 if (zpquantity > 0)//如果有现反赠品则添加一条采购明细记录 { DataAccessor.InsertPurchasingDetail(Guid.NewGuid(), (tempPurchasingId == Guid.Empty ? purchasingId : tempPurchasingId), sale.GoodsId, p.GoodsName, p.Units, p.GoodsCode, sale.Specification, p.CompanyId, 0, zpquantity, 0, 0, string.Empty, sale.WeightedAverageSaleQuantity / 30, zpquantity, p.StockingDays + p.ArrivalDays, isException, salesinfo.SixtyDaySales, salesinfo.ThirtyDaySales, (salesinfo.ElevenDaySales / 11), (int)PurchasingGoodsType.Gift);//赠品 } DataAccessor.InsertPurchasingDetail(Guid.NewGuid(), purchasingId, sale.GoodsId, p.GoodsName, p.Units, p.GoodsCode, sale.Specification, p.CompanyId, p.Price, purchasingQuantity, 0, 0, string.Empty, sale.WeightedAverageSaleQuantity / 30, purchasingQuantity, p.StockingDays + p.ArrivalDays, isException, salesinfo.SixtyDaySales, salesinfo.ThirtyDaySales, (salesinfo.ElevenDaySales / 11), (int)PurchasingGoodsType.NoGift);//非赠品 hasChildGoodsPurchasingInfo = true; #if debug Console.WriteLine("新增采购单成功,单据ID:{0}", purchasingId); #endif } } } } //插入采购单记录 if (hasChildGoodsPurchasingInfo && tempPurchasingId == Guid.Empty) { if (step == 3) { nextPurchasingDate.AddDays(avgStockDays * 2); } DataAccessor.InsertPurchasing(purchasingId, purchasingNo, p.CompanyId, p.CompanyName, hostingFilialeId, warehouseId, hostingFilialeId, 0, 1, DateTime.Now, DateTime.Now, "[自动报备]", Guid.Empty, nextStockDate.AddDays(p.ArrivalDays), nextPurchasingDate, isException, p.PersonResponsible); } }