You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

174 lines
6.8 KiB

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<List<PlanAndActualDashboardDto>> GetPlanAndActualListAsync()
{
return await GetPlanAndActualDashboardsAsync().ConfigureAwait(false);
}
private async Task<List<PlanAndActualDashboardDto>> 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<PlanAndActualDashboardDto> ConvertToPlanAndActualDashboards(List<SupplierAsnDTO> supplierAsns, List<SupplierDTO> suppliers, List<PurchaseReceiptNoteDTO> purchaseReceiptNotes, List<PutawayNoteDTO> putawayNotes, List<ItemSafetyStockDTO> itemSafetyStorks)
{
var dtos = new List<PlanAndActualDashboardDto>();
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<PutawayNoteDTO> 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<PurchaseReceiptNoteDTO> 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<PurchaseReceiptNoteDTO> purchaseReceipts, string itemCode, string lot)
{
return purchaseReceipts.Sum(t => t.Details.Count(t => t.ItemCode == itemCode && t.Lot == lot));
}
private async Task<List<SupplierAsnDTO>> 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<List<SupplierDTO>> GetSuppliersAsync(IEnumerable<string> codes)
{
return await _supplierApp.GetByCodesAsync(codes).ConfigureAwait(false);
}
private async Task<List<PurchaseReceiptNoteDTO>> GetPurchaseReceiptNotesAsync(IEnumerable<string> asnNumbers)
{
return await _purchaseReceiptNoteApp.GetListByAsnNumbers(asnNumbers).ConfigureAwait(false);
}
private async Task<List<PutawayNoteDTO>> GetPutawayNotesAsync(IEnumerable<string> asnNumbers)
{
return await _putawayNoteApp.GetListByAsnNumbers(asnNumbers).ConfigureAwait(false);
}
private async Task<List<ItemSafetyStockDTO>> GetItemSafetyStocksAsync(List<SupplierAsnDTO> supplierAsns)
{
var itemCodes = new List<string>();
supplierAsns.ForEach(t => { itemCodes.AddRange(t.Details.Select(t => t.ItemCode).ToList()); });
var itemSafetyStorks = await _itemSafetyStockApp.GetByItemCodesAsync(itemCodes).ConfigureAwait(false);
return itemSafetyStorks;
}
}