Example #1
0
        public async Task <Result <Guid> > Handle(CreateProductCommand request, CancellationToken token)
        {
            var reference = request.Reference;

            if (!string.IsNullOrWhiteSpace(reference))
            {
                var existingEntity =
                    await _context.Products.AnyAsync(
                        p => p.Reference == reference && p.ProducerId == request.ProducerId, token);

                if (existingEntity)
                {
                    return(Failure <Guid>($"Un produit existe déjà avec la référence {reference}."));
                }
            }
            else
            {
                var resultIdentifier =
                    await _identifierService.GetNextProductReferenceAsync(request.ProducerId, token);

                if (!resultIdentifier.Succeeded)
                {
                    return(Failure <Guid>(resultIdentifier));
                }

                reference = resultIdentifier.Data;
            }

            var producer = await _context.Producers.SingleAsync(e => e.Id == request.ProducerId, token);

            using (var transaction = await _context.BeginTransactionAsync(token))
            {
                var entity = new Domain.Product(Guid.NewGuid(), reference, request.Name, request.Conditioning,
                                                request.Unit, request.QuantityPerUnit, producer);

                entity.SetVat(request.Vat);
                entity.SetDescription(request.Description);
                entity.SetAvailable(request.Available ?? true);
                entity.SetWeight(request.Weight);

                if (request.ReturnableId.HasValue)
                {
                    var returnable =
                        await _context.Returnables.SingleAsync(e => e.Id == request.ReturnableId.Value, token);

                    entity.SetReturnable(returnable);
                }

                var tags = await _context.Tags.Where(t => request.Tags.Contains(t.Id)).ToListAsync(token);

                entity.SetTags(tags);

                if (request.Catalogs != null)
                {
                    foreach (var catalogPrice in request.Catalogs)
                    {
                        var catalog = await _context.Catalogs.SingleAsync(e => e.Id == catalogPrice.CatalogId, token);

                        entity.AddOrUpdateCatalogPrice(catalog, catalogPrice.WholeSalePricePerUnit);
                    }
                }

                await _context.AddAsync(entity, token);

                await _context.SaveChangesAsync(token);

                if (request.Pictures != null && request.Pictures.Any())
                {
                    var result = Success <string>();
                    foreach (var picture in request.Pictures.OrderBy(p => p.Position))
                    {
                        var id = Guid.NewGuid();
                        result = await _imageService.HandleProductPictureAsync(entity, id, picture.Data, token);

                        if (!result.Succeeded)
                        {
                            break;
                        }

                        if (!string.IsNullOrWhiteSpace(result.Data))
                        {
                            entity.AddPicture(new ProductPicture(id, result.Data, picture.Position));
                        }
                    }

                    if (!result.Succeeded)
                    {
                        return(Failure <Guid>(result));
                    }
                }
                else
                {
                    var picture = _imageService.GetDefaultProductPicture(tags);
                    entity.AddPicture(new ProductPicture(Guid.NewGuid(), picture, 0));
                }

                producer.IncreaseProductsCount();

                await _context.SaveChangesAsync(token);

                await transaction.CommitAsync(token);

                if (!request.SkipUpdateProducerTags)
                {
                    _mediatr.Post(new UpdateProducerTagsCommand(request.RequestUser)
                    {
                        ProducerId = request.ProducerId
                    });
                }

                return(Success(entity.Id));
            }
        }