111 lines
5.3 KiB
C#
111 lines
5.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Gebhardt.Shared;
|
|
using Gebhardt.StoreWare.Wcs.Common.Application.LeHandling.Interfaces;
|
|
using Gebhardt.StoreWare.Wcs.Common.Application.LoopStrategy;
|
|
using Gebhardt.StoreWare.Wcs.Common.Application.StorageStrategies.Interfaces;
|
|
using Gebhardt.StoreWare.Wcs.Common.Application.TransportHandling.Interfaces;
|
|
using Gebhardt.StoreWare.Wcs.Common.DbAccess;
|
|
using Gebhardt.StoreWare.Wcs.Common.DbAccess.Model;
|
|
using Gebhardt.StoreWare.Wcs.Common.DbAccess.Model.Enums;
|
|
using Gebhardt.StoreWare.Wcs.Common.DbAccess.Queries;
|
|
using Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms.Interfaces;
|
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Interfaces;
|
|
using static Gebhardt.StoreWare.Wcs.Common.Constants;
|
|
|
|
namespace Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms.MessageImplementation
|
|
{
|
|
public class AcknowledgeTransportCompletedHandler : IHandleRecord<IAcknowledgeTransportCompleted>
|
|
{
|
|
private readonly IWcsDbContextFactory _dbContextFactory;
|
|
private readonly ITransportOrderService _transportOrderService;
|
|
private readonly ILeService _leService;
|
|
private readonly IDestinationService _destinationService;
|
|
private readonly ILoopSelectionService _loopSelectionService;
|
|
|
|
public AcknowledgeTransportCompletedHandler(IWcsDbContextFactory dbContextFactory, ITransportOrderService transportOrderService, ILeService leService, IDestinationService destinationService, ILoopSelectionService loopSelectionService)
|
|
{
|
|
_dbContextFactory = dbContextFactory;
|
|
_transportOrderService = transportOrderService;
|
|
_destinationService = destinationService;
|
|
_leService = leService;
|
|
_loopSelectionService = loopSelectionService;
|
|
}
|
|
|
|
public bool Handle(IAcknowledgeTransportCompleted message)
|
|
{
|
|
using (IWcsDbContext db = _dbContextFactory.GetDbContext())
|
|
{
|
|
List<int> ordersHostIds = db.OrdersHost.Where(o => o.IdOrderWms == message.IdOrderWms).Select(o => o.Id).ToList();
|
|
|
|
if (ordersHostIds.Any())
|
|
{
|
|
if (ordersHostIds.Count() > 1)
|
|
{
|
|
throw new InvalidOperationException($"Multiple OrdersHost found for same WMS id {message.IdOrderWms}");
|
|
}
|
|
|
|
_transportOrderService.FinishOrdersHost(ordersHostIds.Single(), "AcknowledgeTransportCompleted");
|
|
Log.Write(LogLevel.Info, $"{nameof(OrdersHost)} with Id {ordersHostIds.Single()} and WMS id {message.IdOrderWms} finished.");
|
|
|
|
//Other open OH for HU that must be cancelled?
|
|
List<OrdersHost> others = db.OrdersHost
|
|
.OpenByLeNo(message.LeNo).Where(oh => oh.Type == TransportOrderType.Transport).ToList();
|
|
foreach (var other in others)
|
|
{
|
|
_transportOrderService.CancelOrdersHost(other.Id, $"New destination {message.Destination}", $"OrderHost {ordersHostIds.Single()} was finished");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Log.Write(LogLevel.Error, $"{nameof(AcknowledgeTransportCompletedHandler)}: Cannot find OH for WMS id {message.IdOrderWms}");
|
|
}
|
|
|
|
db.SaveChanges();
|
|
}
|
|
|
|
// New DB Context since OrdersConveyorService changes data that we otherwise wouldn't notice
|
|
using (IWcsDbContext db = _dbContextFactory.GetDbContext())
|
|
{
|
|
// le empty?
|
|
Le le = db.Le.ByLeNo(message.LeNo);
|
|
// If there is no other order for this le, send it back to the storage
|
|
if (!db.OrdersHost.OpenByLeNo(message.LeNo).Any() && le != null)
|
|
{
|
|
DestinationProperty workStation = db.DestinationProperty.FirstOrDefault(d => d.Name == message.Destination && d.Property == nameof(IDestinationProperties.Level));
|
|
var workStationDest = _destinationService.Get(message.Destination);
|
|
|
|
List<VLoopOverview> availableLoops = _loopSelectionService.GetSuitableStorageLoops(message.LeNo);
|
|
|
|
// Choose a desired destination based on which is the closest to the workstation
|
|
string destination = MfcAllDestinations.StorageLoop2;
|
|
if (workStationDest != null)
|
|
{
|
|
destination = workStationDest.StorageArea == MfcAllDestinations.AKL02 ? MfcAllDestinationsOldSystem.LOOP3 : workStationDest.Level == ConveyorLevel.EtraBox.ToString() ? MfcAllDestinations.StorageLoop1 : MfcAllDestinations.StorageLoop2;
|
|
|
|
// If only one of the loops is available, choose this, no matter where the LE is located
|
|
if (availableLoops.Count == 1)
|
|
{
|
|
destination = availableLoops.First().PlcName;
|
|
}
|
|
else
|
|
{
|
|
// Prefer the destination closest connected to the pick station but select the other if this is full
|
|
string fallbackDestination = workStationDest.StorageArea == MfcAllDestinations.AKL02 ? MfcAllDestinationsOldSystem.LOOP3 : workStationDest.Level == ConveyorLevel.EtraBox.ToString() ? MfcAllDestinations.StorageLoop1 : MfcAllDestinations.StorageLoop2;
|
|
if (!_loopSelectionService.hasEnoughSpace(destination) && _loopSelectionService.hasEnoughSpace(fallbackDestination))
|
|
{
|
|
destination = fallbackDestination;
|
|
}
|
|
}
|
|
}
|
|
string source = message.Destination == MfcAllDestinationsOldSystem.TOPUP ? MfcAllDestinationsOldSystem.TOPUP : message.Source ?? "?";
|
|
int ordersHostId = _leService.CreateTransport(message.LeNo, source, destination);
|
|
Log.Write(LogLevel.Info, $"Loop selection in acknowledge transport handler for {le.LeNo}, set to {destination}");
|
|
LoopStrategy.ReserveForLoop(le.LeNo, ordersHostId, availableLoops.FirstOrDefault(l => l.PlcName == destination)?.Name);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
} |