using System; using System.Collections.Generic; using System.Linq; using Gebhardt.StoreWare.Wcs.Common.Dao; using Gebhardt.StoreWare.Wcs.Common.DbAccess.Model; using Gebhardt.StoreWare.Wcs.Common.DbAccess.Model.Enums; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Internal; using static Gebhardt.StoreWare.Wcs.Common.Constants; namespace Gebhardt.StoreWare.Wcs.Common.DbAccess.Queries { public static class OrdersHostQueries { public static IQueryable ByStatus(this IQueryable entity, params TransportOrderStatus[] states) { return entity.Where(o => states.Contains(o.Status)); } public static IQueryable ByType(this IQueryable entity, params TransportOrderType[] types) { return entity.Where(o => types.Contains(o.Type)); } public static IQueryable ByLeNo(this IQueryable entity, string leNo) { return entity.Where(o => o.LeNo == leNo); } /// /// select entities with one of the given destinations /// /// public static IQueryable ByDestination(this IQueryable entity, IEnumerable destinations) { return entity.Where(o => destinations.Contains(o.Destination)); } /// /// select entities which hs not one of the given destinations /// /// public static IQueryable ExcludeDestination(this IQueryable entity, IEnumerable destinations) { return entity.Where(o => !destinations.Contains(o.Destination)); } /// /// select entities with the given destination /// /// public static IQueryable ByDestination(this IQueryable entity, string destination) { return entity.Where(o => destination == o.Destination); } /// /// searches for OH /// /// /// /// public static OrdersHost ActiveByLeNo(this IQueryable entity, string leNo) { return entity .ByLeNo(leNo) .SingleOrDefault(o => o.Status == TransportOrderStatus.InProgress || o.Status == TransportOrderStatus.InDestinationZone || o.Status == TransportOrderStatus.InSequencer); } public static IQueryable AllActiveByLeNo(this IQueryable entity, string leNo) { return entity .ByLeNo(leNo) .Where(o => o.Status == TransportOrderStatus.InProgress || o.Status == TransportOrderStatus.InDestinationZone || o.Status == TransportOrderStatus.InSequencer); } /// /// find - if exists open orders host entries (Status: Initial, InProgress, InDestinationZone, Pending) /// /// /// the le number /// null or an open orders host public static IQueryable OpenByLeNo(this IQueryable entity, string leNo) { return entity .Where(o => o.LeNo == leNo) .Open() //Better include this here in case one of the initial orders is started by that (done in many places) .ApplyWmsOrdering(); } /// /// find - open orders host entries (Status: Initial, InProgress, InDestinationZone, Pending) /// /// /// null or an open orders host public static IQueryable Open(this IQueryable entity) { return entity.Where(o => TransportOrderStatusGroups.Open.Contains(o.Status)); } public static IQueryable Active(this IQueryable entity) { return entity.Where(o => TransportOrderStatusGroups.Active.Contains(o.Status)); } public static IQueryable ActivePendingOrInSequecer(this IQueryable entity) { return entity.Where(o => TransportOrderStatusGroups.Active.Contains(o.Status) || o.Status == TransportOrderStatus.InSequencer || o.Status == TransportOrderStatus.Pending); } /// /// Get all destinations for which there are orders host existing in any state /// /// /// public static List GetAllDestinations(this IQueryable entity) { return entity.Select(oh => oh.Destination).Distinct().ToList(); } /// /// Get all destinations for which there are orders host existing in the given states /// /// /// public static List GetAllDestinations(this IQueryable entity, params TransportOrderStatus[] states) { return entity.Where(oh => states.Contains(oh.Status)).Select(oh => oh.Destination).Distinct().ToList(); } /// /// Get all destinations for the orders host (maybe precede by an "Open()"!) /// /// /// public static List GetAllDestinations(this IQueryable entity, IEnumerable destinations) { return entity.Where(oh => destinations.Contains(oh.Destination)).Select(oh => oh.Destination).Distinct().ToList(); } public static IQueryable GetCountByDate(this IQueryable entity, TransportOrderType orderType, IEnumerable dates) { return entity.Where(oh => oh.Status == TransportOrderStatus.Finished && oh.Created.Date > dates.First().Date && oh.Type == orderType).GroupBy(oh => oh.Created.Date).OrderBy(g => g.Key).Select(r => new OrderCountByDay(r.Count(), r.Key)); } public static IQueryable GetCountByDestination(this IQueryable entity) { // This SQL is translated into a Lambda expression DateTime today = DateTime.Now.Date; DateTime yesterday = today.AddDays(-1); return entity.Where(oh => oh.Status == TransportOrderStatus.Finished && oh.Created.Date >= yesterday && oh.Type == TransportOrderType.TransportHost).GroupBy(oh => oh.Destination).OrderBy(g => g.Key).Select(r => new OrderCountByDestination( r.Key, r.Sum(d => d.Created.Date == today ? 1 : 0), r.Sum(d => d.Created.Date == yesterday ? 1 : 0))); } public static IQueryable ExcludeNextEmpty(this IQueryable entity) { return entity.Where(o => o.LeNo != LeTypeName.NextEmptyMiniloadSmall.ToString() && o.LeNo != LeTypeName.NextEmptyMiniloadBig.ToString()); } public static IQueryable OnlyNextEmpty(this IQueryable entity) { return entity.Where(o => o.LeNo == LeTypeName.NextEmptyMiniloadSmall.ToString() || o.LeNo == LeTypeName.NextEmptyMiniloadBig.ToString()); } /// /// Special WMS ordering that takes the common Sequencer Retrieval Time into account /// /// /// /// public static IOrderedQueryable ApplyWmsOrderingSequencerRetrievalTime(this IQueryable entity, IWcsDbContext db) { var query = entity .GroupJoin( db.OrdersHost .GroupBy(xx => xx.IdOrderWmsHead) .Select(g => new { IdOrderWmsHead = g.Key, SequencerRetrievalTime = g.Min(y => y.SequencerRetrievalTime) }), o => o.IdOrderWmsHead, m => m.IdOrderWmsHead, (o, m) => new { o, m } ) .SelectMany(x => x.m.DefaultIfEmpty(), (x, m) => new { x.o, m }) .OrderByDescending(x => x.o.IsStolen) .ThenByDescending(x => x.o.IsDirectPicking) .ThenByDescending(x => x.m.SequencerRetrievalTime != null) .ThenBy(x => x.m.SequencerRetrievalTime) .ThenBy(x => x.o.Created) .Select(x => x.o); return (IOrderedQueryable) query; } public static IOrderedQueryable ApplyWmsOrdering(this IQueryable entity) { // Only order by Created, as WMS anyways only releases a limited number of orders. This saves us from running into dealocks. //Sequencer RetrievalTime is set when box is retrieved from sequencer. return entity .OrderByDescending(o => o.IsStolen) .ThenByDescending(o => o.IsDirectPicking) .ThenByDescending(o => o.SequencerRetrievalTime != null) .ThenBy(o => o.SequencerRetrievalTime) .ThenBy(o => o.Created); } /// /// Exclude all OHs where the LE is located in the sequencer, unless this order is a cancel order /// /// /// public static IQueryable ExcludeOrdersInSequencer(this IQueryable entity) { //The comented orders are started in Seq_Dispo return entity.Where(o => !(o.Le.Status == LeStatus.InStorage && o.Le.Aisle.Type == AisleType.Sequencer) /*|| (o.Source.Contains(WcsNames.SEQ) && o.Destination == MfcAllDestinations.StorageLoop2)*/); } /// /// Filter by sequenceorders that has been cancelled /// /// /// public static IQueryable ByCancelledSequencerOrder(this IQueryable entity) { return entity.Where(o => o.Source.Contains(WcsNames.SEQ) && o.Destination == MfcAllDestinations.StorageLoop2); } /// /// Filters by all orders that have been marked for departure by HostBooking (DepartureNotificationHandler) /// /// /// public static IQueryable IsDepartureReady(this IQueryable entity) { return entity.Where(o => o.DepartureLocation != null && o.DepartureFlag == true); } } }