private static void GetFulfillmentDates(Olma.Order supplyOrder, Olma.Order demandOrder, out DateTime supplyFulfillmentDate, out DateTime demandFulfillmentDate, bool canBeOnSameDay = false) { var supplyRange = new Tuple <DateTime, DateTime>(supplyOrder.EarliestFulfillmentDateTime.Date, supplyOrder.LatestFulfillmentDateTime.Date); var demandRange = new Tuple <DateTime, DateTime>(demandOrder.EarliestFulfillmentDateTime.Date, demandOrder.LatestFulfillmentDateTime.Date); if (!supplyRange.Item1.Intersects(supplyRange.Item2, demandRange.Item1, demandRange.Item2)) { throw new ArgumentException("Date Ranges to not inersect"); } var demandDate = demandRange.Item1; var supplyDate = demandDate.SubstractWorkDay().IsInRange(supplyRange.Item1, supplyRange.Item2) && !canBeOnSameDay ? demandDate.SubstractWorkDay() : demandDate; while (!( (demandDate != supplyDate || canBeOnSameDay) && !supplyDate.IsWeekend() && !demandDate.IsWeekend() && demandDate.IsInRange(demandRange.Item1, demandRange.Item2) && supplyDate.IsInRange(supplyRange.Item1, supplyRange.Item2) )) { demandDate = demandDate.AddWorkDay(); if (supplyDate.DayOfWeek != DayOfWeek.Friday || demandDate.DayOfWeek == DayOfWeek.Tuesday) { supplyDate = supplyDate.AddWorkDay(); } if (!canBeOnSameDay && supplyDate == demandDate) { demandDate = demandDate.AddWorkDay(); //Add another day if supply and demand are on same day } if (demandDate > demandRange.Item2) { throw new Exception("No Fulfillment Date found"); } } demandFulfillmentDate = demandDate; supplyFulfillmentDate = supplyDate; }
private OrderMatchQuantity CalculateOrderMatchQuantities(Olma.Order order, int stackHeight) { var quantities = new OrderMatchQuantity(); var loadcarrierIds = new[] { order.LoadCarrierId, order.BaseLoadCarrierId } .Where(i => i.HasValue) .Select(i => i.Value) .Distinct() .ToArray(); // TODO move call to load carriers into cached method var loadCarriersServiceResponse = (IWrappedResponse <IEnumerable <LoadCarrier> >)_loadCarriersService.GetAll().Result; var loadCarrierQuantityPerEurDict = loadCarriersServiceResponse.Data .Where(i => loadcarrierIds.Contains(i.Id)) .ToDictionary(i => i.Id, i => i.Type.QuantityPerEur); // TODO expand live pooling to provide base load carrier info //var hasBaseLoadCarrier = selfTransportOrderGroup.BaseLoadCarrierId != null || request.BaseLoadCarrierId != null; var hasBaseLoadCarrier = order.BaseLoadCarrierId != null; switch (order.QuantityType) { case OrderQuantityType.Load: { var quantityPerEurLoadCarrier = loadCarrierQuantityPerEurDict[order.LoadCarrierId]; var quantityPerEurBaseLoadCarrier = order.BaseLoadCarrierId.HasValue ? loadCarrierQuantityPerEurDict[order.BaseLoadCarrierId.Value] : 0; // TODO HACK, current assumes number of stacks = 33 both load/baseLoad carrier // instead this should be dependent on their types var numberOfStacks = 33; return(new OrderMatchQuantity() { LoadCarrierQuantity = numberOfStacks * quantityPerEurLoadCarrier * stackHeight, BaseLoadCarrierQuantity = hasBaseLoadCarrier ? 33 * quantityPerEurBaseLoadCarrier : 0, LoadCarrierStackHeight = stackHeight, NumberOfStacks = numberOfStacks }); } case OrderQuantityType.Stacks: { var numberOfStacks = order.NumberOfStacks.HasValue ? order.NumberOfStacks.Value : 0; var quantityPerEurLoadCarrier = loadCarrierQuantityPerEurDict[order.LoadCarrierId]; var quantityPerEurBaseLoadCarrier = order.BaseLoadCarrierId.HasValue ? loadCarrierQuantityPerEurDict[order.BaseLoadCarrierId.Value] : 0; return(new OrderMatchQuantity { LoadCarrierQuantity = numberOfStacks * quantityPerEurLoadCarrier * stackHeight, BaseLoadCarrierQuantity = hasBaseLoadCarrier ? numberOfStacks * quantityPerEurBaseLoadCarrier : 0, LoadCarrierStackHeight = stackHeight, NumberOfStacks = numberOfStacks }); } case OrderQuantityType.LoadCarrierQuantity: { var loadCarrierQuantity = order.LoadCarrierQuantity.Value; var quantityPerEurLoadCarrier = loadCarrierQuantityPerEurDict[order.LoadCarrierId]; int remainder; var numberOfStacks = Math.DivRem(loadCarrierQuantity, quantityPerEurLoadCarrier * stackHeight, out remainder) + (remainder > 0 ? 1 : 0); var quantityPerEurBaseLoadCarrier = order.BaseLoadCarrierId.HasValue ? loadCarrierQuantityPerEurDict[order.BaseLoadCarrierId.Value] : 0; var baseLoadCarrierQuantity = hasBaseLoadCarrier ? numberOfStacks * quantityPerEurBaseLoadCarrier : 0; return(new OrderMatchQuantity() { LoadCarrierQuantity = loadCarrierQuantity, BaseLoadCarrierQuantity = baseLoadCarrierQuantity, LoadCarrierStackHeight = loadCarrierQuantity < stackHeight ? loadCarrierQuantity : stackHeight, NumberOfStacks = numberOfStacks, }); } default: throw new ArgumentOutOfRangeException($"Unknown quantity type {order.QuantityType}"); } }
private async Task <IWrappedResponse> CreateAction(Rules.OrderGroup.Create.MainRule rule) { Olma.OrderGroup orderGroup = new Olma.OrderGroup() { Orders = new List <Olma.Order>() }; // create orders for order group switch (rule.Context.OrderGroupsCreateRequest.QuantityType) { case OrderQuantityType.Load: { for (var i = 0; i < rule.Context.OrderGroupsCreateRequest.NumberOfLoads; i++) { Olma.Order order = Mapper.Map <Olma.Order>(rule.Context.OrderGroupsCreateRequest); order.Status = OrderStatus.Pending; orderGroup.Orders.Add(order); } break; } case OrderQuantityType.LoadCarrierQuantity: { Olma.Order order = Mapper.Map <Olma.Order>(rule.Context.OrderGroupsCreateRequest); order.Status = OrderStatus.Pending; orderGroup.Orders.Add(order); break; } case OrderQuantityType.Stacks: { Olma.Order order = Mapper.Map <Olma.Order>(rule.Context.OrderGroupsCreateRequest); order.Status = OrderStatus.Pending; orderGroup.Orders.Add(order); break; } default: throw new ArgumentOutOfRangeException($"Unknown QuantityType: {rule.Context.OrderGroupsCreateRequest.QuantityType}"); } bool transactionRolledBack = false; IWrappedResponse <OrderMatch> orderMatchServiceResponse = null; _olmaDbContext.Database.CreateExecutionStrategy().Execute(operation: () => { using (_olmaDbContext.Database.BeginTransaction()) { _olmaOrderGroupRepo.Create(orderGroup); _olmaOrderGroupRepo.Save(); // this needs to happen after order is created in db as otherwise no orderGroupid exists if (rule.Context.OrderGroupsCreateRequest.MatchLmsOrderGroupRowGuid.HasValue) { var order = orderGroup.Orders.Single(); var orderMatchQuantity = this.CalculateOrderMatchQuantities(order, order.StackHeightMax); var orderMatchesCreateRequest = Mapper.Map <OrderMatchesCreateRequest>(order); orderMatchesCreateRequest = Mapper.Map(orderMatchQuantity, orderMatchesCreateRequest); if (rule.Context.OrderGroupsCreateRequest.Type == OrderType.Demand) { orderMatchesCreateRequest.SupplyOrderRowGuid = rule.Context.OrderGroupsCreateRequest.MatchLmsOrderGroupRowGuid.Value; orderMatchesCreateRequest.DemandOrderRowGuid = order.RefLmsOrderRowGuid; } else { orderMatchesCreateRequest.DemandOrderRowGuid = rule.Context.OrderGroupsCreateRequest.MatchLmsOrderGroupRowGuid.Value; orderMatchesCreateRequest.SupplyOrderRowGuid = order.RefLmsOrderRowGuid; } orderMatchServiceResponse = (IWrappedResponse <OrderMatch>)_orderMatchesService.Create(orderMatchesCreateRequest).Result; if (orderMatchServiceResponse.ResultType != ResultType.Created) { _olmaDbContext.Database.RollbackTransaction(); transactionRolledBack = true; } else { _olmaDbContext.Database.CommitTransaction(); } } else { _olmaDbContext.Database.CommitTransaction(); } } }); if (transactionRolledBack) { return(orderMatchServiceResponse); } var orders = _olmaDbContext.Orders.Where(i => i.GroupId == orderGroup.Id) .Include(og => og.LoadingLocation).ThenInclude(loc => loc.Address) .Include(og => og.LoadingLocation.BusinessHours) .Include(og => og.LoadingLocation.CustomerDivision).ThenInclude(cd => cd.Customer) .Include(og => og.CreatedBy).ThenInclude(u => u.Person) .Include(og => og.LoadCarrier) .Include(og => og.BaseLoadCarrier) .Include(og => og.PostingAccount).ThenInclude(pa => pa.CustomerDivisions) .ThenInclude(cd => cd.Customer); DateTime syncDate = DateTime.UtcNow; foreach (var order in orders) { order.OrderNumber = await _numberSequencesService.GetProcessNumber(ProcessType.Order, order.Id); var orderCreateSyncRequest = Mapper.Map <Olma.Order, OrderCreateSyncRequest>(order); if (orderMatchServiceResponse != null) { switch (order.Type) { case OrderType.Demand: orderCreateSyncRequest.RefLmsAvailabilityRowGuid = orderMatchServiceResponse.Data.RefLmsAvailabilityRowGuid; orderCreateSyncRequest.RefLmsPermanentAvailabilityRowGuid = orderMatchServiceResponse.Data.RefLmsPermanentAvailabilityRowGuid; break; case OrderType.Supply: orderCreateSyncRequest.RefLmsDeliveryRowGuid = orderMatchServiceResponse.Data.RefLmsDeliveryRowGuid; orderCreateSyncRequest.RefLmsPermanentDeliveryRowGuid = orderMatchServiceResponse.Data.RefLmsPermanentDeliveryRowGuid; break; } orderCreateSyncRequest.DigitalCode = orderMatchServiceResponse.Data.DigitalCode; orderCreateSyncRequest.LoadCarrierQuantity = orderMatchServiceResponse.Data.LoadCarrierQuantity; orderCreateSyncRequest.BaseLoadCarrierQuantity = orderMatchServiceResponse.Data.BaseLoadCarrierQuantity; } var ordersSyncRequest = new OrdersSyncRequest { OrderCreateSyncRequests = new List <OrderCreateSyncRequest> { orderCreateSyncRequest } }; var syncResult = await _synchronizationsService.SendOrdersAsync(ordersSyncRequest); if (syncResult.ResultType == ResultType.Ok) { order.SyncDate ??= syncDate; } } _olmaDbContext.SaveChanges(); var result = Mapper.Map <Olma.OrderGroup, OrderGroup>(orderGroup); return(new WrappedResponse <OrderGroup> { ResultType = ResultType.Created, Data = result }); }
public static bool CheckUpdatedProperties(this OrderGroupsUpdateRequest request, Olma.Order order) { if (order.LoadCarrierId != request.LoadCarrierId || order.LoadingLocationId != request.LoadingLocationId || order.LatestFulfillmentDateTime != request.LatestFulfillmentDateTime || order.EarliestFulfillmentDateTime != request.EarliestFulfillmentDateTime || order.BaseLoadCarrierId != request.BaseLoadCarrierId || order.QuantityType != request.QuantityType || order.StackHeightMax != request.StackHeightMax || order.StackHeightMin != request.StackHeightMin || order.SupportsJumboVehicles != request.SupportsJumboVehicles || order.SupportsRearLoading != request.SupportsRearLoading || order.SupportsSideLoading != request.SupportsSideLoading) { return(true); } return(false); }