public async Task <AnticipationResult> Create(List <int> paymentIds, DateTime solicitationDate)
        {
            // Check if there's a open solicitation
            var openAnalysis = await _dbContext.Set <AnticipationAnalysis>()
                               .Where(x => x.EndDate == null)
                               .FirstOrDefaultAsync();

            if (openAnalysis != null)
            {
                return(_resultService.GenerateFailedResult("Cannot open solicitation without finilizing the current one.", true));
            }

            var payments = await _dbContext.Set <PaymentEntity>()
                           .Where(x => paymentIds.Contains(x.Id) && x.AnticipationId == null && x.Approved == true)
                           .ToListAsync();

            if (payments.Count() == 0)
            {
                return(_resultService.GenerateFailedResult("None of the solicited payments are available for anticipation.", true));
            }


            var entity = new AnticipationEntity
            {
                SolicitationDate = solicitationDate,
                SolicitedValue   = 0,
            };

            await _dbContext.AddAsync(entity);

            await _dbContext.SaveChangesAsync();

            // sets the payment.solicitationId fields to the current anticipation id
            // needs to be done after the SaveChangesAsync so the id is set.
            foreach (var payment in payments)
            {
                payment.AnticipationId = entity.Id;
                entity.SolicitedValue += payment.LiquidValue * TaxRate;
            }

            var analysis = new AnticipationAnalysis
            {
                AnticipationId = entity.Id
            };

            await _dbContext.AddAsync(analysis);

            await _dbContext.SaveChangesAsync();

            await FillInternalEntities(entity);

            return(_resultService.GenerateResult(entity));
        }
        public async Task <PaymentProcessResult> ProcessPayment(PaymentRequest request, DateTime transactionDate)
        {
            if (request.RawValue <= FixedTax)
            {
                var rejectedPayment = new PaymentEntity
                {
                    TransactionDate = transactionDate,
                    Approved        = false,
                    CancelDate      = transactionDate,
                    RawValue        = request.RawValue,
                    Tax             = FixedTax,
                    CreditCard      = request.CreditCard.Substring(12),
                };

                await _paymentDbService.Create(rejectedPayment);

                return(_resultService.GenerateFailedResult(rejectedPayment, $"{nameof(request.RawValue)} must be greater then the {nameof(FixedTax)} ({FixedTax})"));
            }

            if (request.PaymentInstallmentCount == 0)
            {
                request.PaymentInstallmentCount = 1;
            }

            if (request.CreditCard.Substring(0, 4) == UnprocessableCreditCard)
            {
                var rejectedPayment = new PaymentEntity
                {
                    TransactionDate = transactionDate,
                    Approved        = false,
                    CancelDate      = transactionDate,
                    RawValue        = request.RawValue,
                    LiquidValue     = request.RawValue - FixedTax,
                    Tax             = FixedTax,
                    CreditCard      = request.CreditCard.Substring(12),
                };

                await _paymentDbService.Create(rejectedPayment);

                return(_resultService.GenerateFailedResult(rejectedPayment, $"{nameof(request.CreditCard)} denied."));
            }

            var payment = new PaymentEntity
            {
                TransactionDate         = transactionDate,
                Approved                = true,
                AprovalDate             = transactionDate,
                RawValue                = request.RawValue,
                LiquidValue             = request.RawValue - FixedTax,
                Tax                     = FixedTax,
                CreditCard              = request.CreditCard.Substring(12),
                PaymentInstallmentCount = request.PaymentInstallmentCount
            };

            await _paymentDbService.Create(payment);

            for (int i = 1; i <= request.PaymentInstallmentCount; i++)
            {
                await _paymentInstallmentDbService.Create(new PaymentInstallmentEntity
                {
                    PaymentId         = payment.Id,
                    RawValue          = request.RawValue / request.PaymentInstallmentCount,
                    LiquidValue       = payment.LiquidValue / request.PaymentInstallmentCount,
                    InstallmentNumber = i,
                    DueDate           = transactionDate.AddDays(i * 30),
                });
            }

            var entity = await _paymentDbService.Get(payment.Id);

            var result = _resultService.GenerateResult(entity, true);

            return(result);
        }