private void AddOrRemoveCategories(Product product, SavedProductDto productDto)
 {
     try
     {
         var addedCategories =
             productDto.Categories.Where(id => product.ProductCategories.All(pd => pd.CategoryId != id)).ToList();
         if (addedCategories.Any())
         {
             foreach (var category in addedCategories)
             {
                 product.AddCategory(category);
             }
         }
         var removedCategories =
             product.ProductCategories.Where(c => !productDto.Categories.Contains(c.CategoryId)).ToList();
         if (removedCategories.Any())
         {
             foreach (var category in addedCategories)
             {
                 product.RemoveCategory(category);
             }
         }
     }
     catch (Exception e)
     {
         throw new Exception(e.Message);
     }
 }
        public async Task <IServiceResult> UpdateAsync(string id, SavedProductDto productDto)
        {
            try
            {
                var productId = id.ToGuid();
                var product   = await _repository.GetSingleAsync(productId);

                _mapper.Map(productDto, product);

                AddOrRemoveCategories(product, productDto);
                if (!await _unitOfWork.CompleteAsync())
                {
                    throw new SaveFailedException(nameof(product));
                }
                _logger.LogInformation($"Updated {nameof(product)} with id: {product.Id}");

                var result = await GetSingleAsync(product.Id.ToString());

                return(new ServiceResult(payload: result.Payload));
            }
            catch (Exception e)
            {
                _logger.LogError($"Updating product with id: {id} failed. {e.Message}");

                return(new ServiceResult(false, e.Message));
            }
        }
        public async Task <IServiceResult> CreateAsync(SavedProductDto productDto)
        {
            try
            {
                var product = _mapper.Map <SavedProductDto, Product>(productDto);

                await _repository.AddAsync(product);

                AddToInventory(product, productDto.SupplierId, productDto.Stock);

                if (productDto.Categories.Count > 0)
                {
                    foreach (var c in productDto.Categories)
                    {
                        AddCategory(product, c);
                        _logger.LogError($"Added product with id {product.Id}.");
                    }
                }

                if (!await _unitOfWork.CompleteAsync())
                {
                    throw new SaveFailedException(nameof(product));
                }
                _logger.LogInformation($"Added new {nameof(product)} with id: {product.Id}");

                var result = await GetSingleAsync(product.Id.ToString());

                return(new ServiceResult(payload: result.Payload));
            }
            catch (Exception e)
            {
                _logger.LogError($"Adding new product failed. {e.Message}");

                return(new ServiceResult(false, e.Message));
            }
        }