public async Task <ActionResult> Put([FromBody] ChangeInvoice request)
        {
            try
            {
                await _useCases.Invoke(request);

                return(Ok());
            }
            catch (InvoiceNotFoundException ex)
            {
                _logger.LogError(ex, "Invalid not found");

                return(NotFound(new { message = ex.Message }));
            }
            catch (InvalidInvoiceException ex)
            {
                _logger.LogError(ex, "Invalid invoice");

                return(BadRequest(new { message = ex.Message, errors = ex.Errors.Select(error => new { message = error }) }));
            }
            catch (InvalidInvoiceOperationException ex)
            {
                _logger.LogError(ex, "Invalid operation");

                return(BadRequest(new { message = ex.Message }));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error changing invoice");

                while (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                return(StatusCode(500, new { message = ex.Message, details = ex.StackTrace }));
            }
        }
Example #2
0
        public async Task Invoke(ChangeInvoice request)
        {
            var invoice = request.Invoice;

            var existing = await _repository.GetByNumber(invoice?.Number ?? 0);

            if (existing == null)
            {
                throw new InvoiceNotFoundException(invoice.Number);
            }

            if (existing.Status != Status.Created)
            {
                throw new InvalidInvoiceOperationException(invoice.Number, "Change");
            }

            existing.Date     = invoice.Date;
            existing.Customer = invoice.Customer;
            existing.Amount   = invoice.Amount;

            if (invoice.Items != null)
            {
                foreach (var existingItem in existing.Items)
                {
                    var item = invoice.Items.FirstOrDefault(x => x.Number == existingItem.Number);

                    if (item != null)
                    {
                        existingItem.Description = item.Description;
                        existingItem.Quantity    = item.Quantity;
                        existingItem.UnitPrice   = item.UnitPrice;
                        existingItem.Amount      = item.Amount;
                    }
                }
            }

            var errors = new List <string>();

            if (invoice.Date > DateTime.Today)
            {
                errors.Add("Invoice date must not be a future date");
            }

            if (invoice.Number <= 0)
            {
                errors.Add("Invoice number must be greater than 0");
            }

            if (invoice.Amount < 0)
            {
                errors.Add("Invoice amount must be greater than or equal to 0");
            }
            else if (invoice.Amount != (invoice.Items ?? Enumerable.Empty <Item>()).Sum(x => x.Amount))
            {
                errors.Add("Invoice amount must be equal to the sum of items amount");
            }

            if (string.IsNullOrWhiteSpace(invoice.Customer))
            {
                errors.Add("Invoice customer must not be null or empty");
            }

            if (invoice.Items == null || invoice.Items.Count == 0)
            {
                errors.Add("Invoice status must have at least one item");
            }

            if (invoice.Items != null)
            {
                int a = 1;
                foreach (var x in invoice.Items.OrderBy(x => x.Number))
                {
                    if (x.Number != a)
                    {
                        errors.Add($"Invoice item with number {a} not found");

                        break;
                    }

                    a++;
                }

                for (int index = 0; index < invoice.Items.Count; index++)
                {
                    var item = invoice.Items[index];

                    if (item.Number <= 0)
                    {
                        errors.Add($"Item number at position {index} must be greater than 0");
                    }

                    if (string.IsNullOrWhiteSpace(item.Description))
                    {
                        errors.Add($"Item description at position {index} must not be null or empty");
                    }

                    if (item.Quantity < 0)
                    {
                        errors.Add($"Item quantity at position {index} must be greater than or equal to 0");
                    }

                    if (item.UnitPrice < 0)
                    {
                        errors.Add($"Item unit price at position {index} must be greater than or equal to 0");
                    }

                    if (item.Amount < 0)
                    {
                        errors.Add($"Item amount at position {index} must be greater than or equal to 0");
                    }
                    else if (item.Amount != item.Quantity * item.UnitPrice)
                    {
                        errors.Add($"Item amount at position {index} must be equal to quantity x unit price");
                    }
                }
            }

            if (errors.Count > 0)
            {
                throw new InvalidInvoiceException(errors);
            }

            await _repository.Update(existing);
        }