/// <summary>
        /// Remove a movement from a invoice
        /// </summary>
        /// <returns></returns>
        public async Task RemoveFromInvoice(int movementId)
        {
            _movementService = new MovementService();

            var movement = await _movementService.GetById(movementId);

            if (movement.Invoice.InvoiceStatus != InvoiceStatus.NotClosed)
            {
                throw new NotValidOperationException($"The invoice #{movement.Invoice.Id} ({movement.Invoice.Reference}) is already closed");
            }

            movement.Invoice   = null;
            movement.InvoiceId = null;

            await _movementService.Update(movement);
        }
        /// <summary>
        /// Adjust the balance of a collection of accounts
        /// </summary>
        /// <param name="accounts"></param>
        /// <returns></returns>
        public async Task AdjustBalance(IEnumerable <Account> accounts)
        {
            var accountsCollection = new List <Account>();

            _movementService = new MovementService();

            foreach (var account in accounts.Distinct())
            {
                var obj = await GetById(account.Id);

                obj.Balance = (obj.InitialBalance + obj.TotalCredit) - obj.TotalDebit;
                accountsCollection.Add(obj);
            }

            await _repository.Update(accountsCollection);
        }
        /// <summary>
        /// Pay an invoice
        /// </summary>
        /// <param name="invoice"></param>
        public async Task Pay(InvoicePaymentViewModel viewModel)
        {
            _movementService = new MovementService();
            var invoice = await _repository.GetInvoiceById(viewModel.Invoice.Id);

            invoice.InvoiceStatus = InvoiceStatus.Paid;
            invoice.PaymentDate   = viewModel.PaymentDate;

            viewModel.Invoice = invoice;

            if (viewModel.PaidValue > invoice.TotalValue)
            {
                throw new InvalidOperationException($"The max value to pay is {viewModel.Invoice.TotalValue.ToString("F2")}");
            }

            await _movementService.Add(await CreateInvoicePaymentMovementObject(viewModel));

            await _movementService.Update(invoice.Movements.Select((m) => { m.MovementStatus = MovementStatus.Launched; return(m); }), false);

            await _repository.Update(invoice);
        }