Пример #1
0
        public async Task <ISaida> PagarFatura(PagarFaturaEntrada entrada)
        {
            // Verifica se as informações para alteração foram informadas corretamente
            if (entrada.Invalido)
            {
                return(new Saida(false, entrada.Mensagens, null));
            }

            var cartaoSaida = await this.ObterCartaoCreditoPorId(entrada.IdCartaoCredito, entrada.IdUsuario, false);

            if (!cartaoSaida.Sucesso)
            {
                return(cartaoSaida);
            }

            var cartaoCredito = (CartaoCreditoSaida)cartaoSaida.Retorno;

            var dataFatura = new DateTime(entrada.AnoFatura, entrada.MesFatura, cartaoCredito.DiaVencimentoFatura);

            // Obtém todas as parcelas que compôem a fatura
            var parcelas = await _parcelaRepositorio.ObterPorCartaoCredito(entrada.IdCartaoCredito, dataFatura);

            var valorFatura = parcelas?.Where(x => !x.Lancada && !x.Descartada).Sum(x => x.Valor) + (entrada.ValorAdicionalDebito.HasValue ? entrada.ValorAdicionalDebito.Value : 0) - (entrada.ValorAdicionalCredito.HasValue ? entrada.ValorAdicionalCredito.Value : 0) ?? 0;

            // Verifica se o valor do pagamento é suficiente para o pagamento da fatura
            this.NotificarSeMenorQue(entrada.ValorPagamento, valorFatura, CartaoCreditoMensagem.Fatura_Valor_Pagamento_Menor_Valor_Total_Fatura);

            if (this.Invalido)
            {
                return(new Saida(false, this.Mensagens, null));
            }

            var contaSaida = await _contaServico.ObterContaPorId(entrada.IdContaPagamento, entrada.IdUsuario);

            if (!contaSaida.Sucesso)
            {
                return(cartaoSaida);
            }

            var contaPagamento = (ContaSaida)contaSaida.Retorno;

            // Verifica se o saldo da conta é maior ou igual ao valor da fatura
            this.NotificarSeMenorQue(contaPagamento.ValorSaldoAtual ?? 0, entrada.ValorPagamento, string.Format(CartaoCreditoMensagem.Fatura_Saldo_Insuficiente_Pagamento_Fatura, contaPagamento.ValorSaldoAtual?.ToString("C2")));

            if (this.Invalido)
            {
                return(new Saida(false, this.Mensagens, null));
            }

            Pessoa pessoa = null;

            if (entrada.IdPessoaPagamento.HasValue)
            {
                pessoa = await _pessoaRepositorio.ObterPorId(entrada.IdPessoaPagamento.Value);

                this
                .NotificarSeNulo(pessoa, PessoaMensagem.Id_Pessoa_Nao_Existe)
                .NotificarSeDiferentes(pessoa?.IdUsuario, entrada.IdUsuario, PessoaMensagem.Pessoa_Nao_Pertence_Usuario);

                if (this.Invalido)
                {
                    return(new Saida(false, this.Mensagens, null));
                }
            }

            if (this.Invalido)
            {
                return(new Saida(false, this.Mensagens, null));
            }

            var lancamentoFatura = new Lancamento(new LancamentoEntrada(
                                                      entrada.IdUsuario,
                                                      entrada.IdContaPagamento,
                                                      (int)TipoCategoriaEspecial.PagamentoFaturaCartao,
                                                      entrada.DataPagamento,
                                                      entrada.ValorPagamento,
                                                      idPessoa: pessoa?.Id,
                                                      observacao: $"Fatura {dataFatura.ToString("MMM").ToUpper()}/{dataFatura.ToString("yyyy")}"));

            // Insere o lançamento referente ao pagamento da fatura
            await _lancamentoRepositorio.Inserir(lancamentoFatura);

            await _uow.Commit();

            var fatura = new Fatura(
                entrada.IdCartaoCredito,
                lancamentoFatura.Id,
                entrada.MesFatura,
                entrada.AnoFatura,
                entrada.ValorAdicionalCredito,
                entrada.ObservacaoCredito,
                entrada.ValorAdicionalDebito,
                entrada.ObservacaoDebito);

            // Insere a fatura
            await _faturaRepositorio.Inserir(fatura);

            await _uow.Commit();

            foreach (var parcela in parcelas)
            {
                parcela.PagarFatura(fatura.Id, entrada.DataPagamento);
            }

            await _uow.Commit();

            fatura = await _faturaRepositorio.ObterPorId(fatura.Id);

            return(new Saida(true, new[] { CartaoCreditoMensagem.Fatura_Paga_Com_Sucesso }, new FaturaSaida(fatura, parcelas.Select(x => new ParcelaSaida(x)).ToList())));
        }