Beispiel #1
0
        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
            });
        }
Beispiel #4
0
 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);
 }