using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Serilog; using Volo.Abp.AspNetCore.Mvc; using Win_in.Sfs.Basedata.Application.Contracts; using Win_in.Sfs.Wms.Dashboard.Host.Models; using Win_in.Sfs.Wms.Store.Application.Contracts; namespace Win_in.Sfs.Wms.Dashboard.Host.Controllers; [ApiController] [Route($"{PdaHostConst.ROOT_ROUTE}plan-and-actual")] public class PlanAndActualController : AbpController { private readonly ISupplierAsnAppService _supplierAsnApp; private readonly IPurchaseReceiptNoteAppService _purchaseReceiptNoteApp; private readonly IPutawayNoteAppService _putawayNoteApp; private readonly ISupplierAppService _supplierApp; private readonly IItemSafetyStockAppService _itemSafetyStockApp; public PlanAndActualController(ISupplierAsnAppService supplierAsnApp, IPurchaseReceiptNoteAppService purchaseReceiptNoteApp, IPutawayNoteAppService putawayNoteApp, ISupplierAppService supplierApp, IItemSafetyStockAppService itemSafetyStockApp) { _supplierAsnApp = supplierAsnApp; _purchaseReceiptNoteApp = purchaseReceiptNoteApp; _putawayNoteApp = putawayNoteApp; _supplierApp = supplierApp; _itemSafetyStockApp = itemSafetyStockApp; } [HttpGet("plan-actual-list")] public virtual async Task> GetPlanAndActualListAsync() { return await GetPlanAndActualDashboardsAsync().ConfigureAwait(false); } private async Task> GetPlanAndActualDashboardsAsync() { var supplierAsns = await GetSupplierAsnsAsync().ConfigureAwait(false); var supplierCodes = supplierAsns.Select(t => t.SupplierCode).Distinct(); var suppliers = await GetSuppliersAsync(supplierCodes).ConfigureAwait(false); var asnNumbers = supplierAsns.Select(t => t.Number); var purchaseReceiptNotes = await GetPurchaseReceiptNotesAsync(asnNumbers).ConfigureAwait(false); var putawayNotes = await GetPutawayNotesAsync(asnNumbers).ConfigureAwait(false); var itemSafetyStorks = await GetItemSafetyStocksAsync(supplierAsns).ConfigureAwait(false); return ConvertToPlanAndActualDashboards( supplierAsns, suppliers, purchaseReceiptNotes, putawayNotes, itemSafetyStorks); } private static List ConvertToPlanAndActualDashboards(List supplierAsns, List suppliers, List purchaseReceiptNotes, List putawayNotes, List itemSafetyStorks) { var dtos = new List(); foreach (var supplierAsn in supplierAsns) { var purchaseReceipts = purchaseReceiptNotes.FindAll(t => t.AsnNumber == supplierAsn.Number); var putaways = putawayNotes.FindAll(t => t.AsnNumber == supplierAsn.Number); var supplierShortName = string.Empty; var supplier = suppliers.FirstOrDefault(t => t.Code == supplierAsn.SupplierCode); if (supplier == null) { continue; } supplierShortName = supplier.ShortName; foreach (var detail in supplierAsn.Details) { var dto = dtos.FirstOrDefault(t => t.SupplierShortName == supplierShortName && t.ItemCode == detail.ItemCode); if (dto == null) { dto = new PlanAndActualDashboardDto(); dto.SupplierShortName = supplierShortName; dto.ItemCode = detail.ItemCode; dto.ItemDesc1 = detail.ItemDesc1; dto.ItemName = detail.ItemName; var itemSafetyStork = itemSafetyStorks.FirstOrDefault(t => t.ItemCode == detail.ItemCode); if (itemSafetyStork != null) { dto.MaxQty = itemSafetyStork.MaxStock; dto.MinQty = itemSafetyStork.MinStock; } dto.ReceiptNoteCount = CountReceiptNoteCount(purchaseReceipts, detail.ItemCode, detail.Lot); dto.ReceiptQty = CountReceiptQty(purchaseReceipts, detail.ItemCode, detail.Lot); dto.PutawayQty = CountPutawayQty(putawayNotes, detail.ItemCode, detail.Lot); dtos.Add(dto); } dto.SupplierAsnCount += 1; dto.PlanArriveQty += detail.Qty; } } return dtos.OrderBy(t => t.SupplierShortName).ToList(); } private static decimal CountPutawayQty(List putawayNotes, string itemCode, string lot) { return putawayNotes.Sum(t => t.Details.Where(t => t.ItemCode == itemCode && t.ToLot == lot).Sum(t => t.Qty)); } private static decimal CountReceiptQty(List purchaseReceipts, string itemCode, string lot) { return purchaseReceipts.Sum(t => t.Details.Where(t => t.ItemCode == itemCode && t.HandledLot == lot).Sum(t => t.Qty)); } private static int CountReceiptNoteCount(List purchaseReceipts, string itemCode, string lot) { return purchaseReceipts.Sum(t => t.Details.Count(t => t.ItemCode == itemCode && t.Lot == lot)); } private async Task> GetSupplierAsnsAsync() { var startTime = DateTime.Today.AddHours(DashboardConst.AsnReceiptTimeLimitHour); var endTime = startTime.AddDays(1).AddSeconds(-1); if (DateTime.Now.Hour < DashboardConst.AsnReceiptTimeLimitHour) { startTime.AddDays(-1); endTime.AddDays(-1); } return await _supplierAsnApp.GetByStartTimeEndTimeAsync(startTime, endTime).ConfigureAwait(false); } private async Task> GetSuppliersAsync(IEnumerable codes) { return await _supplierApp.GetByCodesAsync(codes).ConfigureAwait(false); } private async Task> GetPurchaseReceiptNotesAsync(IEnumerable asnNumbers) { return await _purchaseReceiptNoteApp.GetListByAsnNumbers(asnNumbers).ConfigureAwait(false); } private async Task> GetPutawayNotesAsync(IEnumerable asnNumbers) { return await _putawayNoteApp.GetListByAsnNumbers(asnNumbers).ConfigureAwait(false); } private async Task> GetItemSafetyStocksAsync(List supplierAsns) { var itemCodes = new List(); supplierAsns.ForEach(t => { itemCodes.AddRange(t.Details.Select(t => t.ItemCode).ToList()); }); var itemSafetyStorks = await _itemSafetyStockApp.GetByItemCodesAsync(itemCodes).ConfigureAwait(false); return itemSafetyStorks; } }