public async Task <IWrappedResponse> SendOrdersAsync(OrdersSyncRequest request)
        {
            try
            {
                _queueClient = new QueueClient(_syncServiceBusConnectionString, _orderSyncRequestQueueName,
                                               retryPolicy: RetryPolicy.Default);

                var messages = new List <Message>();

                messages.AddRange(request.OrderCreateSyncRequests.AsMessages());
                messages.AddRange(request.OrderCancelSyncRequests.AsMessages());
                messages.AddRange(request.OrderFulfillSyncRequests.AsMessages());
                messages.AddRange(request.OrderRollbackFulfillmentSyncRequests.AsMessages());


                await _queueClient.SendAsync(messages);

                return(new WrappedResponse
                {
                    ResultType = ResultType.Ok
                });
            }
            catch (Exception exception)
            {
                ErrorHandler.Create()
                .LogException(new SynchronizationException("Send orders failed.", exception), request);
                return(new WrappedResponse
                {
                    ResultType = ResultType.Failed
                });
            }
        }
Example #2
0
        private async Task CheckOrdersSyncDate(CancellationToken stoppingToken)
        {
            using var scope = Services.CreateScope();

            var olmaOrderRepo =
                scope.ServiceProvider.GetRequiredService <IRepository <Olma.Order> >();

            var orders = olmaOrderRepo.FindByCondition(o =>
                                                       //Order created but not synchronized
                                                       (!o.IsDeleted && !o.SyncDate.HasValue)
                                                       //Order canceled but not synchronized
                                                       || (!o.IsDeleted && o.SyncDate.HasValue && o.ChangedAt.HasValue && o.ChangedAt > o.SyncDate &&
                                                           o.Status == OrderStatus.CancellationRequested))
                         .Include(og => og.LoadingLocation).ThenInclude(loc => loc.Address)
                         .Include(og => og.CreatedBy).ThenInclude(u => u.Person)
                         .Include(og => og.ChangedBy).ThenInclude(u => u.Person)
                         .Include(og => og.DeletedBy).ThenInclude(u => u.Person)
                         .Include(og => og.LoadCarrier).Include(og => og.BaseLoadCarrier)
                         .Include(og => og.PostingAccount).ThenInclude(pa => pa.CustomerDivisions).ThenInclude(cd => cd.Customer)
                         .IgnoreQueryFilters().ToList();

            var mapper = scope.ServiceProvider.GetRequiredService <IMapper>();
            var synchronizationsService =
                scope.ServiceProvider.GetRequiredService <ISynchronizationsService>();

            foreach (var order in orders)
            {
                var ordersSyncRequest = new OrdersSyncRequest
                {
                    OrderCreateSyncRequests = new List <OrderCreateSyncRequest>(),
                    OrderCancelSyncRequests = new List <OrderCancelSyncRequest>()
                };

                if (!order.IsDeleted && !order.SyncDate.HasValue)
                {
                    ordersSyncRequest.OrderCreateSyncRequests.Add(
                        mapper.Map <OrderCreateSyncRequest>(order));
                }

                if (!order.IsDeleted && order.SyncDate.HasValue && order.ChangedAt.HasValue &&
                    order.ChangedAt > order.SyncDate && order.Status == OrderStatus.CancellationRequested)
                {
                    ordersSyncRequest.OrderCreateSyncRequests.Add(
                        mapper.Map <Olma.Order, OrderCreateSyncRequest>(order));
                }

                var syncResult = await synchronizationsService.SendOrdersAsync(ordersSyncRequest);

                if (syncResult.ResultType == ResultType.Ok)
                {
                    order.SyncDate = DateTime.UtcNow;
                    olmaOrderRepo.Update(order);
                    olmaOrderRepo.Save();
                }
            }

            await Task.Delay(30000, stoppingToken);
        }
