public IActionResult Get(int id)
        {
            DoacaoObjeto q = _context.DoacaoObjeto
                             .Include(d => d.Doador)
                             .Include(d => d.Endereco)
                             .Include(d => d.Voluntario)
                             .SingleOrDefault(i => i.Id == id);

            if (q == null)
            {
                return(new NotFoundResult());
            }

            DoacaoObjetoDTO dto = new DoacaoObjetoDTO
            {
                Id           = q.Id,
                DataDaDoacao = q.DataDaDoacao,
                Descricao    = q.Descricao,
                Doador       = new DoadorDTOR()
                {
                    Id = q.Doador.CodDoador,
                    NomeRazaoSocial = q.Doador.GetType() == typeof(PessoaFisica) ? ((PessoaFisica)q.Doador).Nome : ((PessoaJuridica)q.Doador).RazaoSocial,
                    Tipo            = q.Doador.GetType() == typeof(PessoaFisica)?"PF":"PJ"
                },
                DataDeRetirada = q.DataDeRetirada,
                Endereco       = new EnderecoDTO()
                {
                    Id          = q.Endereco.Id,
                    Bairro      = q.Endereco.Bairro,
                    Cep         = q.Endereco.Cep,
                    Cidade      = q.Endereco.Cidade,
                    Complemento = q.Endereco.Complemento,
                    Estado      = q.Endereco.Estado,
                    Logradouro  = q.Endereco.Logradouro,
                    Numero      = q.Endereco.Numero,
                },
                Voluntario = new VoluntarioDTOR()
                {
                    Id    = q.Voluntario.Id,
                    Nome  = q.Voluntario.Nome,
                    Email = q.Voluntario.Email
                }
            };

            return(new ObjectResult(dto));
        }
        public IActionResult Put(int id, [FromBody] DoacaoObjetoDTO dto)
        {
            if (id != dto.Id)
            {
                return(new BadRequestResult());
            }
            if (ModelState.IsValid)
            {
                //corrige fuso horario do js
                //dto.DataDaDoacao = dto.DataDaDoacao.AddHours(-dto.DataDaDoacao.Hour);
                DoacaoObjeto dd = _context.DoacaoObjeto.Include(q => q.Endereco).Single(q => q.Id == id);

                Doador doador = _context.Doador.SingleOrDefault(q => q.CodDoador == dto.Doador.Id);
                if (doador == null)
                {
                    ModelState.AddModelError("Doador", "Doador inválido");
                    return(new BadRequestObjectResult(ModelState));
                }

                Voluntario voluntario = _context.Voluntario.SingleOrDefault(q => q.Id == dto.Voluntario.Id);
                if (voluntario == null)
                {
                    ModelState.AddModelError("Voluntario", "Voluntario inválido");
                    return(new BadRequestObjectResult(ModelState));
                }

                //regra
                //o voluntario tem que ter uma folga de 2 horas entre as retiradas de doações
                DateTime duasHorasAntes  = dto.DataDeRetirada.AddHours(-2);
                DateTime duasHorasDepois = dto.DataDeRetirada.AddHours(2);
                if (_context.DoacaoObjeto.Where(q => q.Id != id && q.DataDeRetirada >= duasHorasAntes && q.DataDeRetirada <= duasHorasDepois && q.Voluntario.Id == voluntario.Id).Any())
                {
                    ModelState.AddModelError("Voluntario", "O voluntário tem outra retirada muito próxima deste horario");
                    return(new BadRequestObjectResult(ModelState));
                }


                dd.Doador         = doador;
                dd.DataDaDoacao   = dto.DataDaDoacao;
                dd.Descricao      = dto.Descricao;
                dd.DataDeRetirada = dto.DataDeRetirada;

                dd.Endereco.Cep         = dto.Endereco.Cep;
                dd.Endereco.Bairro      = dto.Endereco.Bairro;
                dd.Endereco.Cidade      = dto.Endereco.Cidade;
                dd.Endereco.Complemento = dto.Endereco.Complemento;
                dd.Endereco.Estado      = dto.Endereco.Estado;
                dd.Endereco.Numero      = dto.Endereco.Numero;
                dd.Endereco.Logradouro  = dto.Endereco.Logradouro;

                dd.Voluntario = voluntario;

                try
                {
                    _context.SaveChanges();
                    enviarEmail(dd);
                }
                catch
                {
                    return(new BadRequestObjectResult(ModelState));
                }

                return(new ObjectResult(dto));
            }
            else
            {
                return(new BadRequestObjectResult(ModelState));
            }
        }
        public IActionResult Post([FromBody] DoacaoObjetoDTO dto)
        {
            if (ModelState.IsValid)
            {
                Doador doador = _context.Doador.SingleOrDefault(q => q.CodDoador == dto.Doador.Id);
                if (doador == null)
                {
                    ModelState.AddModelError("Doador", "Doador inválido");
                    return(new BadRequestObjectResult(ModelState));
                }

                Voluntario voluntario = _context.Voluntario.SingleOrDefault(q => q.Id == dto.Voluntario.Id);
                if (voluntario == null)
                {
                    ModelState.AddModelError("Voluntario", "Voluntario inválido");
                    return(new BadRequestObjectResult(ModelState));
                }


                //corrige fuso horario do js
                //dto.DataDaDoacao = dto.DataDaDoacao.AddHours(-dto.DataDaDoacao.Hour);


                //regra
                //o voluntario tem que ter uma folga de 2 horas entre as retiradas de doações
                DateTime duasHorasAntes  = dto.DataDeRetirada.AddHours(-2);
                DateTime duasHorasDepois = dto.DataDeRetirada.AddHours(2);
                if (_context.DoacaoObjeto.Where(q => q.DataDeRetirada >= duasHorasAntes && q.DataDeRetirada <= duasHorasDepois && q.Voluntario.Id == voluntario.Id).Any())
                {
                    ModelState.AddModelError("Voluntario", "O voluntário tem outra retirada muito próxima deste horario");
                    return(new BadRequestObjectResult(ModelState));
                }

                DoacaoObjeto novo = new DoacaoObjeto()
                {
                    Doador         = doador,
                    DataDaDoacao   = dto.DataDaDoacao,
                    Descricao      = dto.Descricao,
                    DataDeRetirada = dto.DataDeRetirada,
                    Endereco       = new Endereco
                    {
                        Bairro      = dto.Endereco.Bairro,
                        Cep         = dto.Endereco.Cep,
                        Cidade      = dto.Endereco.Cidade,
                        Complemento = dto.Endereco.Complemento,
                        Estado      = dto.Endereco.Estado,
                        Logradouro  = dto.Endereco.Logradouro,
                        Numero      = dto.Endereco.Numero
                    },
                    Voluntario = voluntario
                };
                try
                {
                    _context.DoacaoObjeto.Add(novo);

                    _context.SaveChanges();
                    enviarEmail(novo);
                    dto.Id = novo.Id;
                    return(new ObjectResult(dto));
                }
                catch {
                    return(new BadRequestObjectResult(ModelState));
                }
            }

            return(new BadRequestObjectResult(ModelState));
        }