Oi professor, a minha duvida é em relaçaõa a criacao de um delete no controller da consulta como tnha no medico ou paciente controller por exemplo. Eu fiz desse jeito mas voce acha que é mais simples do jeito como a esta a resposta?
Oi professor, a minha duvida é em relaçaõa a criacao de um delete no controller da consulta como tnha no medico ou paciente controller por exemplo. Eu fiz desse jeito mas voce acha que é mais simples do jeito como a esta a resposta?
Oi!
Acho que faltou o seu código na mensagem.
package med.absolut.api.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import med.absolut.api.consulta.AgendaConsulta;
import med.absolut.api.consulta.CancelamentoConsulta;
import med.absolut.api.consulta.ConsultaRepository;
import med.absolut.api.consulta.DadosAgendamento;
import med.absolut.api.consulta.DadosCancelamento;
@RestController
@RequestMapping("/consultas")
public class ConsultaController {
@Autowired
private AgendaConsulta agendaConsulta;
@Autowired
private CancelamentoConsulta cancelamentoConsulta;
@PostMapping
@Transactional
public ResponseEntity agendar(@RequestBody @Valid DadosAgendamento dados) {
var dto = agendaConsulta.agendar(dados);
return ResponseEntity.ok(dto);
}
@DeleteMapping("/{id}")
@Transactional
public ResponseEntity cancelar(DadosCancelamento dados) {
var c = cancelamentoConsulta.cancelar(dados.idConsulta());
return ResponseEntity.noContent().build();
}
}
package med.absolut.api.consulta;
import jakarta.validation.constraints.NotNull;
public record DadosCancelamento(
@NotNull
Long idConsulta,
@NotNull
MotivoCancelamento motivo
) {
public boolean existsById(@NotNull Long idConsulta) {
return false;
}
}
package med.absolut.api.consulta;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import med.absolut.api.consulta.validacoes.cancelamento.ValidadorCancelamento;
import med.absolut.api.infra.exception.ValidacaoException;
@Service
public class CancelamentoConsulta {
@Autowired
private ConsultaRepository consultaRepository;
@Autowired
private List<ValidadorCancelamento> validadoresCancelamento;
public void cancelar(DadosCancelamento cancelamento) {
if (!cancelamento.existsById(cancelamento.idConsulta())) {
throw new ValidacaoException("Consulta já está cancelada");
}
validadoresCancelamento.forEach(v -> v.validar(cancelamento));
var c = consultaRepository.getReferenceById(cancelamento.idConsulta());
}
}
package med.absolut.api.consulta.validacoes.cancelamento;
import java.time.Duration;
import java.time.LocalDateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import med.absolut.api.consulta.ConsultaRepository;
import med.absolut.api.consulta.DadosCancelamento;
import med.absolut.api.infra.exception.ValidacaoException;
@Component
public class ValidadorHorarioAtecidencaCancelamento implements ValidadorCancelamento {
@Autowired
private ConsultaRepository repository;
@Override
public void validar(DadosCancelamento dados) {
var consulta = repository.getReferenceById(dados.idConsulta());
var agora = LocalDateTime.now();
var diferencaEmHoras = Duration.between(agora, consulta.getData()).toHours();
if(diferencaEmHoras < 24){
throw new ValidacaoException("Consulta somente pode ser cancelada com antecedência mínima de 24h!");
}
}
}
package med.absolut.api.consulta.validacoes.cancelamento;
import med.absolut.api.consulta.DadosCancelamento;
public interface ValidadorCancelamento {
void validar(DadosCancelamento dados);
}
Assim está ocodigo mas estou tndo um problema no controller em relação ao metodo cancelar, esta é a menssagem: "The method cancelar(DadosCancelamento) in the type CancelamentoConsulta is not applicable for the arguments (Long)"
O problema é no seu método cancelar do controller, que está passando como parâmetro apenas o id da consulta ao invés do objeto dados:
@DeleteMapping("/{id}")
@Transactional
public ResponseEntity cancelar(DadosCancelamento dados) {
var c = cancelamentoConsulta.cancelar(dados.idConsulta());
return ResponseEntity.noContent().build();
}
Altere para:
@DeleteMapping("/{id}")
@Transactional
public ResponseEntity cancelar(DadosCancelamento dados) {
cancelamentoConsulta.cancelar(dados);
return ResponseEntity.noContent().build();
}
professor eu fiz isso e alguns ajustes, mas estou recebendo este erro:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'agendaConsulta': Unsatisfied dependency expressed through field 'medicoRepository': Error creating bean with name 'medicoRepository' defined in med.absolut.api.medico.MedicoRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract med.absolut.api.medico.Medico med.absolut.api.medico.MedicoRepository.escolherMedicoAleatoriamente(med.absolut.api.medico.Especialidades,java.time.LocalDateTime); Reason: Validation failed for query for method public abstract med.absolut.api.medico.Medico med.absolut.api.medico.MedicoRepository.escolherMedicoAleatoriamente(med.absolut.api.medico.Especialidades,java.time.LocalDateTime)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'medicoRepository' defined in med.absolut.api.medico.MedicoRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract med.absolut.api.medico.Medico med.absolut.api.medico.MedicoRepository.escolherMedicoAleatoriamente(med.absolut.api.medico.Especialidades,java.time.LocalDateTime); Reason: Validation failed for query for method public abstract med.absolut.api.medico.Medico med.absolut.api.medico.MedicoRepository.escolherMedicoAleatoriamente(med.absolut.api.medico.Especialidades,java.time.LocalDateTime)
Caused by: org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract med.absolut.api.medico.Medico med.absolut.api.medico.MedicoRepository.escolherMedicoAleatoriamente(med.absolut.api.medico.Especialidades,java.time.LocalDateTime); Reason: Validation failed for query for method public abstract med.absolut.api.medico.Medico med.absolut.api.medico.MedicoRepository.escolherMedicoAleatoriamente(med.absolut.api.medico.Especialidades,java.time.LocalDateTime)
Caused by: java.lang.IllegalArgumentException: org.hibernate.query.sqm.UnknownPathException: Could not resolve attribute 'motivoCancelamento' of 'med.absolut.api.consulta.Consulta' [select m from Medico m where m.ativo = true and m.especialidade = :especialidade and m.id not in (
select c.medico.id from Consulta c where c.data = :data and c.motivoCancelamento is null)
order by rand()
]
Caused by: org.hibernate.query.sqm.UnknownPathException: Could not resolve attribute 'motivoCancelamento' of 'med.absolut.api.consulta.Consulta' [select m from Medico m where m.ativo = true and m.especialidade = :especialidade and m.id not in (
select c.medico.id from Consulta c where c.data = :data and c.motivoCancelamento is null)
order by rand()
]
Caused by: org.hibernate.query.sqm.PathElementException: Could not resolve attribute 'motivoCancelamento' of 'med.absolut.api.consulta.Consulta'
Está dando erro dizendo que na sua classe Consulta não tem o atributo motivoCancelamento
Professor eu fiz estas alterações porem ainda ets adando erro
package med.absolut.api.consulta;
import java.time.LocalDateTime;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import med.absolut.api.medico.Medico;
import med.absolut.api.paciente.Paciente;
@Table(name = "consultas")
@Entity(name = "Consulta")
@Getter
@NoArgsConstructor
@EqualsAndHashCode(of = "id")
public class Consulta {
public Consulta(Long id, Medico medico, Paciente paciente, LocalDateTime data) {
this.id = id;
this.medico = medico;
this.paciente = paciente;
this.data = data;
}
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "medico_id")
private Medico medico;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "paciente_id")
private Paciente paciente;
private LocalDateTime data;
@Enumerated(EnumType.STRING)
private MotivoCancelamento motivo;
public void cancelar(MotivoCancelamento motivoCancelamento) {
this.motivo = motivoCancelamento;
}
}
package med.absolut.api.consulta;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import med.absolut.api.consulta.validacoes.cancelamento.ValidadorCancelamento;
import med.absolut.api.infra.exception.ValidacaoException;
@Service
public class CancelamentoConsulta {
@Autowired
private ConsultaRepository consultaRepository;
@Autowired
private List<ValidadorCancelamento> validadoresCancelamento;
public void cancelar(DadosCancelamento cancelamento) {
if (!cancelamento.existsById(cancelamento.idConsulta())) {
throw new ValidacaoException("Consulta já está cancelada");
}
validadoresCancelamento.forEach(v -> v.validar(cancelamento));
var c = consultaRepository.getReferenceById(cancelamento.idConsulta());
c.cancelar(cancelamento.motivo());
consultaRepository.save(c);
}
}
package med.absolut.api.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import med.absolut.api.consulta.AgendaConsulta;
import med.absolut.api.consulta.CancelamentoConsulta;
import med.absolut.api.consulta.DadosAgendamento;
import med.absolut.api.consulta.DadosCancelamento;
@RestController
@RequestMapping("/consultas")
public class ConsultaController {
@Autowired
private AgendaConsulta agendaConsulta;
@Autowired
private CancelamentoConsulta cancelamentoConsulta;
@PostMapping
@Transactional
public ResponseEntity agendar(@RequestBody @Valid DadosAgendamento dados) {
var dto = agendaConsulta.agendar(dados);
return ResponseEntity.ok(dto);
}
@DeleteMapping("/{id}")
@Transactional
public ResponseEntity cancelar(@RequestBody @Valid DadosCancelamento dados) {
cancelamentoConsulta.cancelar(dados);
return ResponseEntity.noContent().build();
}
}
Na sua classe Consulta o atributo se chama motivo, então na query da interface MedicoRepository você deve ajustar.
Funcionou obrgado professor!!