Example #3
0
        private async Task <IWrappedResponse> CancelAction(Rules.Order.Cancel.MainRule rule)
        {
            var order   = rule.Context.Rules.OrderResourceRule.Context.Resource;
            var request = rule.Context.Request;

            if (IsDplEmployee)
            {
                var dplNote = Mapper.Map <Olma.EmployeeNote>(request.DplNote);
                order.DplNotes.Add(dplNote);

                order.Status = OrderStatus.Cancelled;
            }
            else
            {
                order.Status = OrderStatus.CancellationRequested;
            }

            _olmaOrderRepo.Save();

            var orderCancelSyncRequest = Mapper.Map <Olma.Order, OrderCancelSyncRequest>(order);

            orderCancelSyncRequest.IsApproved = IsDplEmployee;
            // TODO generate string from all emplyoeenote fields
            orderCancelSyncRequest.Note = IsDplEmployee ? request.DplNote.Text : request.Note;
            var ordersSyncRequest = new OrdersSyncRequest
            {
                OrderCancelSyncRequests = new List <OrderCancelSyncRequest>
                {
                    orderCancelSyncRequest
                }
            };
            var syncResult = await _synchronizationsService.SendOrdersAsync(ordersSyncRequest);

            if (syncResult.ResultType == ResultType.Ok)
            {
                order.SyncDate = DateTime.UtcNow;
            }

            _olmaOrderRepo.Save();

            var responseOrder = Mapper.Map <Order>(order);

            return(Updated(responseOrder));
        }
        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
            });
        }
        /// <summary>
        /// Erzeugt eine Quittungen. Diese Action hat abhängigkeiten zum NumberSequencesService und zum PostingRequestsService.
        /// </summary>
        /// <param name="mainRule"></param>
        /// <returns></returns>
        private async Task <IWrappedResponse> CreateAction(Rules.LoadCarrierReceipts.Create.MainRule mainRule)
        {
            var request                = mainRule.Context.Parent;
            var printLanguageId        = request.PrintLanguageId;
            var loadCarrierReceipt     = mainRule.Context.LoadCarrierReceipt;
            var customerDivision       = mainRule.Context.CustomerDivision;
            var isSupply               = mainRule.Context.IsSupply;
            var targetRefLtmsAccountId = mainRule.Context.TargetRefLtmsAccountId;
            var orderLoad              = mainRule.Context.OrderLoad;
            var refLtmsTransactionId   = mainRule.Context.RefLtmsTransactionId;
            var isSelfService          = mainRule.Context.IsSelfService;
            var documentType           = mainRule.Context.DocumentType;
            var lmsAvail2deli          = mainRule.Context.LmsAvail2deli;

            var documentNumber = _numberSequencesService
                                 .GetDocumentNumber(documentType, request.CustomerDivisionId).Result;

            mainRule.Context.LoadCarrierReceipt.Document.Number = documentNumber;

            var strategy = _olmaDbContext.Database.CreateExecutionStrategy();
            var result   = await strategy.ExecuteAsync(async() =>
            {
                await using var ctxTransaction = await _olmaDbContext.Database.BeginTransactionAsync();
                var strategyResult             = _olmaLoadCarrierReceiptRepo
                                                 .Create <Olma.LoadCarrierReceipt, Olma.LoadCarrierReceipt, LoadCarrierReceipt>(
                    loadCarrierReceipt);
                var reportGeneratorServiceResponse =
                    (IWrappedResponse <Report>)_reportGeneratorService.GenerateReportForLanguage(
                        strategyResult.Data.DocumentId, printLanguageId, request.PrintCount - 1,
                        request.PrintDateTimeOffset);

                var downloadLink = (IWrappedResponse <string>) await _documentsService
                                   .GetDocumentDownload(strategyResult.Data.DocumentId, DocumentFileType.Composite);

                if (downloadLink.ResultType != ResultType.Ok)
                {
                    await ctxTransaction.RollbackAsync();
                    return(new WrappedResponse <LoadCarrierReceipt>
                    {
                        ResultType = ResultType.Failed,
                        State = ErrorHandler.Create().AddMessage(new DocumentLinkError()).GetServiceState()
                    });
                }
                strategyResult.Data.DownloadLink = downloadLink.Data;

                var postingRequestsCreateRequest = new PostingRequestsCreateRequest
                {
                    Type = isSupply
                        ? PostingRequestType.Credit
                        : PostingRequestType
                           .Charge,  //HACK Only to fix UI, from LTMS WebApp viewpoint  it would be a charge
                    ReferenceNumber      = loadCarrierReceipt.Document?.Number,
                    Reason               = PostingRequestReason.LoadCarrierReceipt,
                    LoadCarrierReceiptId = strategyResult.Data.Id,
                    IsSortingRequired    = strategyResult.Data.IsSortingRequired,
                    DocumentFileName     = reportGeneratorServiceResponse.Data.DocumentArchiveName,
                    IsSelfService        = isSelfService,
                    Positions            = loadCarrierReceipt.Positions.Select(lcr =>
                                                                               new PostingRequestPosition
                    {
                        LoadCarrierId       = lcr.LoadCarrierId,
                        LoadCarrierQuantity = lcr.LoadCarrierQuantity
                    }),
                    RefLtmsProcessId     = Guid.NewGuid(),
                    RefLtmsTransactionId = refLtmsTransactionId ?? Guid.NewGuid(),
                    PostingAccountId     = customerDivision.PostingAccountId.Value,
                    RefLtmsProcessTypeId =
                        isSupply ? (int)RefLtmsProcessType.Excemption : (int)RefLtmsProcessType.DepotAcceptance,
                    SourceRefLtmsAccountId =
                        isSupply ? customerDivision.PostingAccount.RefLtmsAccountId : targetRefLtmsAccountId,
                    DestinationRefLtmsAccountId = !isSupply
                        ? customerDivision.PostingAccount.RefLtmsAccountId
                        : targetRefLtmsAccountId,
                    DigitalCode               = loadCarrierReceipt.DigitalCode,
                    RefLmsBusinessTypeId      = request.RefLmsBusinessTypeId,
                    RefLtmsTransactionRowGuid = request.RefLtmsTransactionRowGuid,
                    DeliveryNoteNumber        = loadCarrierReceipt.DeliveryNoteNumber,
                    PickUpNoteNumber          = loadCarrierReceipt.PickUpNoteNumber
                };

                var postingRequestsServiceResponse =
                    (IWrappedResponse <IEnumerable <PostingRequest> >) await _postingRequestsService
                    .Create(postingRequestsCreateRequest);
                if (postingRequestsServiceResponse.ResultType != ResultType.Created)
                {
                    await ctxTransaction.RollbackAsync();
                    return(new WrappedResponse <LoadCarrierReceipt>
                    {
                        ResultType = postingRequestsServiceResponse.ResultType,
                        State = postingRequestsServiceResponse.State
                    });
                }

                if (lmsAvail2deli != null)
                {
                    var orderFulfillSyncRequest = new OrderFulfillSyncRequest
                    {
                        DigitalCode               = loadCarrierReceipt.DigitalCode,
                        FulfillmentDateTime       = DateTime.UtcNow,
                        RefLmsDeliveryRowGuid     = lmsAvail2deli.Delivery.RowGuid,
                        RefLmsAvailabilityRowGuid = lmsAvail2deli.Availability.RowGuid
                    };

                    var ordersSyncRequest = new OrdersSyncRequest
                    {
                        OrderFulfillSyncRequests = new List <OrderFulfillSyncRequest>
                        {
                            orderFulfillSyncRequest
                        }
                    };

                    //Reine Sync-Fehler für Updates werden geloggt und müssen manuell behoben werden.
                    await _synchronizationsService.SendOrdersAsync(ordersSyncRequest);
                }
                await ctxTransaction.CommitAsync();
                return(strategyResult);
            });

            return(result);
        }
