public async Task <Order> CreateOrderForRegistrationAsync(
            Registration registration,
            OrderItemDto[] data,
            CancellationToken cancellationToken)
        {
            await _registrationAccessControlService
            .CheckRegistrationUpdateAccessAsync(registration, cancellationToken);

            data ??= Array.Empty <OrderItemDto>();

            var productIds = data.Select(o => o.ProductId).ToArray();
            var variantIds = data.Select(o => o.VariantId).ToArray();

            var productMap = await _context.Products
                             .Where(p => productIds.Contains(p.ProductId))
                             .ToDictionaryAsync(p => p.ProductId, cancellationToken);

            var variantMap = await _context.ProductVariants
                             .Where(v => variantIds.Contains(v.ProductVariantId))
                             .ToDictionaryAsync(v => v.ProductVariantId, cancellationToken);

            var lines = data.Select(o => new OrderDTO
            {
                Product  = productMap[o.ProductId],
                Variant  = o.VariantId.HasValue ? variantMap[o.VariantId.Value] : null,
                Quantity = o.Quantity
            });

            var order = registration.CreateOrder(lines);
            await _registrationManagementService.UpdateRegistrationAsync(registration, cancellationToken);

            return(order);
        }
Exemplo n.º 2
0
        public async Task <IActionResult> CreateOrUpdateOrder([FromBody] NewOrderRequestDto request)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState.FormatErrors()));
            }

            try
            {
                var registration = await _registrationRetrievalService
                                   .GetRegistrationByIdAsync(request.RegistrationId);

                await _registrationAccessControlService
                .CheckRegistrationUpdateAccessAsync(registration);

                // FIXME: calling obsolete API here
                // the obsolete API is hard to maintain, and is not covered with tests...
                // TODO: get into the legacy logic maybe and refactor it!
                var order = await _registrationService.CreateOrUpdateOrder(
                    request.RegistrationId,
                    request.Lines.Select(l => new OrderVM
                {
                    ProductId = l.ProductId,
                    VariantId = l.ProductVariantId,
                    Quantity = l.Quantity
                }).ToList());

                return(Ok(new OrderDto(order)));
            }
            catch (OrderUpdateException e)
            {
                return(BadRequest(e.Message));
            }
        }
Exemplo n.º 3
0
        public async Task CheckOrderUpdateAccessAsync(Order order, CancellationToken cancellationToken = default)
        {
            if (order == null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            var registration = await GetOrderRegistrationAsync(order, cancellationToken);

            await _registrationAccessControlService
            .CheckRegistrationUpdateAccessAsync(registration, cancellationToken);
        }
        public async Task UpdateRegistrationAsync(
            Registration registration,
            CancellationToken cancellationToken)
        {
            if (registration == null)
            {
                throw new ArgumentNullException(nameof(registration));
            }

            await _registrationAccessControlService.CheckRegistrationUpdateAccessAsync(registration, cancellationToken);

            await _context.UpdateAsync(registration, cancellationToken);
        }
        public async Task CheckCertificateUpdateAccessAsync(
            Certificate certificate,
            CancellationToken cancellationToken = default)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            var reg = await GetRegistrationForCertificateAsync(certificate, cancellationToken);

            await _registrationAccessControlService
            .CheckRegistrationUpdateAccessAsync(reg, cancellationToken);
        }
        public async Task <Registration> GetRegistrationByIdAsync(int id,
                                                                  RegistrationRetrievalOptions options,
                                                                  CancellationToken cancellationToken)
        {
            options ??= RegistrationRetrievalOptions.Default;

            var registration = await _context.Registrations
                               .WithOptions(options)
                               .FirstOrDefaultAsync(r => r.RegistrationId == id, cancellationToken)
                               ?? throw new NotFoundException($"Registration {id} not found.");

            if (options.ForUpdate)
            {
                await _registrationAccessControlService
                .CheckRegistrationUpdateAccessAsync(registration, cancellationToken);
            }
            else
            {
                await _registrationAccessControlService
                .CheckRegistrationReadAccessAsync(registration, cancellationToken);
            }

            return(registration);
        }
        public async Task <Order> CreateOrderForRegistrationAsync(
            int registrationId,
            OrderItemDto[] data,
            CancellationToken cancellationToken)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (!data.Any())
            {
                throw new ArgumentException("Can't create empty order"); // can't we?
            }

            var registration = await _registrationRetrievalService
                               .GetRegistrationByIdAsync(registrationId,
                                                         new RegistrationRetrievalOptions
            {
                ForUpdate = true,
                LoadUser  = true
            },
                                                         cancellationToken);

            await _registrationAccessControlService
            .CheckRegistrationUpdateAccessAsync(registration, cancellationToken);

            var productIds = data.Select(o => o.ProductId).ToArray();
            var variantIds = data.Select(o => o.VariantId).ToArray();

            var productMap = await _context.Products
                             .Where(p => productIds.Contains(p.ProductId))
                             .ToDictionaryAsync(p => p.ProductId, cancellationToken);

            var variantMap = await _context.ProductVariants
                             .Where(v => variantIds.Contains(v.ProductVariantId))
                             .ToDictionaryAsync(v => v.ProductVariantId, cancellationToken);

            await ValidateProducts(registration, data, productMap, variantMap, cancellationToken);

            var order = new Order
            {
                User                     = registration.User,
                Registration             = registration,
                CustomerName             = registration.CustomerName ?? registration.ParticipantName,
                CustomerEmail            = registration.CustomerEmail ?? registration.CustomerEmail,
                CustomerVatNumber        = registration.CustomerVatNumber,
                CustomerInvoiceReference = registration.CustomerInvoiceReference,
                PaymentMethod            = registration.PaymentMethod,
                OrderLines               = data.Select(dto => new OrderLine(
                                                           productMap[dto.ProductId], dto.Quantity,
                                                           dto.VariantId.HasValue ? variantMap[dto.VariantId.Value] : null))
                                           .ToList()
            };

            order.AddLog();

            await _context.CreateAsync(order, cancellationToken : cancellationToken);

            return(order);
        }