Example #6
0
        public async Task <IWrappedResponse> Cancel(int id, OrderLoadCancelRequest request)
        {
            #region security

            // TODO add security

            #endregion

            var orderLoad = _olmaOrderLoadRepo.FindByCondition(o => o.Id == id)
                            .Include(i => i.Detail)
                            .Include(i => i.DplNotes)
                            .Include(o => o.Order)
                            .Include(o => o.CreatedBy)
                            .FirstOrDefault();

            if (orderLoad == null)
            {
                return(NotFound <OrderLoad>(id));
            }

            var cancellableStates = new[] { OrderLoadStatus.Pending, OrderLoadStatus.TransportPlanned };
            if (IsDplEmployee)
            {
                cancellableStates = cancellableStates.Append(OrderLoadStatus.CancellationRequested).ToArray();
            }

            if (!cancellableStates.Contains(orderLoad.Detail.Status))
            {
                return(BadRequest <OrderLoad>("OrderLoad is in a state that cannot be cancelled"));
            }

            var status = IsDplEmployee ? OrderLoadStatus.Canceled : OrderLoadStatus.CancellationRequested;
            orderLoad.Detail.Status = status;
            if (IsDplEmployee)
            {
                var dplNote = Mapper.Map <Olma.EmployeeNote>(request.DplNote);
                orderLoad.DplNotes.Add(dplNote);
            }

            _olmaOrderLoadRepo.Save();

            var orderCancelSyncRequest = Mapper.Map <Olma.OrderLoad, OrderCancelSyncRequest>(orderLoad);
            orderCancelSyncRequest.Note = IsDplEmployee ? request.DplNote.Text : request.Note;
            var ordersSyncRequest = new OrdersSyncRequest
            {
                OrderCancelSyncRequests = new List <OrderCancelSyncRequest>
                {
                    orderCancelSyncRequest
                }
            };
            var syncResult = await _synchronizationsService.SendOrdersAsync(ordersSyncRequest);

            if (syncResult.ResultType == ResultType.Ok)
            {
                orderLoad.Order.SyncDate = DateTime.UtcNow;
            }
            _olmaOrderLoadRepo.Save();

            var responseOrderLoad = Mapper.Map <OrderLoad>(orderLoad);
            return(Updated(responseOrderLoad));
        }