diff --git a/.env.example b/.env.example index f9a270e0..4c0043eb 100644 --- a/.env.example +++ b/.env.example @@ -13,3 +13,6 @@ CLOUDINARY_API_SECRET=valor-cloudinary PERSPECTIVE_API_KEY=valor-perspective RECAPTCHA_SITE_KEY=valor-recaptcha +#chaves API Mercado Pago +MP_PUBLIC_KEY=chave +MP_ACCESS_TOKEN=chave \ No newline at end of file diff --git a/pom.xml b/pom.xml index 99cf0888..c7dccaa0 100644 --- a/pom.xml +++ b/pom.xml @@ -139,6 +139,86 @@ jackson-databind 2.13.0 + + org.projectlombok + lombok + 1.18.24 + + + + + com.mercadopago + sdk-java + 2.0.1 + + + com.google.code.gson + gson + 2.8.9 + + + + com.itextpdf + itext7-core + 7.2.0 + + + + com.sun.mail + javax.mail + 1.6.2 + + + + + org.apache.xmlgraphics + batik-transcoder + 1.14 + + + xalan + xalan + + + + + + + com.google.zxing + core + 3.4.1 + + + + com.google.zxing + javase + 3.4.1 + + + + + org.apache.xmlgraphics + fop + 2.6 + + + xalan + xalan + + + + + + com.google.api-client + google-api-client + 1.32.1 + + + + org.postgresql + postgresql + runtime + diff --git a/src/main/java/br/edu/utfpr/servicebook/config/WebSecurityConfig.java b/src/main/java/br/edu/utfpr/servicebook/config/WebSecurityConfig.java index 6f15e02d..3bd3b0dd 100644 --- a/src/main/java/br/edu/utfpr/servicebook/config/WebSecurityConfig.java +++ b/src/main/java/br/edu/utfpr/servicebook/config/WebSecurityConfig.java @@ -12,6 +12,7 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.web.client.RestTemplate; @Configuration @EnableWebSecurity @@ -21,7 +22,6 @@ public class WebSecurityConfig { @Autowired CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler; - private static final String[] PUBLIC_URLS = { "/", "/**", @@ -75,6 +75,9 @@ public AuthenticationManager authenticationManager(AuthenticationConfiguration a return authenticationConfiguration.getAuthenticationManager(); } - + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } } diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/ClientController.java b/src/main/java/br/edu/utfpr/servicebook/controller/ClientController.java index e4966ad3..52b0f7bb 100644 --- a/src/main/java/br/edu/utfpr/servicebook/controller/ClientController.java +++ b/src/main/java/br/edu/utfpr/servicebook/controller/ClientController.java @@ -12,13 +12,23 @@ import br.edu.utfpr.servicebook.sse.EventSSEDTO; import br.edu.utfpr.servicebook.sse.EventSseMapper; import br.edu.utfpr.servicebook.sse.SSEService; +import br.edu.utfpr.servicebook.util.DateUtil; import br.edu.utfpr.servicebook.util.pagination.PaginationDTO; import br.edu.utfpr.servicebook.util.pagination.PaginationUtil; import br.edu.utfpr.servicebook.util.UserTemplateInfo; import br.edu.utfpr.servicebook.util.TemplateUtil; +import com.cloudinary.Cloudinary; +import com.cloudinary.utils.ObjectUtils; +import com.mercadopago.client.common.AddressRequest; +import com.mercadopago.client.common.IdentificationRequest; +import com.mercadopago.client.common.PhoneRequest; +import com.mercadopago.client.preference.*; +import com.mercadopago.resources.preference.Preference; +import org.apache.batik.transcoder.TranscoderException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; @@ -31,12 +41,39 @@ import javax.annotation.security.RolesAllowed; import javax.persistence.EntityNotFoundException; import javax.servlet.http.HttpServletRequest; +import javax.xml.transform.TransformerException; +import java.io.File; import java.io.IOException; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; import java.time.LocalDate; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindingResult; +import com.google.zxing.WriterException; +import org.apache.batik.transcoder.TranscoderException; +import org.apache.fop.configuration.ConfigurationException; +import com.mercadopago.MercadoPagoConfig; +import org.springframework.validation.BindingResult; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.nio.file.Files; +import java.text.ParseException; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.Map; +import com.cloudinary.Cloudinary; +import com.cloudinary.utils.ObjectUtils; +import javax.validation.Valid; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +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; @RequestMapping("/minha-conta/cliente") @Controller public class ClientController { @@ -104,6 +141,54 @@ public class ClientController { @Autowired private ProfessionalMapper professionalMapper; + @Autowired + private PaymentService paymentService; + + @Autowired + private PaymentMapper paymentMapper; + + @Autowired + private PaymentVoucherService paymentVoucherService; + + @Autowired + private PaymentVoucherMapper paymentVoucherMapper; + + @Autowired + private PaymentJobService paymentJobService; + + @Autowired + private PaymentJobMapper paymentJobMapper; + + @Autowired + private Cloudinary cloudinary; + + @Autowired + private ProfessionalServiceOfferingService professionalServiceOfferingService; + + @Autowired + private AssessmentProfessionalService assessmentProfessionalService; + + @Autowired + private AssessmentProfessionalFileService assessmentProfessionalFileService; + + @Autowired + private CategoryService categoryService; + + @Autowired + private AssessmentProfessionalFileMapper assessmentProfessionalFileMapper; + + @Autowired + private ModerateService moderateService; + + @Autowired + private AssessmentResponseService assessmentResponseService; + + @Autowired + private PerspectiveAPIService perspectiveAPIService; + + @Value("${svg.certificate.template}") + private String svgCertificateTemplate; + /** * Método que apresenta a tela inicial do cliente @@ -192,11 +277,14 @@ public String delete (@PathVariable Long id, RedirectAttributes redirectAttribut */ @GetMapping("/meus-pedidos/{id}") @RolesAllowed({RoleType.USER, RoleType.COMPANY}) - public ModelAndView showDetailsRequest(@PathVariable Optional id) throws Exception { + public ModelAndView showDetailsRequest(@PathVariable Optional id, + @RequestParam(value = "pag", defaultValue = "1") int page, + @RequestParam(value = "siz", defaultValue = "4") int size) throws Exception { ModelAndView mv = new ModelAndView("client/details-request"); Optional jobRequest = jobRequestService.findById(id.get()); + Optional oJobContracted = jobContractedService.findByJobRequest(jobRequest.get()); if (!jobRequest.isPresent()) { throw new EntityNotFoundException("Solicitação de serviço não encontrado. Por favor, tente novamente."); @@ -214,7 +302,31 @@ public ModelAndView showDetailsRequest(@PathVariable Optional id) throws E ExpertiseMinDTO expertiseDTO = expertiseMapper.toMinDto(expertise.get()); - List jobCandidates = jobCandidateService.findByJobRequestOrderByChosenByBudgetDesc(jobRequest.get()); + Optional client = (userService.findByEmail(authentication.getEmail())); + + if (!client.isPresent()) { + throw new Exception("Usuário não autenticado! Por favor, realize sua autenticação no sistema."); + } + + PageRequest pageRequest = PageRequest.of(1 - 1, 4, Sort.by("dateTarget").ascending()); + Page jobRequestPage = null; + List jobRequestFullDTOs = null; + + List jobCandidates = jobCandidateService.findByJobRequestAndChosenByBudget(jobRequest.get(), true); + + jobRequestPage = jobRequestService.findByStatusAndClient(JobRequest.Status.DOING, client.get(), pageRequest); + + jobRequestFullDTOs = jobRequestPage.stream() + .map(jobRequest1 -> { + Optional totalCandidates = jobContractedService.findByJobRequest(jobRequest1); + + if (totalCandidates.isPresent()) { + return jobRequestMapper.toFullDto(jobRequest1); + } + + return jobRequestMapper.toFullDto(jobRequest1, Optional.ofNullable(0L)); + }).collect(Collectors.toList()); + List jobCandidatesDTOs = jobCandidates.stream() .map(candidate -> { @@ -222,9 +334,18 @@ public ModelAndView showDetailsRequest(@PathVariable Optional id) throws E }) .collect(Collectors.toList()); + if (jobRequest.get().getServiceOffering() != null) { + Optional pso = professionalServiceOfferingService.findById(jobRequest.get().getServiceOffering().getId()); + mv.addObject("service_professional", pso.get()); + } + + mv.addObject("candidates", jobCandidatesDTOs); + mv.addObject("jobCandidates12", jobRequestFullDTOs); mv.addObject("expertise", expertiseDTO); mv.addObject("jobRequest", jobDTO); + mv.addObject("jobContracted", oJobContracted.get()); + return mv; } @@ -237,15 +358,33 @@ public ModelAndView showDetailsRequest(@PathVariable Optional id) throws E */ @GetMapping("/meus-pedidos/{jobId}/detalhes/{candidateId}") @RolesAllowed({RoleType.USER, RoleType.COMPANY}) - public ModelAndView showDetailsRequestCandidate(@PathVariable Optional jobId, @PathVariable Optional candidateId) throws Exception { + public ModelAndView showDetailsRequestCandidate(@PathVariable Long jobId, @PathVariable Long candidateId) throws Exception { ModelAndView mv = new ModelAndView("client/details-request-candidate"); - Optional oCandidate = userService.findById(candidateId.get()); + System.out.println("DADOSSS"); + System.out.println(jobId); + System.out.println(candidateId); + + Optional oCandidate = userService.findById(candidateId); + Optional oIndividual = individualService.findById(candidateId); + + System.out.println(oCandidate); + System.out.println(oIndividual.get()); + if (!oCandidate.isPresent()) { throw new EntityNotFoundException("O candidato não foi encontrado!"); } - Optional jobCandidate = jobCandidateService.findById(jobId.get(), oCandidate.get().getId()); + Optional oJobRequest = jobRequestService.findById(jobId); + System.out.println("oJobRequest"); + System.out.println(oJobRequest); + + if (!oJobRequest.isPresent()) { + throw new EntityNotFoundException("O candidato não foi encontrado!"); + } + + Optional jobCandidate = jobCandidateService.findById(oJobRequest.get().getId(), oIndividual.get().getId()); + if (!jobCandidate.isPresent()) { throw new EntityNotFoundException("Candidato não encontrado. Por favor, tente novamente."); } @@ -273,7 +412,7 @@ public ModelAndView showDetailsRequestCandidate(@PathVariable Optional job public ModelAndView showAvailableJobs( HttpServletRequest request, @RequestParam(value = "pag", defaultValue = "1") int page, - @RequestParam(value = "siz", defaultValue = "3") int size, + @RequestParam(value = "siz", defaultValue = "4") int size, @RequestParam(value = "ord", defaultValue = "id") String order, @RequestParam(value = "dir", defaultValue = "ASC") String direction ) throws Exception { @@ -739,7 +878,7 @@ public String markAsClose( * Altera o estado de um serviço para TO_HIRED, ou seja, o cliente contratou um serviço mas * fica no estado de espera da confirmação do profissional. * @param jobId - * @param individualId + * @param userId * @param redirectAttributes * @return * @throws IOException @@ -764,16 +903,418 @@ public String markAsHided(@PathVariable Long jobId, @PathVariable Long userId, R jobRequest.setStatus(JobRequest.Status.TO_HIRED); jobRequestService.save(jobRequest); + System.out.println("JOBBBBBBBBB" + oJobRequest.get()); + //guarda a data de contratação - Optional oJobContracted = jobContractedService.findByJobRequest(jobRequest); - if(!oJobContracted.isPresent()) { - throw new EntityNotFoundException("O profissional não pode ser contratado!"); - } + Optional oJobContracted = jobContractedService.findByJobRequest(oJobRequest.get()); +// if(!oJobContracted.isPresent()) { +// throw new EntityNotFoundException("O profissional não pode ser contratado!"); +// } + Optional oUser = userService.findById(userId); - JobContracted jobContracted = oJobContracted.get(); + JobContracted jobContracted = new JobContracted(); jobContracted.setHiredDate(LocalDate.now()); + jobContracted.setJobRequest(oJobRequest.get()); + jobContracted.setUser(oUser.get()); jobContractedService.save(jobContracted); return "redirect:/minha-conta/cliente/meus-pedidos/"+jobId; } + + @Autowired + public ClientController(PaymentService paymentService) { + this.paymentService = paymentService; + } + + /** + * Responsável por realizar o pagamento via API Mercado Pago. + */ + @PostMapping("/pagamento") + @RolesAllowed({RoleType.USER}) + public ResponseEntity createPayment(@RequestBody CardPaymentDTO cardPaymentDTO) { + log.info("Received payment request: {}", cardPaymentDTO); + + Optional oUser = (userService.findByEmail(authentication.getEmail())); + +// +//// if(!paymentResponse.getStatusCode().is2xxSuccessful()){ +//// response.setMessage("Erro ao processar pagamento. Tente novamente"); +//// return ResponseEntity.status(paymentResponse.getStatusCode()).body(response); +//// } +// +// Map responseMap = (Map) responseBody; + +// Integer paymentId = (Integer) responseMap.get("id"); +// String status = (String) responseMap.get("status"); +//// +// PaymentDTO paymentDTO = new PaymentDTO(paymentId, status); +// Payment payment = paymentMapper.toEntity(paymentDTO); +//// +// paymentService.save(payment); +// +// response.setData(paymentResponse.getBody()); +// +// System.out.println("SATTSUS PAGAMENTO....."); +//// System.out.println(status); +// +// +// return ResponseEntity.ok(response); +// +// +// } catch (Exception e) { +// response.setMessage("Erro ao fazer pagamento. Por favor, tente novamente."); +// return ResponseEntity.status(400).body(response); +// } + + + PaymentResponseDTO payment = paymentService.pay(cardPaymentDTO); + + System.out.println("paymentResponse"); + System.out.println(payment.getStatus()); + System.out.println(payment.getId()); + + if(Objects.equals(payment.getStatus(), "approved")){ + Payment payment1 = new Payment(); + payment1.setStatus(payment.getStatus()); + payment1.setPaymentId(payment.getId()); + paymentService.save(payment1); + } + + return ResponseEntity.status(HttpStatus.CREATED).body(payment); + } + + /** + * Apos processar o pagamento, ele é inserido na tabela payments_jobRequests + * contendo o id do pagamento e do serviço que foi realizado o pagamento. + * Finalizado este processo é preciso gerar um comprovante do pagamento + * tanto para cliente quanto profissional, que sera enviado por email + * **/ + @PostMapping("/pagamento/jobRequest") + @RolesAllowed({RoleType.USER}) + public ModelAndView savePaymentJob(@RequestBody PaymentJobDTO dto, BindingResult errors, RedirectAttributes redirectAttributes) throws ConfigurationException, TranscoderException, IOException, TransformerException, WriterException { + ModelAndView modelAndView = new ModelAndView(); + final Date now = new Date(); + + Optional oPayment = paymentService.findByPaymentId(dto.getPaymentId()); + Optional oJobRequest = jobRequestService.findById(dto.getJobRequestId()); + + PaymentJobRequest paymentJob = new PaymentJobRequest(); + paymentJob.setJobRequestId(dto.getJobRequestId()); + paymentJob.setPayment(oPayment.get()); + paymentJob.setJobRequest(oJobRequest.get()); + paymentJob.setDateCreated(now); + + paymentJobService.save(paymentJob); + + createVoucherPayment(paymentJob); // GERA O COMPROVANTE DE PAGAMENTO + + modelAndView.addObject("mensagem", "Pagamento processado com sucesso!"); + + return modelAndView; + } + + public String createVoucherPayment(PaymentJobRequest paymentJob) throws IOException, TranscoderException, ConfigurationException, TransformerException, WriterException, TransformerException { + /*Busca o job request - cliente*/ + Optional oJobRequest = jobRequestService.findById(paymentJob.getJobRequestId()); + + /*Traz o profissional*/ + Optional oJobContracted = jobContractedService.findByJobRequest(oJobRequest.get()); + + /*Traz o servico*/ + Optional oExpertise = expertiseService.findById(oJobRequest.get().getExpertise().getId()); + + PaymentVoucher paymentVoucher = new PaymentVoucher(); + paymentVoucher.setClient(oJobRequest.get().getUser()); + paymentVoucher.setProfessional(oJobContracted.get().getUser()); + paymentVoucher.setCode(gerarCodigoAlfanumerico()); + paymentVoucher.setJobRequest(oJobRequest.get()); + + String emailProfissional = oJobContracted.get().getUser().getEmail(); + String emailClient = oJobRequest.get().getUser().getEmail(); + + paymentVoucherService.save(paymentVoucher); + Date dataAtual = new Date(); + + // Converter LocalDate para Date + SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(dataAtual); + + // Incrementando 15 dias + calendar.add(Calendar.DATE, 15); + + // Obtendo a nova data após o incremento + Date dataFinal = calendar.getTime(); + SimpleDateFormat sdfNovo = new SimpleDateFormat("dd/MM/yyyy"); + + String client_name = paymentVoucher.getClient().getName(); // NOME DO CLIENTE + String client_fone = paymentVoucher.getClient().getPhoneNumber(); // TELEFONE DO CLIENTE + String client_email = paymentVoucher.getClient().getEmail(); // EMAIL DO CLIENTE + String client_address_name = paymentVoucher.getClient().getAddress().getNeighborhood(); // ENDEREÇO DO CLIENTE + String client_address_number = paymentVoucher.getClient().getAddress().getNumber(); // NUMERO ENDEREÇO DO CLIENTE + String client_address = client_address_name + " - " + client_address_number; // ENDEREÇO DO CLIENTE + + String profes_name = paymentVoucher.getProfessional().getName(); // NOME DO PROFISSIONAL + String profes_fone = paymentVoucher.getProfessional().getPhoneNumber(); // TELEFONE DO PROFISSIONAL + String profes_email = paymentVoucher.getProfessional().getEmail(); // EMAIL DO PROFISSIONAL + String profes_address_name = paymentVoucher.getProfessional().getAddress().getNeighborhood(); // ENDEREÇO DO PROFISSIONAL + String profes_address_number = paymentVoucher.getProfessional().getAddress().getNumber(); // NUMERO ENDEREÇO DO PROFISSIONAL + String profes_address = profes_address_name + " - " + profes_address_number; // ENDEREÇO DO PROFISSIONAL + + String service_name = oJobRequest.get().getExpertise().getName(); + +// Optional optionalProfessionalServiceOffering = professionalServiceOfferingService.findProfessionalServiceOfferingByExpertiseAAndUser(paymentVoucher.getProfessional().getId(), oJobRequest.get().getExpertise().getId()); + Optional optionalProfessionalServiceOffering = professionalServiceOfferingService.findProfessionalServiceOfferingByIdAndUser(oJobRequest.get().getServiceOffering().getId(), paymentVoucher.getProfessional().getId()); + + String value_service = "0,00"; + if (optionalProfessionalServiceOffering.isPresent()){ + value_service = String.valueOf(optionalProfessionalServiceOffering.get().getPrice()); + } + + File pdfFile = paymentVoucherService.generateCertificate(svgCertificateTemplate, paymentVoucher.getCode(),service_name, sdfNovo.format(dataAtual), sdfNovo.format(dataFinal), + client_name, "111111111", client_fone, client_email, profes_name, "10444444440", + profes_email, profes_fone, profes_address, "PIX", value_service, "QRDCOD", sdfNovo.format(dataAtual)); + Map uploadResult = cloudinary.uploader().upload(pdfFile, ObjectUtils.asMap("folder", "certificates")); + + String uploadURL = (String)uploadResult.get("url"); + + //envia um email com a URL do certificado + /*Envio de email para o profissional*/ + quartzService.sendEmailPaymentVoucher(paymentVoucher.getCode(), + oJobRequest.get().getUser().getId(), oJobContracted.get().getUser().getId(), oExpertise.get().getName(), sdf.format(dataFinal), (String)uploadResult.get("url")); + pdfFile.delete(); + +// (url.openStream(), voucher, service,date, date_due,name_client,document_client,fone_client,mail_client,name_professional, document_professional, +// mail_professional, fone_professional, endereco_pro, payment_type, payment_value, qrCode); + + return "redirect:/minha-conta/cliente#executados"; + } + + /* Gera código aleatorico e unico para gravação de comprovante */ + private String gerarCodigoAlfanumerico() { + UUID uuid = UUID.randomUUID(); + String codigo = uuid.toString().replace("-", "").substring(0, 10); + return codigo.toUpperCase(); + } + + /** + * Avalia o serviço depois de finalizado + * @param jobId + * @param redirectAttributes + * @return + * @throws IOException + */ + @GetMapping("/avaliar/servico/{jobId}/profissional/{profissionalId}") + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) + public ModelAndView evaluateService(@PathVariable Long jobId, @PathVariable Long profissionalId, RedirectAttributes redirectAttributes) throws IOException { + Optional oClientAuthenticated = (userService.findByEmail(authentication.getEmail())); + ModelAndView mv = new ModelAndView("client/evaluate-jobs"); + + if(!oClientAuthenticated.isPresent()){ + return mv.addObject("visitor/login"); + } + + Optional oJobRequest = jobRequestService.findById(jobId); + + Optional oIndividual = userService.findById(profissionalId); + + System.out.println("INDIVIDUAL"); + System.out.println(oIndividual.get().getName()); + + Optional oJobContracted = jobContractedService.findByJobRequest(oJobRequest.get()); + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + + + mv.addObject("job", oJobRequest.get()); + mv.addObject("professional", oIndividual.get()); + mv.addObject("jobContracted", oJobContracted.get()); + mv.addObject("hiredDate", dateTimeFormatter.format(oJobContracted.get().getHiredDate())); + mv.addObject("finishDate", dateTimeFormatter.format(oJobContracted.get().getFinishDate())); + + return mv; + } + + /** + * @param jobId + * @param profissionalId + * @param dto + * @param redirectAttributes + * @return + * @throws IOException + * @throws ParseException + */ + @PostMapping("/avaliar/servico/{jobId}/profissional/{profissionalId}") + @RolesAllowed({RoleType.USER}) + public ModelAndView saveAssessmentProfessional( + @PathVariable Long profissionalId, + @PathVariable Long jobId, + AssessmentProfessionalDTO dto, + AssessmentProfessionalFileDTO assessmentProfessionalFileDTO, + @RequestParam("pathImage") MultipartFile file, + RedirectAttributes redirectAttributes, + BindingResult errors + ) throws IOException, ParseException { + String currentUserEmail = authentication.getEmail(); + + Optional oindividual = individualService.findById(profissionalId); + Optional oClliente = individualService.findByEmail(currentUserEmail); + + if(!oindividual.isPresent()){ + throw new EntityNotFoundException("O usuário não foi encontrado!"); + } + + Optional oJobRequest = jobRequestService.findById(jobId); + + AssessmentProfessional assessmentProfessional = new AssessmentProfessional(); + String comment = dto.getComment(); + + if (!comment.isEmpty()){ + String analyzedComment = analyzeComment(comment); + if ("Comentário Ofensivo".equals(analyzedComment)) { + errors.rejectValue("comment", "error.dto", "Proibido comentários ofensivos!."); + return errorFowarding(dto, assessmentProfessionalFileDTO, errors); + } + } + + assessmentProfessional.setComment(dto.getComment()); + assessmentProfessional.setProfessional(oindividual.get()); + assessmentProfessional.setQuality(dto.getQuality()); + assessmentProfessional.setDate(DateUtil.getToday()); + + assessmentProfessional.setClient(oClliente.get()); + assessmentProfessional.setJobRequest(oJobRequest.get()); + assessmentProfessionalService.save(assessmentProfessional); + + if (!assessmentProfessionalFileDTO.getPathImage().isEmpty() ) { + Map uploadResult = cloudinary.uploader().upload(file.getBytes(), ObjectUtils.emptyMap()); + + String imageUrl = (String) uploadResult.get("url"); + + if(moderateService.isNsfwImage(imageUrl)){ + String publicId = (String) uploadResult.get("public_id"); + cloudinary.uploader().destroy(publicId, ObjectUtils.emptyMap()); + redirectAttributes.addFlashAttribute("msgError", "A imagem enviada contém conteúdo impróprio. Por favor, envie outra foto."); + return new ModelAndView("redirect:/minha-conta/cliente/avaliar/servico/"+jobId+"/profissional/"+profissionalId); + } + +// AssessmentProfessionalFiles assessmentProfessionalFiles = assessmentProfessionalFileMapper.toEntity(assessmentProfessionalFileDTO); +// assessmentProfessionalFiles.setAssessmentProfessional(assessmentProfessional); + AssessmentProfessionalFiles assessmentProfessionalFiles1 = new AssessmentProfessionalFiles(); + assessmentProfessionalFiles1.setPathImage(imageUrl); + assessmentProfessionalFiles1.setAssessmentProfessional(assessmentProfessional); + assessmentProfessionalFileService.save(assessmentProfessionalFiles1); + } + + redirectAttributes.addFlashAttribute("msg", "Avaliação realizada com sucesso!"); + + return new ModelAndView("redirect:/minha-conta/cliente#executados"); + } + + public boolean isValidateImage(MultipartFile image){ + List contentTypes = Arrays.asList("image/png", "image/jpg", "image/jpeg"); + + for(int i = 0; i < contentTypes.size(); i++){ + if(image.getContentType().toLowerCase().startsWith(contentTypes.get(i))){ + return true; + } + } + + return false; + } + + /*Método responsavel em chamar a api e então validar comentários*/ + @GetMapping("/analyze-comment") + public String analyzeComment(String coment){ + return perspectiveAPIService.analyzeComment(coment); + } + + private ModelAndView errorFowarding(AssessmentProfessionalDTO dto, AssessmentProfessionalFileDTO dtoFiles,BindingResult errors) { + ModelAndView mv = new ModelAndView("client/evaluate-jobs"); + mv.addObject("dto", dto); + mv.addObject("errors", errors.getAllErrors()); + return mv; + } + + private ModelAndView errorFowardingResponse(AssessmentResponseDTO dto,BindingResult errors) { + ModelAndView mv = new ModelAndView("professional/detail-service"); + mv.addObject("dto", dto); + mv.addObject("errors", errors.getAllErrors()); + return mv; + } + + /** + * @param profissionalId + * @param dto + * @param redirectAttributes + * @return + * @throws IOException + * @throws ParseException + */ + @PostMapping("/contratar-servico/profissional/{profissionalId}") + @RolesAllowed({RoleType.USER}) + public ModelAndView saveContratedServiceProfessional( + JobRequestDTO dto, + RedirectAttributes redirectAttributes, + @PathVariable Long profissionalId, + BindingResult errors + ) throws IOException, ParseException { + String currentUserEmail = authentication.getEmail(); + + System.out.println(dto); + + Optional oCliente = individualService.findByEmail(currentUserEmail); + + if(!oCliente.isPresent()){ + throw new EntityNotFoundException("O usuário não foi encontrado!"); + } + + Optional oExpertise = expertiseService.findById(dto.getExpertiseId()); + + if(!oExpertise.isPresent()){ + throw new EntityNotFoundException("Especialidade não foi encontrada!"); + } + + JobRequest jobRequest = new JobRequest(); + jobRequest.setExpertise(oExpertise.get()); + jobRequest.setUser(oCliente.get()); + jobRequest.setClientConfirmation(true); + jobRequest.setQuantityCandidatorsMax(1); + jobRequest.setDateCreated(LocalDate.now()); + jobRequest.setDateTarget(DateUtil.getThisMonth()); // para este mês + jobRequest.setDescription(oExpertise.get().getDescription()); + jobRequest.setProfessionalConfirmation(true); + jobRequest.setStatus(JobRequest.Status.TO_DO); + + Optional oUser = userService.findById(profissionalId); + + Optional oProfessionalServiceOffering = professionalServiceOfferingService.findById(dto.getProfessionalServiceOfferingId()); + if(!oProfessionalServiceOffering.isPresent()){ + throw new EntityNotFoundException("Serviço do profissional não foi encontrada!"); + } + jobRequest.setServiceOffering(oProfessionalServiceOffering.get()); + + jobRequestService.save(jobRequest); + + JobCandidate jobCandidate = new JobCandidate(jobRequest, oUser.get()); + jobCandidateService.save(jobCandidate); + + if(!oUser.isPresent()){ + throw new EntityNotFoundException("Profissional não foi encontrado!"); + } + + JobContracted jobContracted = new JobContracted(); + jobContracted.setJobRequest(jobRequest); + jobContracted.setUser(oUser.get()); + jobContracted.setHiredDate(LocalDate.now()); + + jobContractedService.save(jobContracted); + + jobRequest.setStatus(JobRequest.Status.TO_DO); + jobRequestService.save(jobRequest); + + redirectAttributes.addFlashAttribute("msg", "Pedido foi enviado, o profissional receberá uma notificação!!"); + + return new ModelAndView("redirect:/minha-conta/cliente#paraFazer"); + } } \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/CompanyProfessionalController.java b/src/main/java/br/edu/utfpr/servicebook/controller/CompanyProfessionalController.java new file mode 100644 index 00000000..ca0c3b45 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/controller/CompanyProfessionalController.java @@ -0,0 +1,264 @@ +package br.edu.utfpr.servicebook.controller; + +import br.edu.utfpr.servicebook.model.dto.*; +import br.edu.utfpr.servicebook.model.entity.*; +import br.edu.utfpr.servicebook.model.mapper.*; +import br.edu.utfpr.servicebook.model.repository.UserRepository; +import br.edu.utfpr.servicebook.security.IAuthentication; +import br.edu.utfpr.servicebook.security.RoleType; +import br.edu.utfpr.servicebook.service.*; +import br.edu.utfpr.servicebook.sse.EventSSE; +import br.edu.utfpr.servicebook.sse.EventSSEDTO; +import br.edu.utfpr.servicebook.sse.EventSseMapper; +import br.edu.utfpr.servicebook.sse.SSEService; +import br.edu.utfpr.servicebook.util.TemplateUtil; +import br.edu.utfpr.servicebook.util.UserTemplateInfo; +import br.edu.utfpr.servicebook.util.UserTemplateStatisticInfo; +import com.cloudinary.utils.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import javax.annotation.security.RolesAllowed; +import javax.persistence.EntityNotFoundException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import javax.validation.Valid; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; +@RequestMapping("/minha-conta/empresa/profissionais") +@Controller +public class CompanyProfessionalController { + public static final Logger log = LoggerFactory.getLogger(CompanyProfessionalController.class); + @Autowired + private UserService userService; + + @Autowired + private CompanyProfessionalService companyProfessionalService; + + @Autowired + private IAuthentication authentication; + + @Autowired + private UserMapper userMapper; + + @Autowired + private CompanyProfessionalMapper companyProfessionalMapper; + + @Autowired + private TemplateUtil templateUtil; + + @Autowired + private UserRepository userRepository; + + @Autowired + private QuartzService quartzService; + + @Autowired + private UserCodeMapper userCodeMapper; + + @Autowired + private UserCodeService userCodeService; + + @Autowired + private UserTokenMapper userTokenMapper; + + @Autowired + private UserTokenService userTokenService; + + @Autowired + private StateService stateService; + + @Autowired + private SSEService sseService; + + @Autowired + private EventSseMapper eventSseMapper; + @Autowired + private ProfessionalExpertiseService professionalExpertiseService; + @Autowired + private ExpertiseService expertiseService; + + @Autowired + private ExpertiseMapper expertiseMapper; + + /** + * Apresenta a tela para a empresa adicionar profissionais. + * @param expertiseId + * @return + * @throws Exception + */ + @GetMapping() + @RolesAllowed({RoleType.COMPANY}) + public ModelAndView showProfessionals(@RequestParam(required = false, defaultValue = "0") Optional expertiseId) throws Exception { + + User company = this.getCompany(); + UserDTO professionalMinDTO = userMapper.toDto(company); + + ModelAndView mv = new ModelAndView("company/new-professional"); + + UserTemplateInfo userTemplateInfo = templateUtil.getUserInfo(professionalMinDTO); + UserTemplateStatisticInfo sidePanelStatisticDTO = templateUtil.getCompanyStatisticInfo(company, expertiseId.get()); + + mv.addObject("statisticInfo", sidePanelStatisticDTO); + + mv.addObject("id", expertiseId.orElse(0L)); + + List professionals = userService.findProfessionalsNotExist(); + + List companyProfessionals = companyProfessionalService.findByCompany(company.getId()); + + List companyProfessionalDTO2s = companyProfessionals.stream() + .map(s -> companyProfessionalMapper.toResponseDTO(s)) + .collect(Collectors.toList()); + + Optional oProfessional = (userService.findByEmail(authentication.getEmail())); + + UserTemplateInfo individualInfo = templateUtil.getUserInfo(professionalMinDTO); + + //envia a notificação ao usuário + List eventSsesList = sseService.findPendingEventsByEmail(authentication.getEmail()); + List eventSSEDTOs = eventSsesList.stream() + .map(eventSse -> { + return eventSseMapper.toFullDto(eventSse); + }) + .collect(Collectors.toList()); + List professionalExpertises = professionalExpertiseService.findByProfessional(oProfessional.get()); + + List expertiseDTOs = professionalExpertises.stream() + .map(professionalExpertise -> professionalExpertise.getExpertise()) + .map(expertise -> expertiseMapper.toDto(expertise)) + .collect(Collectors.toList()); + + + mv.addObject("professionals", professionals); + mv.addObject("professionalCompanies", companyProfessionalDTO2s); + mv.addObject("statisticInfo", sidePanelStatisticDTO); + mv.addObject("eventsse", eventSSEDTOs); + mv.addObject("expertises", expertiseDTOs); + mv.addObject("company", true); + + return mv; + } + + @PostMapping() + @RolesAllowed({RoleType.COMPANY}) + public ModelAndView saveProfessionals(@Valid CompanyProfessionalDTO dto, BindingResult errors, RedirectAttributes redirectAttributes) throws Exception { + + ModelAndView mv = new ModelAndView("redirect:profissionais"); + String ids = dto.getIds(); + User company = this.getCompany(); + Optional company_name = userService.findById(company.getId()); + Optional oCompany = (userService.findByEmail(authentication.getEmail())); + + Optional oProfessional = userService.findByEmail(ids); + if(!oProfessional.isPresent()){ + Random random = new Random(); + int numberRandom = random.nextInt(100 - 1) + 1; + + String token = "RP0"+company.getId()+numberRandom; + UserTokenDTO userTokenDTO = new UserTokenDTO(); + userTokenDTO.setUser(company); + userTokenDTO.setEmail(ids); + userTokenDTO.setToken(token); + UserToken userToken = userTokenMapper.toEntity(userTokenDTO); + + userTokenService.save(userToken); + + String tokenLink = ServletUriComponentsBuilder.fromCurrentContextPath().build().toString() + + "/cadastrar-se?passo-1&code="+token; + + quartzService.sendEmailToRegisterUser(dto.getIds(), company.getName(), tokenLink); + + CompanyProfessional p = companyProfessionalService.save(new CompanyProfessional(company, dto.getIds())); + + redirectAttributes.addFlashAttribute("msg", "Convite enviado para usuário, aguardando confirmação!"); + + } else { + String tokenLink = ServletUriComponentsBuilder.fromCurrentContextPath().build().toString() + "/minha-conta/empresa/profissionais/confirmar/" + company_name.get().getId() +"/" + dto.getIds(); + quartzService.sendEmailWithConfirmationUser(dto.getIds(), company.getName(), tokenLink); + + Optional optionalCompanyProfessional = companyProfessionalService.findByCompanyAndProfessional(company, oProfessional.get()); + + + if(!optionalCompanyProfessional.isPresent()){ + + CompanyProfessional p = companyProfessionalService.save(new CompanyProfessional(company, dto.getIds(), oProfessional.get())); + + redirectAttributes.addFlashAttribute("msg", "Convite enviado para usuário, aguardando confirmação!"); + } else { + redirectAttributes.addFlashAttribute("msg", "Usuário ja está na empresa!"); + } + } + return mv; + } + + @DeleteMapping("/{id}") + @RolesAllowed({RoleType.COMPANY}) + @Transactional + public String delete(@PathVariable User id, RedirectAttributes redirectAttributes) throws Exception { + User company = this.getCompany(); + Optional oProfessional = userService.findById(id.getId()); + + Optional optionalCompanyProfessional = companyProfessionalService.findByCompanyAndProfessional(company, oProfessional.get()); + + if (optionalCompanyProfessional.get().getProfessional().getId().equals(id.getId())) { + this.companyProfessionalService.delete(optionalCompanyProfessional.get().getId()); + } + return "redirect:/minha-conta/empresa/profissionais"; + } + + /** + * Retorna a empresa logado. + * @return + * @throws Exception + */ + private User getCompany() throws Exception { + Optional oCompany = (userService.findByEmail(authentication.getEmail())); + + if (!oCompany.isPresent()) { + throw new Exception("Opss! Não foi possivel encontrar seus dados, tente fazer login novamente"); + } + + return oCompany.get(); + } + + @GetMapping("/confirmar/{companyId}/{email}") + @RolesAllowed({RoleType.COMPANY, RoleType.USER}) + public String includeProfessionals(@PathVariable Long companyId, @PathVariable String email, HttpServletRequest request, RedirectAttributes redirectAttributes) throws + IOException { + + Optional oProfessional = userService.findByEmail(email); + Optional oCompany = userService.findById(companyId); + if(!oProfessional.isPresent()){ + throw new EntityNotFoundException("Profissional não encontrado pelo id informado."); + } + + if(!oCompany.isPresent()){ + throw new EntityNotFoundException("Empresa não encontrada pelo id informado."); + } + Optional oCompanyProfessional = companyProfessionalService.findByCompanyAndProfessional(oCompany.get(), oProfessional.get()); + + if(!oCompanyProfessional.isPresent()){ + throw new EntityNotFoundException("Profissional não encontrado na empresa."); + } + + CompanyProfessional companyProfessional = oCompanyProfessional.get(); + + companyProfessional.setConfirmed(true); + companyProfessionalService.save(companyProfessional); + + return "redirect:/login"; + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/IndexController.java b/src/main/java/br/edu/utfpr/servicebook/controller/IndexController.java index e1c2b3bd..49b3bd06 100644 --- a/src/main/java/br/edu/utfpr/servicebook/controller/IndexController.java +++ b/src/main/java/br/edu/utfpr/servicebook/controller/IndexController.java @@ -1,7 +1,13 @@ package br.edu.utfpr.servicebook.controller; +import br.edu.utfpr.servicebook.model.dto.CategoryDTO; +import br.edu.utfpr.servicebook.model.dto.ExpertiseDTO; import br.edu.utfpr.servicebook.model.dto.JobRequestFullDTO; +import br.edu.utfpr.servicebook.model.dto.ServiceDTO; import br.edu.utfpr.servicebook.model.entity.*; +import br.edu.utfpr.servicebook.model.mapper.CategoryMapper; +import br.edu.utfpr.servicebook.model.mapper.ExpertiseMapper; +import br.edu.utfpr.servicebook.model.mapper.ServiceMapper; import br.edu.utfpr.servicebook.security.IAuthentication; import br.edu.utfpr.servicebook.security.RoleType; import br.edu.utfpr.servicebook.service.*; @@ -15,20 +21,20 @@ import org.springframework.data.domain.Page; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.annotation.security.PermitAll; import javax.annotation.security.RolesAllowed; +import javax.persistence.EntityNotFoundException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; @RequestMapping("/") @Controller @@ -61,6 +67,20 @@ public class IndexController { @Autowired private HttpSession httpSession; + @Autowired + private CategoryService categoryService; + + @Autowired + private CategoryMapper categoryMapper; + + @Autowired + private ExpertiseMapper expertiseMapper; + + @Autowired + private ServiceService serviceService; + + @Autowired + private ServiceMapper serviceMapper; @GetMapping @PermitAll public ModelAndView showIndexPage(HttpServletResponse response) { @@ -81,6 +101,11 @@ public ModelAndView showIndexPage(HttpServletResponse response) { return new ModelAndView("redirect:/minha-conta/empresa/disponiveis"); } } + //lista de categorias + List categories = categoryService.findAll(); + List categoryDTOs = categories.stream() + .map(s -> categoryMapper.toDto(s)) + .collect(Collectors.toList()); List cities = cityService.findAll(); mv.addObject("cities", cities); @@ -90,6 +115,7 @@ public ModelAndView showIndexPage(HttpServletResponse response) { mv.addObject("totalJobContracted", jobContractedService.countAll()); mv.addObject("totalProfessionals", userService.countProfessionals()); mv.addObject("totalClients", userService.countUsersWithoutExpertise()); + mv.addObject("categories", categoryDTOs); return mv; } @@ -101,8 +127,6 @@ public String showClientPage(HttpSession httpSession, RedirectAttributes redirec return "redirect:/"; } - - @GetMapping("/bem-vindo") @PermitAll public ModelAndView showWelcomePage() { @@ -122,4 +146,53 @@ public String notAuthorized() { return "error/not-authorized"; } + @GetMapping("/especialidades/categoria/{categoryId}") + @PermitAll + @ResponseBody + public List showExpertisesByCategory(@PathVariable Long categoryId) throws Exception { + if(categoryId != null){ + List expertises = expertiseService.findByCategoryId(categoryId); + + List expertiseDTOS = expertises.stream() + .map(s -> expertiseMapper.toDto(s)) + .collect(Collectors.toList()); + + return expertiseDTOS; + } else { + List expertises = expertiseService.findAll(); + + List expertiseDTOS = expertises.stream() + .map(s -> expertiseMapper.toDto(s)) + .collect(Collectors.toList()); + + return expertiseDTOS; + } + + } + + @GetMapping("/servicos/especialidade/{expertiseId}") + @PermitAll + @ResponseBody + public List showServicesByExpertise(@PathVariable Long expertiseId) throws Exception { + if(expertiseId != null){ + Expertise expertise = expertiseService.findById(expertiseId).orElseThrow(() -> new EntityNotFoundException("Especialidade não encontrada")); + + List services = serviceService.findByExpertise(expertise); + + List servicesDTO = services.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); + return servicesDTO; + + } else { + List services = serviceService.findAll(); + + List servicesDTO = services.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); + + return servicesDTO; + } + + } } \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/JobContractedController.java b/src/main/java/br/edu/utfpr/servicebook/controller/JobContractedController.java index 4ff0414e..021be80a 100644 --- a/src/main/java/br/edu/utfpr/servicebook/controller/JobContractedController.java +++ b/src/main/java/br/edu/utfpr/servicebook/controller/JobContractedController.java @@ -104,13 +104,13 @@ public String markAsToDo( JobContracted jobContracted = oJobContracted.get(); if (dto.isConfirm()) { - DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); JobRequest jobRequest = jobContracted.getJobRequest(); jobRequest.setStatus(JobRequest.Status.TO_DO); jobRequestService.save(jobRequest); - jobContracted.setTodoDate(LocalDate.parse(dto.getTodoDate(), dateTimeFormatter)); +// jobContracted.setTodoDate(LocalDate.parse(dto.getTodoDate(), dateTimeFormatter)); + jobContracted.setTodoDate(LocalDate.parse(dto.getTodoDate())); jobContractedService.save(jobContracted); } else { JobRequest jobRequest = jobContracted.getJobRequest(); diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/JobRequestController.java b/src/main/java/br/edu/utfpr/servicebook/controller/JobRequestController.java index 00f8f6b7..fb0fa337 100644 --- a/src/main/java/br/edu/utfpr/servicebook/controller/JobRequestController.java +++ b/src/main/java/br/edu/utfpr/servicebook/controller/JobRequestController.java @@ -22,6 +22,7 @@ import com.cloudinary.utils.ObjectUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; @@ -97,16 +98,16 @@ public class JobRequestController { private TemplateUtil templateUtil; - public enum RequestDateSelect{ - today(0), tomorrow(1) , thisweek(2), nextweek(3), thismonth(4), nextmonth(5); + public enum RequestDateSelect { + today(0), tomorrow(1), thisweek(2), nextweek(3), thismonth(4), nextmonth(5); private int value; - RequestDateSelect(int value){ + RequestDateSelect(int value) { this.value = value; } - public int getValue(){ + public int getValue() { return value; } @@ -115,16 +116,30 @@ public int getValue(){ @GetMapping @PermitAll public String showWizard(@RequestParam(value = "passo", required = false, defaultValue = "1") Long step, + @RequestParam(value = "especialidade", required = false, defaultValue = "0") Long expertiseId, HttpSession httpSession, Model model) throws Exception { log.debug("Mostrando o passo {}", step); - if(step < 1 || step > 8){ + if (step < 1 || step > 5) { step = 1L; } + + String currentUserEmail = authentication.getEmail(); + + Optional oUser = userService.findByEmail(currentUserEmail); +// if (!oUser.isPresent()) { +// return "redirect:/login"; +// } + JobRequestDTO dto = wizardSessionUtil.getWizardState(httpSession, JobRequestDTO.class, WizardSessionUtil.KEY_WIZARD_JOB_REQUEST); model.addAttribute("dto", dto); - if(step == 1L){ + if (expertiseId != 0) { + JobRequestDTO sessionDTO = wizardSessionUtil.getWizardState(httpSession, JobRequestDTO.class, WizardSessionUtil.KEY_WIZARD_JOB_REQUEST); + sessionDTO.setExpertiseId(expertiseId); + } + + if (step == 1L) { List expertise = expertiseService.findAll(); List expertiseDTOs = expertise.stream() .map(u -> expertiseMapper.toDto(u)) @@ -140,14 +155,14 @@ public String showWizard(@RequestParam(value = "passo", required = false, defaul public String saveFormRequestedJob(HttpSession httpSession, @Validated(JobRequestDTO.RequestExpertiseGroupValidation.class) JobRequestDTO dto, BindingResult errors, RedirectAttributes redirectAttributes, Model model) throws Exception { Optional oExpertise = null; - if(dto.getExpertiseId() != null) { + if (dto.getExpertiseId() != null) { oExpertise = expertiseService.findById(dto.getExpertiseId()); if (!oExpertise.isPresent()) { - errors.rejectValue("expertiseId","error.dto","Especialidade não encontrada! Por favor, selecione uma especialidade profissional."); + errors.rejectValue("expertiseId", "error.dto", "Especialidade não encontrada! Por favor, selecione uma especialidade profissional."); } } - if(errors.hasErrors()){ + if (errors.hasErrors()) { model.addAttribute("dto", dto); model.addAttribute("errors", errors.getAllErrors()); @@ -173,8 +188,7 @@ public String saveFormRequestedJob(HttpSession httpSession, @Validated(JobReques @PermitAll public String saveFormDateJob(HttpSession httpSession, @Validated(JobRequestDTO.RequestExpirationGroupValidation.class) JobRequestDTO dto, BindingResult errors, RedirectAttributes redirectAttributes, Model model) throws Exception { - - if(errors.hasErrors()){ + if (errors.hasErrors()) { model.addAttribute("dto", dto); model.addAttribute("errors", errors.getAllErrors()); log.debug("Passo 2 {}", dto); @@ -184,32 +198,32 @@ public String saveFormDateJob(HttpSession httpSession, @Validated(JobRequestDTO. } JobRequestDTO sessionDTO = wizardSessionUtil.getWizardState(httpSession, JobRequestDTO.class, WizardSessionUtil.KEY_WIZARD_JOB_REQUEST); System.out.println("dto.getDateProximity()" + dto.getDateProximity()); - if(dto.getDateProximity() == RequestDateSelect.today.value){ + if (dto.getDateProximity() == RequestDateSelect.today.value) { //Hoje log.debug("HOJE: {}", sessionDTO); sessionDTO.setDateTarget(DateUtil.getToday()); } - if(dto.getDateProximity() == RequestDateSelect.tomorrow.value){ + if (dto.getDateProximity() == RequestDateSelect.tomorrow.value) { //Amanhã log.debug("Amanhã: {}", sessionDTO); sessionDTO.setDateTarget(DateUtil.getTomorrow()); } - if(dto.getDateProximity() == RequestDateSelect.thisweek.value){ + if (dto.getDateProximity() == RequestDateSelect.thisweek.value) { //Esta Semana log.debug("Esta Semana: {}", sessionDTO); sessionDTO.setDateTarget(DateUtil.getThisWeek()); } - if(dto.getDateProximity() == RequestDateSelect.nextweek.value){ + if (dto.getDateProximity() == RequestDateSelect.nextweek.value) { //Proxima Semana log.debug("Proxima Semana: {}", sessionDTO); sessionDTO.setDateTarget(DateUtil.getNextWeek()); } - if(dto.getDateProximity() == RequestDateSelect.thismonth.value){ + if (dto.getDateProximity() == RequestDateSelect.thismonth.value) { //Este Mês log.debug("Este Mês: {}", sessionDTO); sessionDTO.setDateTarget(DateUtil.getThisMonth()); } - if(dto.getDateProximity() == RequestDateSelect.nextmonth.value){ + if (dto.getDateProximity() == RequestDateSelect.nextmonth.value) { //Proximo Mes log.debug("Proximo Mês: {}", sessionDTO); sessionDTO.setDateTarget(DateUtil.getNextMonth()); @@ -219,52 +233,53 @@ public String saveFormDateJob(HttpSession httpSession, @Validated(JobRequestDTO. return "redirect:/requisicoes?passo=3"; } - @PostMapping("/passo-3") - @PermitAll - public String saveFormMaxCandidates(HttpSession httpSession, @Validated(JobRequestDTO.RequestMaxCandidatesGroupValidation.class) JobRequestDTO dto, BindingResult errors, RedirectAttributes redirectAttributes, Model model) throws Exception { - if(errors.hasErrors()){ - model.addAttribute("dto", dto); - model.addAttribute("errors", errors.getAllErrors()); - - log.debug("Passo 3 {}", dto); - log.debug("Errors 3 {}", errors); - return "client/job-request/wizard-step-03"; - - } - JobRequestDTO sessionDTO = wizardSessionUtil.getWizardState(httpSession, JobRequestDTO.class, WizardSessionUtil.KEY_WIZARD_JOB_REQUEST); - sessionDTO.setQuantityCandidatorsMax(dto.getQuantityCandidatorsMax()); - - log.debug("Passo 3 {}", sessionDTO); - return "redirect:/requisicoes?passo=4"; - - } +// @PostMapping("/passo-3") +// @PermitAll +// public String saveFormMaxCandidates(HttpSession httpSession, @Validated(JobRequestDTO.RequestMaxCandidatesGroupValidation.class) JobRequestDTO dto, BindingResult errors, RedirectAttributes redirectAttributes, Model model) throws Exception { +// if(errors.hasErrors()){ +// model.addAttribute("dto", dto); +// model.addAttribute("errors", errors.getAllErrors()); +// +// log.debug("Passo 3 {}", dto); +// log.debug("Errors 3 {}", errors); +// return "client/job-request/wizard-step-03"; +// +// } +// JobRequestDTO sessionDTO = wizardSessionUtil.getWizardState(httpSession, JobRequestDTO.class, WizardSessionUtil.KEY_WIZARD_JOB_REQUEST); +// sessionDTO.setQuantityCandidatorsMax(dto.getQuantityCandidatorsMax()); +// +// log.debug("Passo 3 {}", sessionDTO); +// return "redirect:/requisicoes?passo=4"; +// +// } - @PostMapping("/passo-4") + @PostMapping("/passo-3") @PermitAll public String saveFormDescription(HttpSession httpSession, @Validated(JobRequestDTO.RequestDescriptionGroupValidation.class) JobRequestDTO dto, BindingResult errors, RedirectAttributes redirectAttributes, Model model) throws Exception { - - if(errors.hasErrors()){ + if (errors.hasErrors()) { model.addAttribute("dto", dto); model.addAttribute("errors", errors.getAllErrors()); log.debug("Passo 4 {}", dto); log.debug("Errors 4 {}", errors); - return "client/job-request/wizard-step-04"; + return "client/job-request/wizard-step-03"; } JobRequestDTO sessionDTO = wizardSessionUtil.getWizardState(httpSession, JobRequestDTO.class, WizardSessionUtil.KEY_WIZARD_JOB_REQUEST); sessionDTO.setDescription(dto.getDescription()); + sessionDTO.setQuantityCandidatorsMax(5); // valor padrão log.debug("Passo 4 {}", sessionDTO); - return "redirect:/requisicoes?passo=5"; + return "redirect:/requisicoes?passo=4"; } /** * Cadastra várias imagens, mas um POST para cada imagem. * Para cadastrar várias imagens, é necessário fazer um POST para cada imagem. + * * @param httpSession * @param redirectAttributes * @param dto @@ -272,28 +287,58 @@ public String saveFormDescription(HttpSession httpSession, @Validated(JobRequest * @return * @throws IOException */ - @PostMapping("/passo-5") + @PostMapping("/passo-4") @PermitAll public String saveFormImagePath(HttpSession httpSession, RedirectAttributes redirectAttributes, JobRequestDTO dto, Model model) throws IOException { - //persiste na sessão JobRequestDTO sessionDTO = wizardSessionUtil.getWizardState(httpSession, JobRequestDTO.class, WizardSessionUtil.KEY_WIZARD_JOB_REQUEST); sessionDTO.setImageFile(dto.getImageFile()); + Optional oExpertise = expertiseService.findById(sessionDTO.getExpertiseId()); + + if (!oExpertise.isPresent()) { + throw new InvalidParamsException("A especilidade informada não foi encontrada!"); + } - System.out.println(sessionDTO.getExpertiseId()); + /* Verifica se o usuário está logado, pois pode submeter um anuncio sem estar logado. */ + User user = null; + Optional oUser = userService.findByEmail(authentication.getEmail()); + if (oUser.isPresent()) { + user = oUser.get(); + } - if(isValidateImage(dto.getImageFile())){ + if (isValidateImage(dto.getImageFile())) { File jobImage = Files.createTempFile("temp", dto.getImageFile().getOriginalFilename()).toFile(); dto.getImageFile().transferTo(jobImage); Map data = cloudinary.uploader().upload(jobImage, ObjectUtils.asMap("folder", "jobs")); + sessionDTO.setImageSession((String) data.get("url")); + + Expertise exp = oExpertise.get(); + sessionDTO.setClientConfirmation(true); + sessionDTO.setDateCreated(DateUtil.getToday()); + sessionDTO.setStatus(JobRequest.Status.AVAILABLE.toString()); + + log.debug("Passo 7 {}", sessionDTO); + JobRequest jobRequest = jobRequestMapper.toEntity(sessionDTO); + jobRequest.setExpertise(exp); + jobRequest.setUser(user); + + //jobRequest.setImage(sessionDTO.getImageSession()); + jobRequestService.save(jobRequest); + //envia a notificação SSE + if (jobRequest.getUser() != null) { + EventSSE eventSse = new EventSSE(EventSSE.Status.JOB_CONFIRMED, jobRequest.getDescription().toString(), user.getName(), jobRequest.getUser().getName(), jobRequest.getUser().getEmail()); + sseService.send(eventSse); + System.out.println("Push: " + eventSse.getMessage()); + } + + redirectAttributes.addFlashAttribute("msg", "Requisição confirmada!"); - sessionDTO.setImageSession((String)data.get("url")); - log.debug("Passo 5 {}", sessionDTO); +// return "redirect:/requisicoes?passo=7"; + return "redirect:/requisicoes/passo-5"; - return "redirect:/requisicoes/passo=5"; } else { - return "redirect:/requisicoes/passo=5"; + return "redirect:/requisicoes/passo=4"; } } @@ -315,6 +360,7 @@ public String saveFormImagePath(HttpSession httpSession, RedirectAttributes redi /** * Salva a requisição + * * @param httpSession * @param dto * @param redirectAttributes @@ -323,20 +369,20 @@ public String saveFormImagePath(HttpSession httpSession, RedirectAttributes redi */ @PostMapping("/passo-7") @PermitAll - public String saveFormVerification(HttpSession httpSession, JobRequestDTO dto, RedirectAttributes redirectAttributes, Model model){ + public String saveFormVerification(HttpSession httpSession, JobRequestDTO dto, RedirectAttributes redirectAttributes, Model model) { JobRequestDTO sessionDTO = wizardSessionUtil.getWizardState(httpSession, JobRequestDTO.class, WizardSessionUtil.KEY_WIZARD_JOB_REQUEST); Optional oExpertise = expertiseService.findById(sessionDTO.getExpertiseId()); - if(!oExpertise.isPresent()){ + if (!oExpertise.isPresent()) { throw new InvalidParamsException("A especilidade informada não foi encontrada!"); } /* Verifica se o usuário está logado, pois pode submeter um anuncio sem estar logado. */ User user = null; Optional oUser = userService.findByEmail(authentication.getEmail()); - if(oUser.isPresent()){ - user = oUser.get(); + if (oUser.isPresent()) { + user = oUser.get(); } Expertise exp = oExpertise.get(); @@ -357,21 +403,23 @@ public String saveFormVerification(HttpSession httpSession, JobRequestDTO dto, R System.out.println("Push: " + eventSse.getMessage()); redirectAttributes.addFlashAttribute("msg", "Requisição confirmada!"); - return "redirect:/requisicoes/passo-8"; + return "redirect:/requisicoes/passo-5"; } /** * Mostra os profissionais resultado da busca + * * @param httpSession * @return */ - @GetMapping("/passo-8") + @GetMapping("/passo-5") @PermitAll protected ModelAndView showProfessionals(HttpSession httpSession) { - ModelAndView mv = new ModelAndView("client/job-request/wizard-step-08"); + ModelAndView mv = new ModelAndView("client/job-request/wizard-step-05"); JobRequestDTO sessionDTO = wizardSessionUtil.getWizardState(httpSession, JobRequestDTO.class, WizardSessionUtil.KEY_WIZARD_JOB_REQUEST); - + System.out.println("toto"); + System.out.println(sessionDTO); Optional expertise = expertiseService.findById(sessionDTO.getExpertiseId()); List professionals = individualService.findDistinctByTermIgnoreCase(expertise.get().getName()); @@ -380,9 +428,6 @@ protected ModelAndView showProfessionals(HttpSession httpSession) { .map(s -> individualMapper.toSearchItemDto(s, individualService.getExpertises(s))) .collect(Collectors.toList()); - - - mv.addObject("professionals", professionalSearchItemDTOS); mv.addObject("professionalsAmount", professionalSearchItemDTOS.size()); @@ -397,6 +442,7 @@ protected ModelAndView showProfessionals(HttpSession httpSession) { * depois que realizao login na aplicação. * Esta requisição de serviço é pega da sessão e então, é salva no BD e o usuário é encaminhado para este endereço. * TODO apresentar uma mensagem de erro genérica no JSP caso error seja true + * * @return */ // @GetMapping("pedido-recebido") @@ -415,12 +461,11 @@ protected ModelAndView showProfessionals(HttpSession httpSession) { // // return mv; // } - - public boolean isValidateImage(MultipartFile image){ + public boolean isValidateImage(MultipartFile image) { List contentTypes = Arrays.asList("image/png", "image/jpg", "image/jpeg"); - for(int i = 0; i < contentTypes.size(); i++){ - if(image.getContentType().toLowerCase().startsWith(contentTypes.get(i))){ + for (int i = 0; i < contentTypes.size(); i++) { + if (image.getContentType().toLowerCase().startsWith(contentTypes.get(i))) { return true; } } @@ -431,6 +476,7 @@ public boolean isValidateImage(MultipartFile image){ /** * O profissional solicita para não ver mais o JobRequest informado na lista de disponíveis, não tendo interesse. * A persistência é temporária na tabela, pois ao passar de uns dias será removido por um job assíncrono. + * * @param id * @param redirectAttributes * @return @@ -442,12 +488,12 @@ public String rememberToHide(@PathVariable Long id, RedirectAttributes redirectA String currentUserEmail = authentication.getEmail(); Optional oUser = userService.findByEmail(currentUserEmail); - if(!oUser.isPresent()){ + if (!oUser.isPresent()) { throw new EntityNotFoundException("O usuário não foi encontrado!"); } Optional oJobRequest = jobRequestService.findById(id); - if(!oJobRequest.isPresent()) { + if (!oJobRequest.isPresent()) { throw new EntityNotFoundException("Candidatura não encontrada!"); } @@ -456,4 +502,4 @@ public String rememberToHide(@PathVariable Long id, RedirectAttributes redirectA return "redirect:/minha-conta/profissional#disponiveis"; } -} +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/MyAccountController.java b/src/main/java/br/edu/utfpr/servicebook/controller/MyAccountController.java index a5ad97f4..e347edd7 100644 --- a/src/main/java/br/edu/utfpr/servicebook/controller/MyAccountController.java +++ b/src/main/java/br/edu/utfpr/servicebook/controller/MyAccountController.java @@ -97,6 +97,8 @@ public class MyAccountController { @Autowired private ModerateService moderateService; + @Autowired + private StateService stateService; private String userSmsErrorForwarding(String step, UserSmsDTO dto, Model model, BindingResult errors) { model.addAttribute("dto", dto); model.addAttribute("errors", errors.getAllErrors()); @@ -906,6 +908,92 @@ public String updateMyPersonalData(@PathVariable Long id, redirectAttributes.addFlashAttribute("msg", "Informações pessoais atualizadas com sucesso!"); return "redirect:/minha-conta/informacoes-pessoais/" + id; } + + @GetMapping("/meu-endereco/{id}") + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) + public ModelAndView showMyAddress(@PathVariable Long id) throws IOException { + + Optional oUser = this.userService.findById(id); + + if (!oUser.isPresent()) { + throw new EntityNotFoundException("O usuário não foi encontrado."); + } + + Optional oUserAuthenticated = this.userService.findByEmail(authentication.getEmail()); + + User userAuthenticated = oUserAuthenticated.get(); + + if (id != userAuthenticated.getId()) { + throw new AuthenticationCredentialsNotFoundException("Você não tem permissão para atualizar essas informações pessoais."); + } + + UserDTO userDTO = userMapper.toDto(userAuthenticated); + + List cities = cityService.findAll(); + List states = stateService.findAll(); + + ModelAndView mv = new ModelAndView("professional/account/my-address"); + mv.addObject("userDTO", userDTO); + mv.addObject("cities", cities); + mv.addObject("states", states); + return mv; + } + + /** + * Atualiza o endereço do indivíduo e empresa + * @param addressDTO + * @param errors + * @param redirectAttributes + * @return + * @throws IOException + */ + @PatchMapping("/salvar-endereco/{id}") + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) + public String updateMyAddress(@PathVariable Long id, + AddressDTO addressDTO, + BindingResult errors, + RedirectAttributes redirectAttributes + ) throws IOException { + + if (errors.hasErrors()) { + redirectAttributes.addFlashAttribute("errors", errors.getAllErrors()); + return "redirect:/minha-conta/meu-endereco/" + id; + } + + Optional oUser = this.userService.findById(id); + + if (!oUser.isPresent()) { + throw new EntityNotFoundException("O usuário não foi encontrado."); + } + + Optional oUserAuthenticated = this.userService.findByEmail(authentication.getEmail()); + User userAuthenticated = oUserAuthenticated.get(); + + if (id != userAuthenticated.getId()) { + throw new AuthenticationCredentialsNotFoundException("Você não tem permissão para atualizar o endereço."); + } + + Optional oInvididual = this.individualService.findById(id); + + Optional ocity = this.cityService.findByName(addressDTO.getCity()); + + Individual individual = oInvididual.get(); + Address address = new Address(); + + address.setPostalCode(addressDTO.getPostalCode()); + address.setNeighborhood(addressDTO.getNeighborhood()); + address.setNumber(addressDTO.getNumber()); + address.setStreet(addressDTO.getStreet()); + address.setCity(ocity.get()); + + individual.setAddress(address); + + this.individualService.save(individual); + + + redirectAttributes.addFlashAttribute("msg", "Endereço atualizado com sucesso!"); + return "redirect:/minha-conta/meu-endereco/" + id; + } } diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/MyAdsController.java b/src/main/java/br/edu/utfpr/servicebook/controller/MyAdsController.java new file mode 100644 index 00000000..b8b3a498 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/controller/MyAdsController.java @@ -0,0 +1,328 @@ +package br.edu.utfpr.servicebook.controller; + +import br.edu.utfpr.servicebook.model.dto.*; +import br.edu.utfpr.servicebook.model.entity.*; +import br.edu.utfpr.servicebook.model.mapper.ExpertiseMapper; +import br.edu.utfpr.servicebook.model.mapper.ServiceMapper; +import br.edu.utfpr.servicebook.security.IAuthentication; +import br.edu.utfpr.servicebook.security.RoleType; +import br.edu.utfpr.servicebook.service.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Controller; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import javax.annotation.security.PermitAll; +import javax.annotation.security.RolesAllowed; +import javax.persistence.EntityNotFoundException; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +@RequestMapping("/minha-conta/profissional/meus-anuncios") +@Controller +public class MyAdsController { + public static final Logger log = LoggerFactory.getLogger(ProfessionalHomeController.class); + + @Autowired + private ServiceService serviceService; + + @Autowired + private ServiceMapper serviceMapper; + + @Autowired + private ExpertiseService expertiseService; + + @Autowired + private ExpertiseMapper expertiseMapper; + + @Autowired + private ProfessionalServiceOfferingService professionalServiceOfferingService; + + @Autowired + private UserService userService; + + @Autowired + private IAuthentication authentication; + + @Autowired + private ProfessionalServicePackageOfferingService professionalServicePackageOfferingService; + + @Autowired + private ProfessionalServiceOfferingAdItemService professionalServiceOfferingAdItemService; + + @GetMapping + @PermitAll + protected ModelAndView showMyAds() throws Exception { + ModelAndView mv = new ModelAndView("professional/my-ads"); + Optional oUser = (userService.findByEmail(authentication.getEmail())); + + //paginação de serviços + PageRequest pageRequest = PageRequest.of(0, 5); + Page servicePage = serviceService.findAll(pageRequest); + + Page expertisePage = expertiseService.findAll(pageRequest); + + List expertiseDTOS = expertisePage.stream() + .map(s -> expertiseMapper.toDto(s)) + .collect(Collectors.toList()); + + List serviceDTOS = servicePage.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); + + List professionalServiceOfferings = professionalServiceOfferingService.findProfessionalServiceOfferingByUser(oUser.get()); + List servicesIndividuals = professionalServiceOfferingService.findFirst3ProfessionalServiceOfferingByUserAndType(oUser.get(), ProfessionalServiceOffering.Type.INDIVIDUAL); + + List servicesPackages = professionalServicePackageOfferingService.findAllByUserAndType(oUser.get(), ProfessionalServicePackageOffering.Type.SIMPLE_PACKAGE); + List servicesCombined = professionalServicePackageOfferingService.findByTypeAndUser(oUser.get(), ProfessionalServicePackageOffering.Type.COMBINED_PACKAGE); + List teste = professionalServiceOfferingAdItemService.findAllByProfessionalServicePackageOfferingUser(oUser.get()); + + mv.addObject("expertises", expertiseDTOS); + mv.addObject("professionalServiceOfferings", professionalServiceOfferings); + mv.addObject("servicesIndividuals", servicesIndividuals); + mv.addObject("servicesPackages", servicesPackages); + mv.addObject("servicesCombined", servicesCombined); + mv.addObject("teste", teste); + return mv; + } + + @GetMapping("/novo") + @PermitAll + protected ModelAndView registerMyAds() throws Exception { + ModelAndView mv = new ModelAndView("professional/my-ads-register"); + + //paginação de serviços + PageRequest pageRequest = PageRequest.of(0, 5); + + List expertises = expertiseService.findAll(); + List expertiseDTOs = expertises.stream() + .map(s -> expertiseMapper.toDto(s)) + .collect(Collectors.toList()); + mv.addObject("expertises", expertiseDTOs); + + Page servicePage = serviceService.findAll(pageRequest); + List serviceDTOS = servicePage.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); +// mv.addObject("services", serviceDTOS); + return mv; + } + + /** + * Adiciona um serviço individual. + * @param professionalServiceOfferingDTO + * @param errors + * @param redirectAttributes + * @return + * @throws Exception + */ + @PostMapping("/novo/individual") + @PermitAll + public String saveAds(ProfessionalServiceOfferingDTO professionalServiceOfferingDTO, BindingResult errors, RedirectAttributes + redirectAttributes) throws Exception { + Optional oUser = (userService.findByEmail(authentication.getEmail())); + + ModelAndView mv = new ModelAndView("professional/my-ads-register"); + + ProfessionalServiceOffering professionalServiceOffering = new ProfessionalServiceOffering(); + Optional oService = serviceService.findById(professionalServiceOfferingDTO.getServiceId()); + Optional oExpertise = expertiseService.findById(professionalServiceOfferingDTO.getExpertiseId()); + + professionalServiceOffering.setUser(oUser.get()); + professionalServiceOffering.setPrice(professionalServiceOfferingDTO.getPrice()); + professionalServiceOffering.setUnit(professionalServiceOfferingDTO.getUnit()); + professionalServiceOffering.setDuration(professionalServiceOfferingDTO.getDuration()); + professionalServiceOffering.setType(ProfessionalServiceOffering.Type.INDIVIDUAL); + + professionalServiceOffering.setDescription(professionalServiceOfferingDTO.getDescription()); + if(oService.isPresent()){ + professionalServiceOffering.setService(oService.get()); + } + if(oExpertise.isPresent()){ + professionalServiceOffering.setExpertise(oExpertise.get()); + } + //grava o nome do serviço original + professionalServiceOffering.setName(oService.get().getName()); + professionalServiceOfferingService.save(professionalServiceOffering); + + return("redirect:/minha-conta/profissional/meus-anuncios"); + } + + /** + * Adiciona um pacote de serviço. + * @param professionalServicePackageOfferingDTO + * @param professionalServiceOfferingDTO + * @return + * @throws Exception + */ + @PostMapping("/novo/pacote") + @PermitAll + public String saveAdsPackage(ProfessionalServiceOfferingDTO professionalServiceOfferingDTO, ProfessionalServicePackageOfferingDTO professionalServicePackageOfferingDTO, BindingResult errors, RedirectAttributes + redirectAttributes) throws Exception { + Optional oUser = (userService.findByEmail(authentication.getEmail())); + ModelAndView mv = new ModelAndView("professional/my-ads-register"); + + Optional oService = serviceService.findById(professionalServicePackageOfferingDTO.getServiceId()); + + ProfessionalServicePackageOffering professionalServicePackageOffering = new ProfessionalServicePackageOffering(); + professionalServicePackageOffering.setPrice(professionalServicePackageOfferingDTO.getPrice()); + professionalServicePackageOffering.setType(ProfessionalServicePackageOffering.Type.SIMPLE_PACKAGE); + professionalServicePackageOffering.setUnit(professionalServicePackageOfferingDTO.getUnit()); + professionalServicePackageOffering.setDuration(professionalServicePackageOfferingDTO.getDuration()); + professionalServicePackageOffering.setDescription(professionalServicePackageOfferingDTO.getDescription()); + //grava o nome do serviço original + professionalServicePackageOffering.setName(oService.get().getName()); + professionalServicePackageOffering.setAmount(professionalServicePackageOfferingDTO.getAmount()); + professionalServicePackageOffering.setUser(oUser.get()); + professionalServicePackageOffering.setService(oService.get()); + + professionalServicePackageOfferingService.save(professionalServicePackageOffering); + + return("redirect:/minha-conta/profissional/meus-anuncios"); + } + /** + * Adiciona um serviço combinado com um ou mais serviços. + * @param professionalServicePackageOfferingDTO + * @param professionalServiceOfferingDTO + * @return + * @throws Exception + */ + @PostMapping("/novo/combinado") + @PermitAll + public String saveAdsCombined(ProfessionalServiceOfferingDTO professionalServiceOfferingDTO, ProfessionalServicePackageOfferingDTO professionalServicePackageOfferingDTO, BindingResult errors, RedirectAttributes + redirectAttributes) throws Exception { + Optional oUser = (userService.findByEmail(authentication.getEmail())); + Optional oExpertise = expertiseService.findById(professionalServicePackageOfferingDTO.getExpertiseId()); + + ModelAndView mv = new ModelAndView("professional/my-ads-register"); + ProfessionalServicePackageOffering professionalServicePackageOffering = new ProfessionalServicePackageOffering(); + professionalServicePackageOffering.setPrice(professionalServicePackageOfferingDTO.getPrice()); + professionalServicePackageOffering.setType(ProfessionalServicePackageOffering.Type.COMBINED_PACKAGE); + professionalServicePackageOffering.setUnit(professionalServicePackageOfferingDTO.getUnit()); + professionalServicePackageOffering.setDuration(professionalServicePackageOfferingDTO.getDuration()); + professionalServicePackageOffering.setDescription(professionalServicePackageOfferingDTO.getDescription()); + professionalServicePackageOffering.setName(professionalServicePackageOfferingDTO.getDescription()); + professionalServicePackageOffering.setExpertise(oExpertise.get()); + professionalServicePackageOffering.setName(professionalServicePackageOfferingDTO.getDescription()); + + //grava o nome do serviço original + professionalServicePackageOffering.setUser(oUser.get()); + + professionalServicePackageOfferingService.save(professionalServicePackageOffering); + + for (Long valor : professionalServiceOfferingDTO.getDescriptions()) { + ProfessionalServiceOffering professionalServiceOffering = new ProfessionalServiceOffering(); + Optional oService = serviceService.findById(valor); + + professionalServiceOffering.setDescription(professionalServicePackageOfferingDTO.getDescription()); + //grava o nome do serviço original + professionalServiceOffering.setName(oService.get().getName()); + professionalServiceOffering.setType(ProfessionalServiceOffering.Type.COMBINED_PACKAGE); + professionalServiceOffering.setUnit(professionalServiceOfferingDTO.getUnit()); + professionalServiceOffering.setDuration(professionalServiceOfferingDTO.getDuration()); + professionalServiceOffering.setPrice(professionalServiceOfferingDTO.getPrice()); + professionalServiceOffering.setUser(oUser.get()); + professionalServiceOffering.setService(oService.get()); + professionalServiceOfferingService.save(professionalServiceOffering); +// + ProfessionalServiceOfferingAdItem professionalServiceOfferingAdItem = new ProfessionalServiceOfferingAdItem(professionalServiceOffering, professionalServicePackageOffering); + professionalServiceOfferingAdItemService.save(professionalServiceOfferingAdItem); + + } + + return("redirect:/minha-conta/profissional/meus-anuncios"); + } + @GetMapping("/pacotes") + @PermitAll + protected ModelAndView showMyAdsPackages() throws Exception { + ModelAndView mv = new ModelAndView("professional/ads/my-ads-packages"); + Optional oUser = (userService.findByEmail(authentication.getEmail())); + + //paginação de serviços + PageRequest pageRequest = PageRequest.of(0, 5); + Page servicePage = serviceService.findAll(pageRequest); + List serviceDTOS = servicePage.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); + + List servicesPackages = professionalServicePackageOfferingService.findByTypeAndUser(oUser.get(), ProfessionalServicePackageOffering.Type.SIMPLE_PACKAGE); + + mv.addObject("services", serviceDTOS); + mv.addObject("servicesPackages", servicesPackages); + return mv; + } + + @GetMapping("/individuais") + @PermitAll + protected ModelAndView showMyAdsIndividuals() throws Exception { + ModelAndView mv = new ModelAndView("professional/ads/my-ads-individuals"); + Optional oUser = (userService.findByEmail(authentication.getEmail())); + + //paginação de serviços + PageRequest pageRequest = PageRequest.of(0, 5); + Page servicePage = serviceService.findAll(pageRequest); + List serviceDTOS = servicePage.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); + + List professionalServiceOfferings = professionalServiceOfferingService.findProfessionalServiceOfferingByUserAndType(oUser.get(), ProfessionalServiceOffering.Type.INDIVIDUAL); + + mv.addObject("services", serviceDTOS); + mv.addObject("professionalServiceOfferings", professionalServiceOfferings); + return mv; + } + + @GetMapping("/combinados") + @PermitAll + protected ModelAndView showMyAdsCombineds() throws Exception { + ModelAndView mv = new ModelAndView("professional/ads/my-ads-combineds"); + Optional oUser = (userService.findByEmail(authentication.getEmail())); + + //paginação de serviços + PageRequest pageRequest = PageRequest.of(0, 5); + Page servicePage = serviceService.findAll(pageRequest); + List serviceDTOS = servicePage.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); + + List servicesCombined = professionalServicePackageOfferingService.findByTypeAndUser(oUser.get(), ProfessionalServicePackageOffering.Type.COMBINED_PACKAGE); + + mv.addObject("services", serviceDTOS); + mv.addObject("servicesCombined", servicesCombined); + return mv; + } + @GetMapping("/especialidade/{expertiseId}") + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) + @ResponseBody + public List findAdsByExpertise(@PathVariable Long expertiseId) throws Exception { + + User professional = this.getAuthenticatedUser(); + + Expertise expertise = expertiseService.findById(expertiseId).orElseThrow(() -> new EntityNotFoundException("Especialidade não encontrada")); + + //lista de serviços + List services = serviceService.findByExpertise(expertise); + List professionalServiceOfferings = professionalServiceOfferingService.findProfessionalServiceOfferingByUserAndExpertise(professional.getId(), expertiseId); + + return professionalServiceOfferings; + } + /** + * Retorna o indivíduo logado. + * @return + * @throws Exception + */ + private User getAuthenticatedUser() throws Exception { + Optional oProfessional = (userService.findByEmail(authentication.getEmail())); + + if (!oProfessional.isPresent()) { + throw new EntityNotFoundException("Usuário não autenticado! Por favor, realize sua autenticação no sistema."); + } + + return oProfessional.get(); + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/ProfessionalController.java b/src/main/java/br/edu/utfpr/servicebook/controller/ProfessionalController.java index e64b516c..02f2d7cf 100644 --- a/src/main/java/br/edu/utfpr/servicebook/controller/ProfessionalController.java +++ b/src/main/java/br/edu/utfpr/servicebook/controller/ProfessionalController.java @@ -2,10 +2,7 @@ import br.edu.utfpr.servicebook.model.dto.*; import br.edu.utfpr.servicebook.model.entity.*; -import br.edu.utfpr.servicebook.model.mapper.IndividualMapper; -import br.edu.utfpr.servicebook.model.mapper.JobContractedMapper; -import br.edu.utfpr.servicebook.model.mapper.ProfessionalServiceOfferingMapper; -import br.edu.utfpr.servicebook.model.mapper.UserMapper; +import br.edu.utfpr.servicebook.model.mapper.*; import br.edu.utfpr.servicebook.security.IAuthentication; import br.edu.utfpr.servicebook.service.*; @@ -15,8 +12,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.stereotype.Controller; +import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.annotation.security.PermitAll; import javax.persistence.EntityNotFoundException; @@ -73,6 +72,30 @@ public class ProfessionalController { @Autowired private PaginationUtil paginationUtil; + @Autowired + private ServiceService serviceService; + + @Autowired + private ExpertiseService expertiseService; + + @Autowired + private CategoryService categoryService; + + @Autowired + private CategoryMapper categoryMapper; + + @Autowired + private AssessmentProfessionalMapper assessmentProfessionalMapper; + + @Autowired + private AssessmentProfessionalService assessmentProfessionalService; + + @Autowired + private AssessmentProfessionalFileMapper assessmentProfessionalFileMapper; + + @Autowired + private AssessmentResponseService assessmentResponseService; + @GetMapping @PermitAll protected ModelAndView showAll() throws Exception { @@ -106,7 +129,8 @@ protected ModelAndView showAll() throws Exception { * Retorna a lista de profissionais de acordo com o termo de busca. * Se estiver logado, o usuário poderá ter acesso a todos os profissionais de acordo com a sua busca. * Caso seja um visitante, terá acesso a apenas 4 profissionais. - * @param searchTerm + * + * @param searchService * @param page * @return * @throws Exception @@ -114,8 +138,12 @@ protected ModelAndView showAll() throws Exception { @GetMapping(value = "/busca") @PermitAll protected ModelAndView showSearchResults( - @RequestParam(value = "termo-da-busca") String searchTerm, - @RequestParam(value = "pag", defaultValue = "1") int page +// @RequestParam(value = "termo-da-busca") String searchTerm, + @RequestParam(defaultValue = "0", value = "serviceId") Long searchService, + @RequestParam(defaultValue = "", value = "expertiseId") Long searchExpertise, + @RequestParam(defaultValue = "", value = "categoryId") Long searchCategory, + @RequestParam(value = "pag", defaultValue = "1") int page, + RedirectAttributes redirectAttributes ) throws Exception { ModelAndView mv = new ModelAndView("visitor/search-results"); @@ -132,17 +160,59 @@ protected ModelAndView showSearchResults( page = 1; size = this.paginationSizeVisitor; } + if (searchService == 0) { + redirectAttributes.addFlashAttribute("msg", "A atualização foi salva com sucesso!"); + } else { - Page professionals = individualService.findDistinctByTermIgnoreCaseWithPagination(searchTerm, page, size); - List professionalSearchItemDTOS = professionals.stream() - .map(s -> individualMapper.toSearchItemDto(s, individualService.getExpertises(s))) - .collect(Collectors.toList()); + Optional service = serviceService.findById(searchService); + Optional expertise = expertiseService.findById(searchExpertise); + Optional category = categoryService.findById(searchCategory); + + Page professionals = individualService.findAllIndividualsByService(service.get(), page, size); + Page professionalServiceOfferings = professionalServiceOfferingService.findAllIndividualsByService(service.get(), page, size); + + List professionalSearchItemDTOS = professionals.stream() + .map(s -> individualMapper.toSearchItemDto(s, individualService.getExpertises(s))) + .collect(Collectors.toList()); + + List professionalServiceOfferingDTOS = professionalServiceOfferings.stream() + .map(s -> professionalServiceOfferingMapper.toDTO(s)).collect(Collectors.toList()); + + //lista de categorias + List categories = categoryService.findAll(); + List categoryDTOs = categories.stream() + .map(s -> categoryMapper.toDto(s)) + .collect(Collectors.toList()); - PaginationDTO paginationDTO = paginationUtil.getPaginationDTO(professionals, "/profissionais/busca?termo-da-busca="+ searchTerm); - mv.addObject("professionals", professionalSearchItemDTOS); - mv.addObject("pagination", paginationDTO); - mv.addObject("isParam", true); - mv.addObject("searchTerm", searchTerm); + Page professionalsByExpertise = individualService.findDistinctByExpertiseAndCategoryPagination(expertise.get(), page, size); + + Page listProfessionals = individualService.listByExpertiseAndCategory(expertise.get(), category.get(), page, size); + + List professionalSearchItemDTOS2 = professionalsByExpertise.stream() + .map(s -> individualMapper.toSearchItemDto(s, individualService.getExpertises(s))) + .collect(Collectors.toList()); + + List professionals1 = individualService.findAllIndividualsAutonomosByService(expertise.get().getId(), page, size); + + List professionalSearchItemDTOS1 = professionals1.stream() + .map(s -> individualMapper.toSearchItemDto(s, individualService.getExpertises(s))) + .collect(Collectors.toList()); + + PaginationDTO paginationDTO = paginationUtil.getPaginationDTO(professionalServiceOfferings, "/profissionais/busca?termo-da-busca=" + searchService); + + mv.addObject("professionals", professionalSearchItemDTOS2); + mv.addObject("categoryDTOs", categoryDTOs); + mv.addObject("pagination", paginationDTO); + mv.addObject("isParam", true); + mv.addObject("service", service.get().getName()); + mv.addObject("searchTerm", searchService); + mv.addObject("dto_expertise", expertise.get()); + mv.addObject("dto", category.get()); + mv.addObject("dto_service", service.get()); + + mv.addObject("professionalServiceOfferingDTOS", professionalServiceOfferingDTOS); + mv.addObject("count_results", professionalServiceOfferingDTOS.size()); + } return mv; } @@ -150,6 +220,7 @@ protected ModelAndView showSearchResults( /** * Retorna a página de detalhes do profissional. * Esta página pode ser acessada de forma autenticada ou anônima. + * * @param id * @return * @throws Exception @@ -160,10 +231,71 @@ protected ModelAndView showProfessionalDetailsToVisitors(@PathVariable("id") Lon Optional oProfessional = userService.findById(id); - if(!oProfessional.isPresent()) { + if (!oProfessional.isPresent()) { + throw new EntityNotFoundException("Profissional não encontrado."); + } + + //cliente autenticado, caso esteja logado + Optional oClientAuthenticated = (userService.findByEmail(authentication.getEmail())); + + //profissional requisitado + UserDTO professionalDTO = userMapper.toDto(oProfessional.get()); + + //especialidades do profissional requisitado + List expertisesDTO = userService.getExpertiseDTOs(oProfessional.get()); + + List professionalExpertises = professionalExpertiseService.findByProfessional(oProfessional.get()); + + //serviços por especialidade + Map> servicesByExpertise = new HashMap<>(); + for (ProfessionalExpertise pe : professionalExpertises) { + List professionalServiceOfferings = professionalServiceOfferingService.findProfessionalServiceOfferingByUserAndExpertise(oProfessional.get().getId(), pe.getExpertise().getId()); + + if (professionalServiceOfferings.isEmpty()) { + continue; + } + + //transforma para DTO + List professionalServiceOfferingsDTO = professionalServiceOfferings.stream() + .map(service -> professionalServiceOfferingMapper.toDTO(service)) + .collect(Collectors.toList()); + + servicesByExpertise.put(pe, professionalServiceOfferingsDTO); + } + + ModelAndView mv = new ModelAndView("visitor/professional-details"); + mv.addObject("professional", professionalDTO); + mv.addObject("professionalExpertises", expertisesDTO); + mv.addObject("logged", oClientAuthenticated.isPresent()); + mv.addObject("servicesByExpertise", servicesByExpertise); + + //se o cliente está logado, mostra se ele segue o profissional + if (oClientAuthenticated.isPresent()) { + List follows = followsService.findFollowProfessionalClient(oProfessional.get(), oClientAuthenticated.get()); + boolean isFollow = !follows.isEmpty(); + UserDTO clientDTO = userMapper.toDto(oClientAuthenticated.get()); + mv.addObject("isFollow", isFollow); + mv.addObject("client", clientDTO); + } + return mv; + } + + @GetMapping("/detalhes/{id}/profissional/{professional_id}/servico/{service_id}") + @PermitAll + protected ModelAndView showProfessionalDetailsAndServiceToVisitors(@PathVariable("id") Long id, @PathVariable("professional_id") Long professional_id, @PathVariable("service_id") Long service_id) throws Exception { + + Optional oProfessional = userService.findById(professional_id); + + if (!oProfessional.isPresent()) { throw new EntityNotFoundException("Profissional não encontrado."); } + Optional oService = serviceService.findById(service_id); + + if (!oService.isPresent()) { + throw new EntityNotFoundException("Serviço não encontrado."); + } + //cliente autenticado, caso esteja logado Optional oClientAuthenticated = (userService.findByEmail(authentication.getEmail())); @@ -177,10 +309,10 @@ protected ModelAndView showProfessionalDetailsToVisitors(@PathVariable("id") Lon //serviços por especialidade Map> servicesByExpertise = new HashMap<>(); - for(ProfessionalExpertise pe : professionalExpertises) { + for (ProfessionalExpertise pe : professionalExpertises) { List professionalServiceOfferings = professionalServiceOfferingService.findProfessionalServiceOfferingByUserAndExpertise(oProfessional.get().getId(), pe.getExpertise().getId()); - if(professionalServiceOfferings.isEmpty()){ + if (professionalServiceOfferings.isEmpty()) { continue; } @@ -192,20 +324,48 @@ protected ModelAndView showProfessionalDetailsToVisitors(@PathVariable("id") Lon servicesByExpertise.put(pe, professionalServiceOfferingsDTO); } + List professionalServiceOfferings = professionalServiceOfferingService.findProfessionalServiceOfferingByServiceAndUser(oService.get().getId(), oProfessional.get().getId()); + List professionalServiceOfferings1 = professionalServiceOfferingService.findProfessionalServiceOfferingByUser(oProfessional.get()); + + /*AVALIAÇÕES*/ +// List assessmentProfessionalList = + List assessmentResponseList1 = assessmentProfessionalService.findAssessmentProfessionalByProfessional(oProfessional.get().getId()); + + List assessmentProfessionalDTOList = new ArrayList<>(); + + for (Object[] result : assessmentResponseList1) { + AssessmentProfessional assessmentProfessional = (AssessmentProfessional) result[0]; + AssessmentResponse assessmentResponse = (AssessmentResponse) result[1]; + AssessmentProfessionalFiles assessmentProfessionalFiles = (AssessmentProfessionalFiles) result[2]; + + AssessmentProfessionalDTO dto = assessmentProfessionalMapper.toFullDto(assessmentProfessional); + dto.setAssessmentResponses(assessmentProfessionalMapper.toResponseDto(assessmentResponse)); + dto.setAssessmentProfessionalFiles(assessmentProfessionalMapper.toFilesDto(assessmentProfessionalFiles)); + assessmentProfessionalDTOList.add(dto); + } + ModelAndView mv = new ModelAndView("visitor/professional-details"); mv.addObject("professional", professionalDTO); mv.addObject("professionalExpertises", expertisesDTO); mv.addObject("logged", oClientAuthenticated.isPresent()); mv.addObject("servicesByExpertise", servicesByExpertise); + mv.addObject("service", oService.get()); + mv.addObject("assessment", assessmentProfessionalDTOList); + mv.addObject("professionalServiceOfferings", professionalServiceOfferings1); //se o cliente está logado, mostra se ele segue o profissional - if(oClientAuthenticated.isPresent()){ + if (oClientAuthenticated.isPresent()) { List follows = followsService.findFollowProfessionalClient(oProfessional.get(), oClientAuthenticated.get()); boolean isFollow = !follows.isEmpty(); UserDTO clientDTO = userMapper.toDto(oClientAuthenticated.get()); mv.addObject("isFollow", isFollow); mv.addObject("client", clientDTO); } + + Optional oProfessionalServiceOffering = professionalServiceOfferingService.findById(id); + if(oProfessionalServiceOffering.isPresent()){ + mv.addObject("oProfessionalServiceOffering", oProfessionalServiceOffering.get()); + } return mv; } } diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/ProfessionalHomeController.java b/src/main/java/br/edu/utfpr/servicebook/controller/ProfessionalHomeController.java index 03ef5b16..bf67584b 100644 --- a/src/main/java/br/edu/utfpr/servicebook/controller/ProfessionalHomeController.java +++ b/src/main/java/br/edu/utfpr/servicebook/controller/ProfessionalHomeController.java @@ -12,30 +12,31 @@ import br.edu.utfpr.servicebook.sse.EventSSEDTO; import br.edu.utfpr.servicebook.sse.EventSseMapper; import br.edu.utfpr.servicebook.sse.SSEService; -import br.edu.utfpr.servicebook.util.SessionNames; +import br.edu.utfpr.servicebook.util.*; import br.edu.utfpr.servicebook.util.pagination.PaginationDTO; import br.edu.utfpr.servicebook.util.pagination.PaginationUtil; -import br.edu.utfpr.servicebook.util.UserTemplateInfo; -import br.edu.utfpr.servicebook.util.UserTemplateStatisticInfo; -import br.edu.utfpr.servicebook.util.TemplateUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; import org.springframework.stereotype.Controller; +import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.annotation.security.RolesAllowed; import javax.persistence.EntityNotFoundException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.text.ParseException; import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; @RequestMapping("/minha-conta/profissional") @@ -114,6 +115,30 @@ public class ProfessionalHomeController { @Autowired private UserService userService; + @Autowired + private AssessmentProfessionalMapper assessmentProfessionalMapper; + + @Autowired + private AssessmentProfessionalService assessmentProfessionalService; + + @Autowired + private AssessmentProfessionalFileService assessmentProfessionalFileService; + + @Autowired + private AssessmentResponseService assessmentResponseService; + + @Autowired + private PerspectiveAPIService perspectiveAPIService; + + @Autowired + private JobImagesService jobImagesService; + + @Autowired + private AssessmentResponseMapper assessmentResponseMapper; + + @Value("${svg.certificate.template}") + private String svgCertificateTemplate; + /** * Mostra a tela da minha conta no perfil do profissional, mostrando os anúncios disponíveis por default. * @param expertiseId @@ -121,7 +146,7 @@ public class ProfessionalHomeController { * @throws Exception */ @GetMapping - @RolesAllowed({RoleType.USER}) + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) public ModelAndView showMyAccountProfessional(@RequestParam(required = false, defaultValue = "0") Optional expertiseId) throws Exception { log.debug("ServiceBook: Minha conta."); @@ -502,7 +527,7 @@ public ModelAndView showMyDetails() throws Exception { } @GetMapping("/detalhes-servico/{id}") - @RolesAllowed({RoleType.USER}) + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) public ModelAndView showAvailableDetailJobs( @PathVariable Long id ) throws Exception { @@ -524,6 +549,8 @@ public ModelAndView showAvailableDetailJobs( JobRequestDetailsDTO jobFull = jobRequestMapper.jobRequestDetailsDTO(jobRequest); + List jobImages = jobImagesService.findJobImagesByJobRequest(oJobRequest.get()); + Optional oClient, oCity, oState; oClient = individualService.findById(jobFull.getUser().getId()); @@ -557,7 +584,26 @@ public ModelAndView showAvailableDetailJobs( UserTemplateInfo individualInfo = templateUtil.getUserInfo(oIndividual.get()); + List assessmentResponseList1 = assessmentProfessionalService.findAssessmentProfessionalByAssessmentResponses(oIndividual.get().getId(),jobRequest.getId()); + + List assessmentProfessionalDTOList = new ArrayList<>(); + + for (Object[] result : assessmentResponseList1) { + AssessmentProfessional assessmentProfessional = (AssessmentProfessional) result[0]; + AssessmentResponse assessmentResponse = (AssessmentResponse) result[1]; + + AssessmentProfessionalDTO dto = assessmentProfessionalMapper.toFullDto(assessmentProfessional); + + if(result[1] != null){ + dto.setAssessmentResponses(assessmentProfessionalMapper.toResponseDto(assessmentResponse)); + } + + assessmentProfessionalDTOList.add(dto); + } + mv.addObject("job", jobFull); + mv.addObject("jobImages", jobRequest.getJobImages()); + mv.addObject("client", client); mv.addObject("city", city.getName()); mv.addObject("state", state.getName()); @@ -567,6 +613,7 @@ public ModelAndView showAvailableDetailJobs( mv.addObject("isAvailableJobRequest", isAvailableJobRequest); mv.addObject("isJobToHired", isJobToHired); mv.addObject("userInfo", individualInfo); + mv.addObject("assessmentsProfessional", assessmentProfessionalDTOList); return mv; } @@ -766,4 +813,59 @@ private List generateJobContractedDTOList(Page oUser = individualService.findByEmail(currentUserEmail); + + Optional oAssessmentProfessional = assessmentProfessionalService.findById(assessmentId); + + if(!oAssessmentProfessional.isPresent()){ + throw new EntityNotFoundException("Avaliação não foi encontrada!"); + } + + AssessmentResponse assessmentResponse = new AssessmentResponse(); + String response = dto.getResponse(); + +// assessmentResponse.setAssessmentProfessional(dto.getAssessmentProfessional()); + +// assessmentResponse.setAssessmentProfessional(oAssessmentProfessional.get()); + + if (!response.isEmpty()){ + String analyzedComment = analyzeComment(response); + if ("Comentário Ofensivo".equals(analyzedComment)) { + errors.rejectValue("response", "error.dto", "Proibido comentários ofensivos!."); + return errorFowardingResponse(dto, errors); + } + } + + assessmentResponse.setResponse(dto.getResponse()); + assessmentResponse.setProfessional(oUser.get()); + assessmentResponse.setDate(DateUtil.getToday()); + + assessmentResponseService.save(assessmentResponse); + + return new ModelAndView("redirect:/minha-conta/profissional/meus-jobs#executados"); + } + + private ModelAndView errorFowardingResponse(AssessmentResponseDTO dto,BindingResult errors) { + ModelAndView mv = new ModelAndView("professional/detail-service"); + mv.addObject("dto", dto); + mv.addObject("errors", errors.getAllErrors()); + return mv; + } + + /*Método responsavel em chamar a api e então validar comentários*/ + @GetMapping("/analyze-comment") + public String analyzeComment(String coment){ + return perspectiveAPIService.analyzeComment(coment); + } + } diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/UserRegisterController.java b/src/main/java/br/edu/utfpr/servicebook/controller/UserRegisterController.java index 3ff8b031..d6909226 100644 --- a/src/main/java/br/edu/utfpr/servicebook/controller/UserRegisterController.java +++ b/src/main/java/br/edu/utfpr/servicebook/controller/UserRegisterController.java @@ -673,6 +673,7 @@ public String saveUser( if(isCompany){ CompanyDTO userSessionDTO = (CompanyDTO) userWizardUtil.getWizardState(httpSession, CompanyDTO.class, UserWizardUtil.KEY_WIZARD_COMPANY); + userSessionDTO.setProfilePicture(null); validator.validate(userSessionDTO, errors, new Class[]{ IndividualDTO.RequestUserEmailInfoGroupValidation.class, @@ -692,6 +693,7 @@ public String saveUser( } else{ IndividualDTO userSessionDTO = (IndividualDTO) userWizardUtil.getWizardState(httpSession, IndividualDTO.class, UserWizardUtil.KEY_WIZARD_INDIVIDUAL); + userSessionDTO.setProfilePicture(null); validator.validate(userSessionDTO, errors, new Class[]{ IndividualDTO.RequestUserEmailInfoGroupValidation.class, diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/company/CompanyAdsController.java b/src/main/java/br/edu/utfpr/servicebook/controller/company/CompanyAdsController.java new file mode 100644 index 00000000..a056df20 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/controller/company/CompanyAdsController.java @@ -0,0 +1,334 @@ +package br.edu.utfpr.servicebook.controller.company; + +import br.edu.utfpr.servicebook.controller.ProfessionalHomeController; +import br.edu.utfpr.servicebook.model.dto.ExpertiseDTO; +import br.edu.utfpr.servicebook.model.dto.ProfessionalServiceOfferingDTO; +import br.edu.utfpr.servicebook.model.dto.ProfessionalServicePackageOfferingDTO; +import br.edu.utfpr.servicebook.model.dto.ServiceDTO; +import br.edu.utfpr.servicebook.model.entity.*; +import br.edu.utfpr.servicebook.model.mapper.ExpertiseMapper; +import br.edu.utfpr.servicebook.model.mapper.ServiceMapper; +import br.edu.utfpr.servicebook.security.IAuthentication; +import br.edu.utfpr.servicebook.security.RoleType; +import br.edu.utfpr.servicebook.service.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Controller; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import javax.annotation.security.PermitAll; +import javax.annotation.security.RolesAllowed; +import javax.persistence.EntityNotFoundException; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@RequestMapping("/minha-conta/empresa/meus-anuncios") +@Controller +public class CompanyAdsController { + public static final Logger log = LoggerFactory.getLogger(ProfessionalHomeController.class); + + @Autowired + private ServiceService serviceService; + + @Autowired + private ServiceMapper serviceMapper; + + @Autowired + private ExpertiseService expertiseService; + + @Autowired + private ExpertiseMapper expertiseMapper; + + @Autowired + private ProfessionalServiceOfferingService professionalServiceOfferingService; + + @Autowired + private UserService userService; + + @Autowired + private IAuthentication authentication; + + @Autowired + private ProfessionalServicePackageOfferingService professionalServicePackageOfferingService; + + @Autowired + private ProfessionalServiceOfferingAdItemService professionalServiceOfferingAdItemService; + + @GetMapping + @PermitAll + protected ModelAndView showMyAds() throws Exception { + ModelAndView mv = new ModelAndView("company/my-ads"); + Optional oUser = (userService.findByEmail(authentication.getEmail())); + + //paginação de serviços + PageRequest pageRequest = PageRequest.of(0, 5); + Page servicePage = serviceService.findAll(pageRequest); + + Page expertisePage = expertiseService.findAll(pageRequest); + + List expertiseDTOS = expertisePage.stream() + .map(s -> expertiseMapper.toDto(s)) + .collect(Collectors.toList()); + + List serviceDTOS = servicePage.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); + + List professionalServiceOfferings = professionalServiceOfferingService.findProfessionalServiceOfferingByUser(oUser.get()); + List servicesIndividuals = professionalServiceOfferingService.findFirst3ProfessionalServiceOfferingByUserAndType(oUser.get(), ProfessionalServiceOffering.Type.INDIVIDUAL); + + List servicesPackages = professionalServicePackageOfferingService.findAllByUserAndType(oUser.get(), ProfessionalServicePackageOffering.Type.SIMPLE_PACKAGE); + List servicesCombined = professionalServicePackageOfferingService.findByTypeAndUser(oUser.get(), ProfessionalServicePackageOffering.Type.COMBINED_PACKAGE); + List teste = professionalServiceOfferingAdItemService.findAllByProfessionalServicePackageOfferingUser(oUser.get()); + + mv.addObject("expertises", expertiseDTOS); + mv.addObject("professionalServiceOfferings", professionalServiceOfferings); + mv.addObject("servicesIndividuals", servicesIndividuals); + mv.addObject("servicesPackages", servicesPackages); + mv.addObject("servicesCombined", servicesCombined); + mv.addObject("teste", teste); + return mv; + } + + @GetMapping("/novo") + @PermitAll + protected ModelAndView registerMyAds() throws Exception { + ModelAndView mv = new ModelAndView("company/my-ads-register"); + + //paginação de serviços + PageRequest pageRequest = PageRequest.of(0, 5); + + List expertises = expertiseService.findAll(); + List expertiseDTOs = expertises.stream() + .map(s -> expertiseMapper.toDto(s)) + .collect(Collectors.toList()); + mv.addObject("expertises", expertiseDTOs); + + Page servicePage = serviceService.findAll(pageRequest); + List serviceDTOS = servicePage.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); +// mv.addObject("services", serviceDTOS); + return mv; + } + + /** + * Adiciona um serviço individual. + * @param professionalServiceOfferingDTO + * @param errors + * @param redirectAttributes + * @return + * @throws Exception + */ + @PostMapping("/novo/individual") + @PermitAll + public String saveAds(ProfessionalServiceOfferingDTO professionalServiceOfferingDTO, BindingResult errors, RedirectAttributes + redirectAttributes) throws Exception { + Optional oUser = (userService.findByEmail(authentication.getEmail())); + + ModelAndView mv = new ModelAndView("company/my-ads-register"); + + ProfessionalServiceOffering professionalServiceOffering = new ProfessionalServiceOffering(); + Optional oService = serviceService.findById(professionalServiceOfferingDTO.getServiceId()); + Optional oExpertise = expertiseService.findById(professionalServiceOfferingDTO.getExpertiseId()); + + professionalServiceOffering.setUser(oUser.get()); + professionalServiceOffering.setPrice(professionalServiceOfferingDTO.getPrice()); + professionalServiceOffering.setUnit(professionalServiceOfferingDTO.getUnit()); + professionalServiceOffering.setDuration(professionalServiceOfferingDTO.getDuration()); + professionalServiceOffering.setType(ProfessionalServiceOffering.Type.INDIVIDUAL); + + professionalServiceOffering.setDescription(professionalServiceOfferingDTO.getDescription()); + if(oService.isPresent()){ + professionalServiceOffering.setService(oService.get()); + } + if(oExpertise.isPresent()){ + professionalServiceOffering.setExpertise(oExpertise.get()); + } + //grava o nome do serviço original + professionalServiceOffering.setName(oService.get().getName()); + professionalServiceOfferingService.save(professionalServiceOffering); + + return("redirect:/minha-conta/profissional/meus-anuncios"); + } + + /** + * Adiciona um pacote de serviço. + * @param professionalServicePackageOfferingDTO + * @param professionalServiceOfferingDTO + * @return + * @throws Exception + */ + @PostMapping("/novo/pacote") + @PermitAll + public String saveAdsPackage(ProfessionalServiceOfferingDTO professionalServiceOfferingDTO, ProfessionalServicePackageOfferingDTO professionalServicePackageOfferingDTO, BindingResult errors, RedirectAttributes + redirectAttributes) throws Exception { + Optional oUser = (userService.findByEmail(authentication.getEmail())); + ModelAndView mv = new ModelAndView("company/my-ads-register"); + + Optional oService = serviceService.findById(professionalServicePackageOfferingDTO.getServiceId()); + + ProfessionalServicePackageOffering professionalServicePackageOffering = new ProfessionalServicePackageOffering(); + professionalServicePackageOffering.setPrice(professionalServicePackageOfferingDTO.getPrice()); + professionalServicePackageOffering.setType(ProfessionalServicePackageOffering.Type.SIMPLE_PACKAGE); + professionalServicePackageOffering.setUnit(professionalServicePackageOfferingDTO.getUnit()); + professionalServicePackageOffering.setDuration(professionalServicePackageOfferingDTO.getDuration()); + professionalServicePackageOffering.setDescription(professionalServicePackageOfferingDTO.getDescription()); + //grava o nome do serviço original + professionalServicePackageOffering.setName(oService.get().getName()); + professionalServicePackageOffering.setAmount(professionalServicePackageOfferingDTO.getAmount()); + professionalServicePackageOffering.setUser(oUser.get()); + professionalServicePackageOffering.setService(oService.get()); + + professionalServicePackageOfferingService.save(professionalServicePackageOffering); + + return("redirect:/minha-conta/profissional/meus-anuncios"); + } + /** + * Adiciona um serviço combinado com um ou mais serviços. + * @param professionalServicePackageOfferingDTO + * @param professionalServiceOfferingDTO + * @return + * @throws Exception + */ + @PostMapping("/novo/combinado") + @PermitAll + public String saveAdsCombined(ProfessionalServiceOfferingDTO professionalServiceOfferingDTO, ProfessionalServicePackageOfferingDTO professionalServicePackageOfferingDTO, BindingResult errors, RedirectAttributes + redirectAttributes) throws Exception { + Optional oUser = (userService.findByEmail(authentication.getEmail())); + Optional oExpertise = expertiseService.findById(professionalServicePackageOfferingDTO.getExpertiseId()); + + ModelAndView mv = new ModelAndView("company/my-ads-register"); + ProfessionalServicePackageOffering professionalServicePackageOffering = new ProfessionalServicePackageOffering(); + professionalServicePackageOffering.setPrice(professionalServicePackageOfferingDTO.getPrice()); + professionalServicePackageOffering.setType(ProfessionalServicePackageOffering.Type.COMBINED_PACKAGE); + professionalServicePackageOffering.setUnit(professionalServicePackageOfferingDTO.getUnit()); + professionalServicePackageOffering.setDuration(professionalServicePackageOfferingDTO.getDuration()); + professionalServicePackageOffering.setDescription(professionalServicePackageOfferingDTO.getDescription()); + professionalServicePackageOffering.setName(professionalServicePackageOfferingDTO.getDescription()); + professionalServicePackageOffering.setExpertise(oExpertise.get()); + professionalServicePackageOffering.setName(professionalServicePackageOfferingDTO.getDescription()); + + //grava o nome do serviço original + professionalServicePackageOffering.setUser(oUser.get()); + + professionalServicePackageOfferingService.save(professionalServicePackageOffering); + + for (Long valor : professionalServiceOfferingDTO.getDescriptions()) { + ProfessionalServiceOffering professionalServiceOffering = new ProfessionalServiceOffering(); + Optional oService = serviceService.findById(valor); + + professionalServiceOffering.setDescription(professionalServicePackageOfferingDTO.getDescription()); + //grava o nome do serviço original + professionalServiceOffering.setName(oService.get().getName()); + professionalServiceOffering.setType(ProfessionalServiceOffering.Type.COMBINED_PACKAGE); + professionalServiceOffering.setUnit(professionalServiceOfferingDTO.getUnit()); + professionalServiceOffering.setDuration(professionalServiceOfferingDTO.getDuration()); + professionalServiceOffering.setPrice(professionalServiceOfferingDTO.getPrice()); + professionalServiceOffering.setUser(oUser.get()); + professionalServiceOffering.setService(oService.get()); + professionalServiceOfferingService.save(professionalServiceOffering); +// + ProfessionalServiceOfferingAdItem professionalServiceOfferingAdItem = new ProfessionalServiceOfferingAdItem(professionalServiceOffering, professionalServicePackageOffering); + professionalServiceOfferingAdItemService.save(professionalServiceOfferingAdItem); + + } + + return("redirect:/minha-conta/profissional/meus-anuncios"); + } + @GetMapping("/pacotes") + @PermitAll + protected ModelAndView showMyAdsPackages() throws Exception { + ModelAndView mv = new ModelAndView("company/ads/my-ads-packages"); + Optional oUser = (userService.findByEmail(authentication.getEmail())); + + //paginação de serviços + PageRequest pageRequest = PageRequest.of(0, 5); + Page servicePage = serviceService.findAll(pageRequest); + List serviceDTOS = servicePage.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); + + List servicesPackages = professionalServicePackageOfferingService.findByTypeAndUser(oUser.get(), ProfessionalServicePackageOffering.Type.SIMPLE_PACKAGE); + + mv.addObject("services", serviceDTOS); + mv.addObject("servicesPackages", servicesPackages); + return mv; + } + + @GetMapping("/individuais") + @PermitAll + protected ModelAndView showMyAdsIndividuals() throws Exception { + ModelAndView mv = new ModelAndView("company/ads/my-ads-individuals"); + Optional oUser = (userService.findByEmail(authentication.getEmail())); + + //paginação de serviços + PageRequest pageRequest = PageRequest.of(0, 5); + Page servicePage = serviceService.findAll(pageRequest); + List serviceDTOS = servicePage.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); + + List professionalServiceOfferings = professionalServiceOfferingService.findProfessionalServiceOfferingByUserAndType(oUser.get(), ProfessionalServiceOffering.Type.INDIVIDUAL); + + mv.addObject("services", serviceDTOS); + mv.addObject("professionalServiceOfferings", professionalServiceOfferings); + return mv; + } + + @GetMapping("/combinados") + @PermitAll + protected ModelAndView showMyAdsCombineds() throws Exception { + ModelAndView mv = new ModelAndView("company/ads/my-ads-combineds"); + Optional oUser = (userService.findByEmail(authentication.getEmail())); + + //paginação de serviços + PageRequest pageRequest = PageRequest.of(0, 5); + Page servicePage = serviceService.findAll(pageRequest); + List serviceDTOS = servicePage.stream() + .map(s -> serviceMapper.toDto(s)) + .collect(Collectors.toList()); + + List servicesCombined = professionalServicePackageOfferingService.findByTypeAndUser(oUser.get(), ProfessionalServicePackageOffering.Type.COMBINED_PACKAGE); + + mv.addObject("services", serviceDTOS); + mv.addObject("servicesCombined", servicesCombined); + return mv; + } + @GetMapping("/especialidade/{expertiseId}") + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) + @ResponseBody + public List findAdsByExpertise(@PathVariable Long expertiseId) throws Exception { + + User professional = this.getAuthenticatedUser(); + + Expertise expertise = expertiseService.findById(expertiseId).orElseThrow(() -> new EntityNotFoundException("Especialidade não encontrada")); + + //lista de serviços + List services = serviceService.findByExpertise(expertise); + List professionalServiceOfferings = professionalServiceOfferingService.findProfessionalServiceOfferingByUserAndExpertise(professional.getId(), expertiseId); + + return professionalServiceOfferings; + } + /** + * Retorna o indivíduo logado. + * @return + * @throws Exception + */ + private User getAuthenticatedUser() throws Exception { + Optional oProfessional = (userService.findByEmail(authentication.getEmail())); + + if (!oProfessional.isPresent()) { + throw new EntityNotFoundException("Usuário não autenticado! Por favor, realize sua autenticação no sistema."); + } + + return oProfessional.get(); + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/company/CompanyController.java b/src/main/java/br/edu/utfpr/servicebook/controller/company/CompanyController.java index 3585e8a4..826d4397 100644 --- a/src/main/java/br/edu/utfpr/servicebook/controller/company/CompanyController.java +++ b/src/main/java/br/edu/utfpr/servicebook/controller/company/CompanyController.java @@ -97,10 +97,25 @@ public class CompanyController { private EventSseMapper eventSseMapper; @Autowired - private IAuthentication authentication; + private PaginationUtil paginationUtil; @Autowired - private PaginationUtil paginationUtil; + private CategoryService categoryService; + + @Autowired + private CategoryMapper categoryMapper; + + @Autowired + private JobContractedService jobContractedService; + + @Autowired + private JobContractedMapper jobContractedMapper; + + @Autowired + private IndividualService individualService; + + @Autowired + private IAuthentication authentication; @GetMapping @RolesAllowed({RoleType.COMPANY}) @@ -204,7 +219,7 @@ public ModelAndView showAvailableJobs( List jobRequestFullDTOs = generateJobRequestDTOList(jobRequestPage); - PaginationDTO paginationDTO = paginationUtil.getPaginationDTO(jobRequestPage, "/minha-conta/profissional/disponiveis"); + PaginationDTO paginationDTO = paginationUtil.getPaginationDTO(jobRequestPage, "/minha-conta/empresa/disponiveis"); ModelAndView mv = new ModelAndView("professional/professional-index"); mv.addObject("pagination", paginationDTO); @@ -272,7 +287,6 @@ else if(status == JobRequest.Status.CANCELED){ } } @RolesAllowed({RoleType.COMPANY}) - private List generateJobRequestDTOList(Page jobRequestPage){ return jobRequestPage.stream().distinct() .map(jobRequest -> { @@ -285,4 +299,460 @@ private List generateJobRequestDTOList(Page jobRe return jobRequestMapper.toFullDto(jobRequest, Optional.ofNullable(0L)); }).collect(Collectors.toList()); } + + /** + * Apresenta a tela para o profissional adicionar especialidades. + * @return + * @throws Exception + */ + @GetMapping("/especialidades") + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) + public ModelAndView showExpertises() throws Exception { + + User professional = this.getAuthenticatedUser(); + + //lista de categorias + List categories = categoryService.findAll(); + List categoryDTOs = categories.stream() + .map(s -> categoryMapper.toDto(s)) + .collect(Collectors.toList()); + + List professionalExpertises = professionalExpertiseService.findByProfessional(professional); + + List professionalExpertiseDTOs = professionalExpertises.stream() + .map(professionalExpertise -> professionalExpertise.getExpertise()) + .map(expertise -> expertiseMapper.toDto(expertise)) + .collect(Collectors.toList()); + + List professionPage = expertiseService.findExpertiseNotExist(getAuthenticatedUser().getId()); + + List otherExpertisesDTOs = professionPage.stream() + .map(s -> expertiseMapper.toDto(s)) + .collect(Collectors.toList()); + + ModelAndView mv = new ModelAndView("professional/my-expertises"); + mv.addObject("categories", categoryDTOs); + mv.addObject("otherExpertises", otherExpertisesDTOs); + mv.addObject("professionalExpertises", professionalExpertiseDTOs); + return mv; + } + + @GetMapping("/especialidades/novo") + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) + public ModelAndView showFormToRegister() throws Exception { + + User professional = this.getAuthenticatedUser(); + + //lista de categorias + List categories = categoryService.findAll(); + List categoryDTOs = categories.stream() + .map(s -> categoryMapper.toDto(s)) + .collect(Collectors.toList()); + + ModelAndView mv = new ModelAndView("professional/my-expertises-register"); + mv.addObject("categories", categoryDTOs); + + return mv; + } + + @GetMapping("/meus-jobs") + @RolesAllowed({RoleType.COMPANY}) + public ModelAndView showMyJobsProfessional(@RequestParam(required = false, defaultValue = "0") Optional expertiseId) throws Exception { + log.debug("ServiceBook: Minha conta."); + + Optional oProfessional = (userService.findByEmail(authentication.getEmail())); + + if (!oProfessional.isPresent()) { + throw new Exception("Usuário não autenticado! Por favor, realize sua autenticação no sistema."); + } + + List professionalExpertises = professionalExpertiseService.findByProfessional(oProfessional.get()); + List professionalExpertiseDTOs = professionalExpertises.stream() + .map(professionalExpertise -> professionalExpertise.getExpertise()) + .map(expertise -> expertiseMapper.toDto(expertise)) + .collect(Collectors.toList()); + + //envia a notificação ao usuário + List eventSsesList = sseService.findPendingEventsByEmail(authentication.getEmail()); + List eventSSEDTOs = eventSsesList.stream() + .map(eventSse -> { + return eventSseMapper.toFullDto(eventSse); + }) + .collect(Collectors.toList()); + + ModelAndView mv = new ModelAndView("professional/my-account"); + mv.addObject("eventsse", eventSSEDTOs); + mv.addObject("professionalExpertises", professionalExpertiseDTOs); + + return mv; + } + + /** + * Mostra os serviços em que o profissional se candidatou. + * @param request + * @param id + * @param page + * @param size + * @param order + * @param direction + * @return + * @throws Exception + */ + @GetMapping("/em-disputa") + @RolesAllowed({RoleType.COMPANY}) + public ModelAndView showDisputedJobs( + HttpServletRequest request, + @RequestParam(required = false, defaultValue = "0") Long id, + @RequestParam(value = "pag", defaultValue = "1") int page, + @RequestParam(value = "siz", defaultValue = "3") int size, + @RequestParam(value = "ord", defaultValue = "id") String order, + @RequestParam(value = "dir", defaultValue = "ASC") String direction + ) throws Exception { + +// Optional oProfessional = (individualService.findByEmail(authentication.getEmail())); + User oProfessional = this.getAuthenticatedUser(); + +// if (!oProfessional.isPresent()) { +// throw new Exception("Usuário não autenticado! Por favor, realize sua autenticação no sistema."); +// } + + PageRequest pageRequest = PageRequest.of(page - 1, size, Sort.by("dateCreated").descending()); + Page jobCandidatePage = null; + List jobCandidateDTOs = null; + + if (id == 0) { + jobCandidatePage = jobCandidateService.findByJobRequest_StatusAndProfessional(JobRequest.Status.AVAILABLE, oProfessional, pageRequest); + } else { + if (id < 0) { + throw new InvalidParamsException("O identificador da especialidade não pode ser negativo. Por favor, tente novamente."); + } + + Optional oExpertise = expertiseService.findById(id); + + if (!oExpertise.isPresent()) { + throw new EntityNotFoundException("A especialidade não foi encontrada pelo id informado. Por favor, tente novamente."); + } + + Optional oProfessionalExpertise = professionalExpertiseService.findByProfessionalAndExpertise(oProfessional, oExpertise.get()); + + if (!oProfessionalExpertise.isPresent()) { + throw new InvalidParamsException("A especialidade profissional não foi encontrada. Por favor, tente novamente."); + } + + jobCandidatePage = jobCandidateService.findByJobRequest_StatusAndJobRequest_ExpertiseAndProfessional(JobRequest.Status.AVAILABLE, oExpertise.get(), oProfessional, pageRequest); + } + + jobCandidateDTOs = generateJobCandidateDTOList(jobCandidatePage); + + PaginationDTO paginationDTO = paginationUtil.getPaginationDTO(jobCandidatePage, "/minha-conta/profissional/em-disputa"); + + ModelAndView mv = new ModelAndView("professional/disputed-jobs-report"); + mv.addObject("pagination", paginationDTO); + mv.addObject("jobs", jobCandidateDTOs); + + return mv; + } + + @GetMapping("/em-orcamento") + @RolesAllowed({RoleType.COMPANY}) + public ModelAndView showBudgetJobs( + HttpServletRequest request, + @RequestParam(required = false, defaultValue = "0") Long id, + @RequestParam(value = "pag", defaultValue = "1") int page, + @RequestParam(value = "siz", defaultValue = "3") int size, + @RequestParam(value = "ord", defaultValue = "id") String order, + @RequestParam(value = "dir", defaultValue = "ASC") String direction + ) throws Exception { + + User oProfessional = this.getAuthenticatedUser(); + + PageRequest pageRequest = PageRequest.of(page - 1, size, Sort.by("dateCreated").descending()); + Page jobCandidatePage = null; + List jobCandidateDTOs = null; + + if (id == 0) { + jobCandidatePage = jobCandidateService.findByJobRequest_StatusAndProfessional(JobRequest.Status.BUDGET, oProfessional, pageRequest); + } else { + if (id < 0) { + throw new InvalidParamsException("O identificador da especialidade não pode ser negativo. Por favor, tente novamente."); + } + + Optional oExpertise = expertiseService.findById(id); + + if (!oExpertise.isPresent()) { + throw new EntityNotFoundException("A especialidade não foi encontrada pelo id informado. Por favor, tente novamente."); + } + + Optional oProfessionalExpertise = professionalExpertiseService.findByProfessionalAndExpertise(oProfessional, oExpertise.get()); + + if (!oProfessionalExpertise.isPresent()) { + throw new InvalidParamsException("A especialidade profissional não foi encontrada. Por favor, tente novamente."); + } + + jobCandidatePage = jobCandidateService.findByJobRequest_StatusAndJobRequest_ExpertiseAndProfessional(JobRequest.Status.BUDGET, oExpertise.get(), oProfessional, pageRequest); + } + + jobCandidateDTOs = generateJobCandidateDTOList(jobCandidatePage); + + PaginationDTO paginationDTO = paginationUtil.getPaginationDTO(jobCandidatePage, "/minha-conta/profissional/em-orcamento"); + + ModelAndView mv = new ModelAndView("professional/budget-jobs-report"); + mv.addObject("pagination", paginationDTO); + mv.addObject("jobs", jobCandidateDTOs); + + return mv; + } + + @GetMapping("/para-contratar") + @RolesAllowed({RoleType.COMPANY}) + public ModelAndView showForHiredJobs( + HttpServletRequest request, + @RequestParam(required = false, defaultValue = "0") Long id, + @RequestParam(value = "pag", defaultValue = "1") int page, + @RequestParam(value = "siz", defaultValue = "3") int size, + @RequestParam(value = "ord", defaultValue = "id") String order, + @RequestParam(value = "dir", defaultValue = "ASC") String direction + ) throws Exception { + + Page jobCandidatePage = findJobCandidates(id, JobRequest.Status.TO_HIRED, page, size); + + List jobCandidateDTOs = generateJobCandidateDTOList(jobCandidatePage); + + PaginationDTO paginationDTO = paginationUtil.getPaginationDTO(jobCandidatePage, "/minha-conta/profissional/para-contratar"); + + ModelAndView mv = new ModelAndView("professional/to-hired-jobs-report"); + mv.addObject("pagination", paginationDTO); + mv.addObject("jobs", jobCandidateDTOs); + + return mv; + } + + /** + * Mostra as ordens de serviços para serem feitas, ou seja, que o profissional já foi contratado. + * @param request + * @param expertiseId + * @param page + * @param size + * @param order + * @param direction + * @return + * @throws Exception + */ + @GetMapping("/para-fazer") + @RolesAllowed({RoleType.COMPANY}) + public ModelAndView showTodoJobs( + HttpServletRequest request, + @RequestParam(required = false, defaultValue = "0") Long expertiseId, + @RequestParam(value = "pag", defaultValue = "1") int page, + @RequestParam(value = "siz", defaultValue = "3") int size, + @RequestParam(value = "ord", defaultValue = "id") String order, + @RequestParam(value = "dir", defaultValue = "ASC") String direction + ) throws Exception { + + Page jobRequestPage = findJobRequests(expertiseId, JobRequest.Status.TO_DO, page, size); + + List jobRequestFullDTOs = generateJobRequestDTOList(jobRequestPage); + + PaginationDTO paginationDTO = paginationUtil.getPaginationDTO(jobRequestPage, "/minha-conta/profissional/para-fazer"); + + ModelAndView mv = new ModelAndView("professional/todo-jobs-report"); + mv.addObject("pagination", paginationDTO); + mv.addObject("jobs", jobRequestFullDTOs); + + return mv; + } + + @GetMapping("/fazendo") + @RolesAllowed({RoleType.COMPANY}) + public ModelAndView showWorkingJobs( + HttpServletRequest request, + @RequestParam(required = false, defaultValue = "0") Long id, + @RequestParam(value = "pag", defaultValue = "1") int page, + @RequestParam(value = "siz", defaultValue = "3") int size, + @RequestParam(value = "ord", defaultValue = "id") String order, + @RequestParam(value = "dir", defaultValue = "ASC") String direction + ) throws Exception { + + Page jobRequestPage = findJobRequests(id, JobRequest.Status.DOING, page, size); + List jobRequestFullDTOs = generateJobRequestDTOList(jobRequestPage); + + PaginationDTO paginationDTO = paginationUtil.getPaginationDTO(jobRequestPage, "/minha-conta/profissional/para-fazer"); + + ModelAndView mv = new ModelAndView("professional/todo-jobs-report"); + mv.addObject("pagination", paginationDTO); + mv.addObject("jobs", jobRequestFullDTOs); + + return mv; + } + + @GetMapping("/executados") + @RolesAllowed({RoleType.COMPANY}) + public ModelAndView showJobsPerformed( + HttpServletRequest request, + @RequestParam(required = false, defaultValue = "0") Long id, + @RequestParam(value = "pag", defaultValue = "1") int page, + @RequestParam(value = "siz", defaultValue = "3") int size, + @RequestParam(value = "ord", defaultValue = "id") String order, + @RequestParam(value = "dir", defaultValue = "ASC") String direction + ) throws Exception { + + Page jobContractedPage = findJobContracted(id, JobRequest.Status.CLOSED, page, size); + List jobContractedDTOs = generateJobContractedDTOList(jobContractedPage); + + PaginationDTO paginationDTO = paginationUtil.getPaginationDTO(jobContractedPage, "/minha-conta/profissional/executados"); + + ModelAndView mv = new ModelAndView("professional/jobs-performed-report"); + mv.addObject("pagination", paginationDTO); + mv.addObject("jobs", jobContractedDTOs); + + return mv; + } + + @GetMapping("/cancelados") + @RolesAllowed({RoleType.COMPANY}) + public ModelAndView showCanceledJobs( + HttpServletRequest request, + @RequestParam(required = false, defaultValue = "0") Long id, + @RequestParam(value = "pag", defaultValue = "1") int page, + @RequestParam(value = "siz", defaultValue = "3") int size, + @RequestParam(value = "ord", defaultValue = "id") String order, + @RequestParam(value = "dir", defaultValue = "ASC") String direction + ) throws Exception { + + Page jobRequestPage = findJobRequests(id, JobRequest.Status.CANCELED, page, size); + List jobRequestFullDTOs = generateJobRequestDTOList(jobRequestPage); + + PaginationDTO paginationDTO = paginationUtil.getPaginationDTO(jobRequestPage, "/minha-conta/profissional/para-fazer"); + + ModelAndView mv = new ModelAndView("professional/todo-jobs-report"); + mv.addObject("pagination", paginationDTO); + mv.addObject("jobs", jobRequestFullDTOs); + + return mv; + } + + private List generateJobCandidateDTOList(Page jobCandidatePage){ + return jobCandidatePage.stream() + .map(jobCandidate -> { + Optional totalCandidates = jobCandidateService.countByJobRequest(jobCandidate.getJobRequest()); + + if (totalCandidates.isPresent()) { + return jobCandidateMapper.toMinDto(jobCandidate, totalCandidates); + } + + return jobCandidateMapper.toMinDto(jobCandidate, Optional.ofNullable(0L)); + }).collect(Collectors.toList()); + } + + + private Page findJobContracted(Long expertiseId, JobRequest.Status status, int page, int size){ + Optional oProfessional = (userService.findByEmail(authentication.getEmail())); + + if (!oProfessional.isPresent()) { + throw new EntityNotFoundException("Usuário não autenticado! Por favor, realize sua autenticação no sistema."); + } + + PageRequest pageRequest = PageRequest.of(page - 1, size, Sort.by("id").descending()); + Page jobContractedPage = null; + List jobContractedDTOs = null; + + if (expertiseId == 0) { + if(status == JobRequest.Status.CLOSED){ + return jobContractedPage = jobContractedService.findByJobRequest_StatusAndProfessional(JobRequest.Status.CLOSED, oProfessional.get(), pageRequest); + } + return null; + } else { + + if (expertiseId < 0) { + throw new InvalidParamsException("O identificador da especialidade não pode ser negativo. Por favor, tente novamente."); + } + + Optional oExpertise = expertiseService.findById(expertiseId); + + if (!oExpertise.isPresent()) { + throw new EntityNotFoundException("A especialidade não foi encontrada pelo id informado. Por favor, tente novamente."); + } + + Optional oProfessionalExpertise = professionalExpertiseService.findByProfessionalAndExpertise(oProfessional.get(), oExpertise.get()); + + if (!oProfessionalExpertise.isPresent()) { + throw new InvalidParamsException("A especialidade profissional não foi encontrada. Por favor, tente novamente."); + } + + if(status == JobRequest.Status.CLOSED){ + jobContractedPage = jobContractedService.findByJobRequest_StatusAndJobRequest_ExpertiseAndProfessional(JobRequest.Status.CLOSED, oExpertise.get(), oProfessional.get(), pageRequest); + } + return null; + } + } + + private List generateJobContractedDTOList(Page jobContractedPage) { + return jobContractedPage.stream() + .map(jobContracted -> { + Optional totalCandidates = jobCandidateService.countByJobRequest(jobContracted.getJobRequest()); + + if (totalCandidates.isPresent()) { + return jobContractedMapper.toFullDto(jobContracted, totalCandidates); + } + + return jobContractedMapper.toFullDto(jobContracted, Optional.ofNullable(0L)); + }) + .collect(Collectors.toList()); + } + + private Page findJobCandidates(Long expertiseId, JobRequest.Status status, int page, int size){ + Optional oProfessional = (userService.findByEmail(authentication.getEmail())); + + if (!oProfessional.isPresent()) { + throw new EntityNotFoundException("Usuário não autenticado! Por favor, realize sua autenticação no sistema."); + } + + PageRequest pageRequest = PageRequest.of(page - 1, size, Sort.by("dateCreated").descending()); + Page jobCandidatePage = null; + List jobCandidateDTOs = null; + + if (expertiseId == 0) { + if(status == JobRequest.Status.TO_HIRED){ + return jobCandidatePage = jobCandidateService.findByJobRequest_StatusAndProfessional(status, oProfessional.get(), pageRequest); + } + return null; + } else { + if (expertiseId < 0) { + throw new InvalidParamsException("O identificador da especialidade não pode ser negativo. Por favor, tente novamente."); + } + + Optional oExpertise = expertiseService.findById(expertiseId); + + if (!oExpertise.isPresent()) { + throw new EntityNotFoundException("A especialidade não foi encontrada pelo id informado. Por favor, tente novamente."); + } + + Optional oProfessionalExpertise = professionalExpertiseService.findByProfessionalAndExpertise(oProfessional.get(), oExpertise.get()); + + if (!oProfessionalExpertise.isPresent()) { + throw new InvalidParamsException("A especialidade profissional não foi encontrada. Por favor, tente novamente."); + } + + if(status == JobRequest.Status.TO_HIRED){ + return jobCandidatePage = jobCandidateService.findByJobRequest_StatusAndJobRequest_ExpertiseAndProfessional(JobRequest.Status.TO_HIRED, oExpertise.get(), oProfessional.get(), pageRequest); + } + + return null; + } + } + + /** + * Retorna a empresa logada. + * @return + * @throws Exception + */ + private User getAuthenticatedUser() throws Exception { + Optional oProfessional = (userService.findByEmail(authentication.getEmail())); + + if (!oProfessional.isPresent()) { + throw new EntityNotFoundException("Usuário não autenticado! Por favor, realize sua autenticação no sistema."); + } + + return oProfessional.get(); + } } diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/company/CompanyServiceOfferingController.java b/src/main/java/br/edu/utfpr/servicebook/controller/company/CompanyServiceOfferingController.java new file mode 100644 index 00000000..a47f3278 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/controller/company/CompanyServiceOfferingController.java @@ -0,0 +1,223 @@ +package br.edu.utfpr.servicebook.controller.company; + +import br.edu.utfpr.servicebook.controller.ProfessionalHomeController; +import br.edu.utfpr.servicebook.model.dto.ExpertiseDTO; +import br.edu.utfpr.servicebook.model.dto.ProfessionalServiceOfferingDTO; +import br.edu.utfpr.servicebook.model.dto.ServiceDTO; +import br.edu.utfpr.servicebook.model.entity.Expertise; +import br.edu.utfpr.servicebook.model.entity.ProfessionalServiceOffering; +import br.edu.utfpr.servicebook.model.entity.Service; +import br.edu.utfpr.servicebook.model.entity.User; +import br.edu.utfpr.servicebook.model.mapper.ExpertiseMapper; +import br.edu.utfpr.servicebook.model.mapper.ProfessionalServiceOfferingMapper; +import br.edu.utfpr.servicebook.model.mapper.ServiceMapper; +import br.edu.utfpr.servicebook.security.IAuthentication; +import br.edu.utfpr.servicebook.security.RoleType; +import br.edu.utfpr.servicebook.service.ExpertiseService; +import br.edu.utfpr.servicebook.service.ProfessionalServiceOfferingService; +import br.edu.utfpr.servicebook.service.ServiceService; +import br.edu.utfpr.servicebook.service.UserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.validation.BindingResult; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import javax.annotation.security.RolesAllowed; +import javax.persistence.EntityNotFoundException; +import java.util.List; +import java.util.Optional; + +@RequestMapping("/minha-conta/empresa/servicos") +@Controller +public class CompanyServiceOfferingController { + public static final Logger log = LoggerFactory.getLogger(ProfessionalHomeController.class); + @Autowired + private UserService userService; + + @Autowired + private ProfessionalServiceOfferingService professionalServiceOfferingService; + + @Autowired + private ServiceService serviceService; + + @Autowired + private ServiceMapper serviceMapper; + + @Autowired + private ExpertiseService expertiseService; + + @Autowired + private ExpertiseMapper expertiseMapper; + + @Autowired + private ProfessionalServiceOfferingMapper professionalServiceOfferingMapper; + + @Autowired + private IAuthentication authentication; + + /** + * Retorna a lista de serviços oferecidos pelo profissional. + * @param id + * @return + * @throws Exception + */ + @GetMapping("") + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) + public ModelAndView showServices(@RequestParam(required = false) Long id) throws Exception { + + User user = this.getAuthenticatedUser(); + + //verifica se o id da especialidade foi passado, caso contrário retorna os serviços de todas as especialidades + ExpertiseDTO expertiseDTO = null; + List professionalServiceOfferings = null; + if(id != null && id > 0){ + Expertise expertise = expertiseService.findById(id) + .orElseThrow(() -> new EntityNotFoundException("Especialidade não encontrada")); + + expertiseDTO = expertiseMapper.toDto(expertise); + + professionalServiceOfferings = professionalServiceOfferingService.findProfessionalServiceOfferingByUserAndService_Expertise(user, expertise); + } + else { + professionalServiceOfferings = professionalServiceOfferingService.findProfessionalServiceOfferingByUser(user); + } + + //todas as expertises do profissional + List expertisesDTO = userService.getExpertiseDTOs(user); + + //transforma a lista de ofertas de serviços em uma lista de DTOs com stream + List professionalServiceOfferingsDTO = professionalServiceOfferings.stream() + .map(professionalServiceOffering -> professionalServiceOfferingMapper.toDTO(professionalServiceOffering)) + .toList(); + + ModelAndView mv = new ModelAndView("professional/my-services"); + mv.addObject("expertise", expertiseDTO); + mv.addObject("expertises", expertisesDTO); + mv.addObject("professionalServiceOfferings", professionalServiceOfferingsDTO); + + return mv; + } + + /** + * Retorna o formulário para cadastrar um novo serviço para uma das especialidades do profissional. + * @param id + * @return + * @throws Exception + */ + @GetMapping("/novo") + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) + public ModelAndView showServicesFormToRegister(@RequestParam(required = false, defaultValue = "0") Long id) throws Exception { + + User user = this.getAuthenticatedUser(); + + //verifica se o id da especialidade foi passado, caso contrário retorna os serviços de todas as especialidades + ExpertiseDTO expertiseDTO = null; + List servicesDTO = null; + if(id != null && id > 0){ + + Expertise expertise = expertiseService.findById(id) + .orElseThrow(() -> new EntityNotFoundException("Especialidade não encontrada")); + expertiseDTO = expertiseMapper.toDto(expertise); + + //lista os serviços desta especialidade + List services = serviceService.findByExpertise(expertise); + servicesDTO = services.stream() + .map(service -> serviceMapper.toDto(service)) + .toList(); + } + else { + + } + + //todas as expertises do profissional + List expertisesDTO = userService.getExpertiseDTOs(user); + + ModelAndView mv = new ModelAndView("professional/my-services-register"); + mv.addObject("expertise", expertiseDTO); + mv.addObject("expertises", expertisesDTO); + mv.addObject("services", servicesDTO); + + return mv; + } + + @PostMapping() + @RolesAllowed({RoleType.USER, RoleType.COMPANY}) + public String saveService(@Validated ServiceDTO serviceDTO, BindingResult errors, RedirectAttributes redirectAttributes) throws Exception { + + String routeRedirect = "redirect:/minha-conta/profissional/servicos/novo?id=" + serviceDTO.getExpertiseId(); + if(serviceDTO.getExpertiseId() == null){ + routeRedirect = "redirect:/minha-conta/profissional/servicos/novo"; + } + else{ + routeRedirect = "redirect:/minha-conta/profissional/servicos/novo?id=" + serviceDTO.getExpertiseId(); + } + + if (errors.hasErrors()) { + log.error("Erro de validação de especialidade"); + redirectAttributes.addFlashAttribute("errors", errors.getAllErrors()); + return routeRedirect; + } + + //verifica se o serviço existe, se foi cadastrado pelo administrador + Long serviceId = serviceDTO.getId(); + Optional oService = serviceService.findById(serviceId); + if(!oService.isPresent()){ + log.error("Serviço não encontrado"); + errors.rejectValue("id", "service.not.found", "Serviço não encontrado"); + redirectAttributes.addFlashAttribute("errors", errors.getAllErrors()); + return routeRedirect; + } + + //verifica se já existe o serviço cadastrado pelo nome + Optional oProfessionalServiceOffering = professionalServiceOfferingService.findProfessionalServiceOfferingByName(serviceDTO.getName()); + + if(oProfessionalServiceOffering.isPresent()){ + log.error("Serviço já cadastrado"); + errors.rejectValue("name", "service.already.registered", "Serviço já cadastrado"); + redirectAttributes.addFlashAttribute("errors", errors.getAllErrors()); + return routeRedirect; + } + + User professional = this.getAuthenticatedUser(); + + ProfessionalServiceOffering professionalServiceOffering = new ProfessionalServiceOffering(); + professionalServiceOffering.setName(serviceDTO.getName()); + professionalServiceOffering.setDescription(serviceDTO.getDescription()); + professionalServiceOffering.setUser(professional); + professionalServiceOffering.setService(oService.get()); + + professionalServiceOfferingService.save(professionalServiceOffering); + + //sucesso + if(serviceDTO.getExpertiseId() == null){ + return "redirect:/minha-conta/profissional/servicos"; + } + else{ + return "redirect:/minha-conta/profissional/servicos?id=" + serviceDTO.getExpertiseId(); + } + } + + /** + * Retorna o usuário logado. + * @return + * @throws Exception + */ + private User getAuthenticatedUser() throws Exception { + Optional oProfessional = (userService.findByEmail(authentication.getEmail())); + + if (!oProfessional.isPresent()) { + throw new EntityNotFoundException("Usuário não autenticado! Por favor, realize sua autenticação no sistema."); + } + + return oProfessional.get(); + } + +} diff --git a/src/main/java/br/edu/utfpr/servicebook/controller/company/JobController.java b/src/main/java/br/edu/utfpr/servicebook/controller/company/JobController.java index 87453624..1b5ba5ac 100644 --- a/src/main/java/br/edu/utfpr/servicebook/controller/company/JobController.java +++ b/src/main/java/br/edu/utfpr/servicebook/controller/company/JobController.java @@ -126,6 +126,8 @@ public String save(@Valid JobDTO dto, BindingResult errors, RedirectAttributes r Optional oUser = userService.findByEmail(authentication.getEmail()); Optional oCompany = companyService.findById(oUser.get().getId()); + System.out.println("EMPRESA"); + System.out.println(oUser); if (!oCompany.isPresent()) { throw new EntityNotFoundException("A Empresa não foi encontrada!"); } diff --git a/src/main/java/br/edu/utfpr/servicebook/exception/Advisor.java b/src/main/java/br/edu/utfpr/servicebook/exception/Advisor.java new file mode 100644 index 00000000..132b8034 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/exception/Advisor.java @@ -0,0 +1,40 @@ +package br.edu.utfpr.servicebook.exception; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import java.util.HashMap; +import java.util.Map; + +@ControllerAdvice +public class Advisor extends ResponseEntityExceptionHandler { + @Override + public ResponseEntity handleMethodArgumentNotValid( + MethodArgumentNotValidException exception, + HttpHeaders headers, + HttpStatus status, + WebRequest request + ) { + Map body = new HashMap<>(); + + exception.getBindingResult().getFieldErrors().forEach((error) -> { + body.put(error.getField(), error.getDefaultMessage()); + }); + + return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(MercadoPagoException.class) + public ResponseEntity handleMercadoPagoException(MercadoPagoException exception) { + Map body = new HashMap<>(); + body.put("error_message", exception.getMessage()); + + return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST); + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/exception/MercadoPagoException.java b/src/main/java/br/edu/utfpr/servicebook/exception/MercadoPagoException.java new file mode 100644 index 00000000..f206c98b --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/exception/MercadoPagoException.java @@ -0,0 +1,7 @@ +package br.edu.utfpr.servicebook.exception; + +public class MercadoPagoException extends RuntimeException { + public MercadoPagoException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/jobs/SendEmailToRegisterUser.java b/src/main/java/br/edu/utfpr/servicebook/jobs/SendEmailToRegisterUser.java new file mode 100644 index 00000000..72a89f2d --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/jobs/SendEmailToRegisterUser.java @@ -0,0 +1,39 @@ +package br.edu.utfpr.servicebook.jobs; + +import br.edu.utfpr.servicebook.service.EmailSenderService; +import org.quartz.Job; +import org.quartz.JobDataMap; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.mail.MessagingException; +@Component +public class SendEmailToRegisterUser implements Job { + public static final String RECIPIENT_KEY = "recipient"; + public static final String CODE_KEY = "token"; + public static final String LINK_KEY = "link"; + public static final String USER_KEY = "user"; + + @Autowired + private EmailSenderService emailSenderService; + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); + String email = (String) jobDataMap.get(SendEmailWithVerificationCodeJob.RECIPIENT_KEY); + String code = (String) jobDataMap.get(SendEmailWithVerificationCodeJob.CODE_KEY); + String company = (String) jobDataMap.get(SendEmailToRegisterUser.USER_KEY); + String link = (String) jobDataMap.get(SendEmailToAuthenticateJob.LINK_KEY); + + String text = "Olá

A empresa "+ company + ", deseja incluir você ao quadro de funcionários." + + "
Para isto é necessário realizar o cadastro na plataforma, você pode se cadastrar usando o link: " + link + ".

"; + + try { + emailSenderService.sendHTMLEmail(email, "Service Book", text); + } catch (MessagingException e) { + System.out.println(e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/jobs/SendEmailVoucher.java b/src/main/java/br/edu/utfpr/servicebook/jobs/SendEmailVoucher.java new file mode 100644 index 00000000..490cb318 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/jobs/SendEmailVoucher.java @@ -0,0 +1,137 @@ +package br.edu.utfpr.servicebook.jobs; + +import br.edu.utfpr.servicebook.service.EmailSenderService; +import br.edu.utfpr.servicebook.service.UserService; +import com.itextpdf.layout.properties.TextAlignment; +import org.quartz.Job; +import org.quartz.JobDataMap; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import javax.mail.MessagingException; +import java.io.IOException; +import java.util.Optional; +import br.edu.utfpr.servicebook.model.entity.User; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfWriter; +import com.itextpdf.layout.Document; +import com.itextpdf.layout.element.Paragraph; + +import java.io.ByteArrayOutputStream; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfWriter; +import com.itextpdf.layout.Document; +import com.itextpdf.layout.element.Paragraph; +import com.itextpdf.layout.element.Text; +import org.quartz.JobDataMap; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class SendEmailVoucher implements Job { + + public static final String PAYMENT_KEY = "token"; + public static final Long CLIENT_ID = Long.valueOf(0); + public static final Long PROFESSIONAL_ID = Long.valueOf(0); + public static final String SERVICE_KEY = "recipient_service"; + public static final String DATE_KEY = "recipient_date"; + + public static final String VOUCHER_KEY = "recipient_voucher"; + + @Autowired + private EmailSenderService emailSenderService; + + @Autowired + private UserService userService; + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); + + String email1 = "thryssai@gmail.com"; + + String code = (String) jobDataMap.get(SendEmailVoucher.PAYMENT_KEY); + String voucher = (String) jobDataMap.get(SendEmailVoucher.VOUCHER_KEY); + + Long clientId = (Long) jobDataMap.get(SendEmailVoucher.CLIENT_ID.toString()); + Optional oUser = userService.findById(clientId); + + Long professionalId = (Long) jobDataMap.get(SendEmailVoucher.PROFESSIONAL_ID.toString()); + Optional oProfessional = userService.findById(professionalId); + + String service = (String) jobDataMap.get(SendEmailVoucher.SERVICE_KEY); + + String date = (String) jobDataMap.get(SendEmailVoucher.DATE_KEY); + + String emailClient = (String) oUser.get().getEmail(); + String emailProfessional = (String) oProfessional.get().getEmail(); + + String text = "" + + "

Olá, "+ oUser.get().getName() +"

" + + "

Segue abaixo o link para acessar o seu voucher. Com ele é possível verificar os dados relacionados ao seu pedido.

" + + "

Qualquer informação pode ser obtida diretamente com o profissional, através do contato disponibilizado na plataforma.

" + + "

Clique no link para acessar o seu voucher:

" + + "

Ver o meu Voucher

"+ + "

Atenciosamente,

" + + "

Equipe ServiceBook.

" + + ""; + + String textProfessional = "" + + "

Olá, "+ oProfessional.get().getName() +"

" + + "

Segue o voucher emitido pelo cliente referente ao pedido de serviço.

" + + "

Serviço solicitado por: "+ oUser.get().getName() +".

" + + "

Serviço solicitado: "+ service +".

" + + "

Clique no link para acessar o voucher disponível:

" + + "

Ver o Voucher

"+ + "

Atenciosamente,

" + + "

Equipe ServiceBook.

" + + ""; + try { + + emailSenderService.sendHTMLEmail(emailClient, "Service Book - Voucher de Pagamento", text); + emailSenderService.sendHTMLEmail(emailProfessional, "Service Book - Voucher de Pagamento", textProfessional); + + } catch (MessagingException e) { + System.out.println(e.getMessage()); + } + } + + public byte[] generatePDF(String code, String service, String date, String professional, String client) throws JobExecutionException { + // criar PDF + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PdfWriter pdfWriter = new PdfWriter(outputStream); + PdfDocument pdfDocument = new PdfDocument(pdfWriter); + Document document = new Document(pdfDocument); + + Text titleText = new Text("Comprovante de Pagamento\n\n") + .setFontSize(20) + .setBold(); + Paragraph titleParagraph = new Paragraph(titleText) + .setTextAlignment(TextAlignment.CENTER); + document.add(titleParagraph); + + Paragraph contentParagraph = new Paragraph() + .add(new Text("Voucher: ").setBold()) + .add(new Text(code)) + .add("\n") + .add(new Text("Serviço: ").setBold()) + .add(new Text(service)) + .add("\n") + .add(new Text("Data de Validade: ").setBold()) + .add(new Text(date)) + .add("\n\n") + .add(new Text("Profissional: : ").setBold()) + .add(new Text(professional)) + .add("\n\n") + .add(new Text("Cliente: ").setBold()) + .add(new Text(client)) + .add("\n\n"); + document.add(contentParagraph); + + document.close(); + return outputStream.toByteArray(); + } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/jobs/SendEmailWithConfirmationUser.java b/src/main/java/br/edu/utfpr/servicebook/jobs/SendEmailWithConfirmationUser.java new file mode 100644 index 00000000..86d9ec05 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/jobs/SendEmailWithConfirmationUser.java @@ -0,0 +1,40 @@ +package br.edu.utfpr.servicebook.jobs; + +import br.edu.utfpr.servicebook.service.EmailSenderService; +import org.quartz.Job; +import org.quartz.JobDataMap; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.mail.MessagingException; + +@Component +public class SendEmailWithConfirmationUser implements Job { + public static final String RECIPIENT_KEY = "recipient"; + public static final String CODE_KEY = "token"; + public static final String LINK_KEY = "link"; + public static final String USER_KEY = "user"; + + @Autowired + private EmailSenderService emailSenderService; + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); + String email = (String) jobDataMap.get(SendEmailWithConfirmationUser.RECIPIENT_KEY); + String code = (String) jobDataMap.get(SendEmailWithConfirmationUser.CODE_KEY); + String link = (String) jobDataMap.get(SendEmailWithConfirmationUser.LINK_KEY); + String company = (String) jobDataMap.get(SendEmailWithConfirmationUser.USER_KEY); + + String text = "Olá " + "!

a empresa "+ company + ", deseja incluir você ao quadro de funcionários." + + " Se desejar fazer parte da empresa basta confirmar acessando o link: " + link + ".

"; + + try { + emailSenderService.sendHTMLEmail(email, "Service Book", text); + } catch (MessagingException e) { + System.out.println(e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/AssessmentProfessionalDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/AssessmentProfessionalDTO.java new file mode 100644 index 00000000..9091fcca --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/AssessmentProfessionalDTO.java @@ -0,0 +1,45 @@ +package br.edu.utfpr.servicebook.model.dto; + +import br.edu.utfpr.servicebook.model.entity.AssessmentProfessionalFiles; +import br.edu.utfpr.servicebook.model.entity.AssessmentResponse; +import br.edu.utfpr.servicebook.model.entity.JobRequest; +import br.edu.utfpr.servicebook.model.entity.User; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.io.Serializable; +import java.time.LocalDate; +import java.util.Set; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class AssessmentProfessionalDTO implements Serializable { + private Long id; + + private float quality; + + private String comment; + + private String date; + + private Long professionalId; + + private User professional; + + private Long clientId; + + private User client; + + private Long jobRequestId; + + private JobRequest jobRequest; + + private AssessmentProfessionalFileDTO assessmentProfessionalFiles; + + private AssessmentResponseDTO assessmentResponses; + +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/AssessmentProfessionalFileDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/AssessmentProfessionalFileDTO.java new file mode 100644 index 00000000..17a6ae8e --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/AssessmentProfessionalFileDTO.java @@ -0,0 +1,31 @@ +package br.edu.utfpr.servicebook.model.dto; + +import br.edu.utfpr.servicebook.model.entity.AssessmentProfessional; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.springframework.web.multipart.MultipartFile; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class AssessmentProfessionalFileDTO implements Serializable { + private Long id; + +// private String path; + + // private String video; + private String image; + + private MultipartFile pathImage; + + private String comment; + + private Long assessmentProfessionalId; + + private AssessmentProfessional assessmentProfessional; +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/AssessmentResponseDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/AssessmentResponseDTO.java new file mode 100644 index 00000000..cba9e7c3 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/AssessmentResponseDTO.java @@ -0,0 +1,30 @@ +package br.edu.utfpr.servicebook.model.dto; + +import br.edu.utfpr.servicebook.model.entity.AssessmentProfessional; +import br.edu.utfpr.servicebook.model.entity.JobImages; +import br.edu.utfpr.servicebook.model.entity.User; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class AssessmentResponseDTO implements Serializable { + private Long id; + + private AssessmentProfessional assessmentProfessional; + + private User professional; + + private String date; + + private String response; + +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/CardPaymentDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/CardPaymentDTO.java new file mode 100644 index 00000000..cd72b827 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/CardPaymentDTO.java @@ -0,0 +1,78 @@ +package br.edu.utfpr.servicebook.model.dto; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +public class CardPaymentDTO { + @NotNull + private String token; + + private String issuerId; + + @NotNull + private String paymentMethodId; + + @NotNull + private BigDecimal transactionAmount; + + @NotNull + private Integer installments; + + @NotNull + @JsonProperty("description") + private String productDescription; + + @NotNull + private PayerDTO payer; + + public CardPaymentDTO() { + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getIssuerId() { + return issuerId; + } + + public void setIssuerId(String issuerId) { + this.issuerId = issuerId; + } + + public String getPaymentMethodId() { + return paymentMethodId; + } + + public void setPaymentMethodId(String paymentMethodId) { + this.paymentMethodId = paymentMethodId; + } + + public BigDecimal getTransactionAmount() { + return transactionAmount; + } + + public void setTransactionAmount(BigDecimal transactionAmount) { + this.transactionAmount = transactionAmount; + } + + public Integer getInstallments() { + return installments; + } + + public void setInstallments(Integer installments) { + this.installments = installments; + } + + public PayerDTO getPayer() { + return payer; + } + + public void setPayer(PayerDTO payer) { + this.payer = payer; + } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/ClientMinDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/ClientMinDTO.java index 395bfc48..5feafebc 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/dto/ClientMinDTO.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/ClientMinDTO.java @@ -1,5 +1,6 @@ package br.edu.utfpr.servicebook.model.dto; +import br.edu.utfpr.servicebook.util.IWizardDTO; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -9,9 +10,9 @@ @Data @NoArgsConstructor @AllArgsConstructor -public class ClientMinDTO implements Serializable { +public class ClientMinDTO extends UserDTO implements IWizardDTO, Serializable{ private String name; - private AddressMinDTO address; +// private AddressMinDTO address; } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/CompanyProfessionalDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/CompanyProfessionalDTO.java new file mode 100644 index 00000000..ea6e482c --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/CompanyProfessionalDTO.java @@ -0,0 +1,17 @@ +package br.edu.utfpr.servicebook.model.dto; + +import br.edu.utfpr.servicebook.util.IWizardDTO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CompanyProfessionalDTO implements IWizardDTO, Serializable { + private String ids; +// private Set ids = new HashSet<>(); +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/CompanyProfessionalDTO2.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/CompanyProfessionalDTO2.java new file mode 100644 index 00000000..1ba47c91 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/CompanyProfessionalDTO2.java @@ -0,0 +1,23 @@ +package br.edu.utfpr.servicebook.model.dto; + +import br.edu.utfpr.servicebook.model.entity.CompanyProfessionalPK; +import br.edu.utfpr.servicebook.util.IWizardDTO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class CompanyProfessionalDTO2 implements IWizardDTO, Serializable { + + private CompanyProfessionalPK id; + private String name; + private String email; + private String profilePicture; + private String isConfirmed; +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/ExpertiseMinDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/ExpertiseMinDTO.java index b831a082..fa139fd2 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/dto/ExpertiseMinDTO.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/ExpertiseMinDTO.java @@ -12,5 +12,5 @@ public class ExpertiseMinDTO implements Serializable { private String name; - + private Long categoryId; } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/JobContractedFullDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/JobContractedFullDTO.java index 7293c57f..4c3151ba 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/dto/JobContractedFullDTO.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/JobContractedFullDTO.java @@ -4,6 +4,8 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.time.LocalDate; + @Data @NoArgsConstructor @AllArgsConstructor @@ -13,5 +15,6 @@ public class JobContractedFullDTO { private String comments; private int rating; private JobRequestFullDTO jobRequest; + private String todoDate; } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestDTO.java index 561a3a07..faf27a15 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestDTO.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestDTO.java @@ -20,6 +20,8 @@ public class JobRequestDTO implements Serializable { @NotNull(message = "Especialidade inválida! Por favor, selecione uma especialidade de um profissional.", groups = RequestExpertiseGroupValidation.class) private Long expertiseId; + private Long professionalServiceOfferingId; + private Long clientId; private Integer dateProximity; private LocalDate dateCreated; diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestDetailsDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestDetailsDTO.java index 08de75f4..6fd0861d 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestDetailsDTO.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestDetailsDTO.java @@ -3,6 +3,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; import java.io.Serializable; @@ -21,5 +22,8 @@ public class JobRequestDetailsDTO implements Serializable { private Long totalCandidates; private String textualDate; private Long amountOfCandidates; + private MultipartFile imageFile; + private String imageSession; + private ProfessionalServiceOfferingDTO professionalServiceOfferingDTO; } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestFullDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestFullDTO.java index 9d5bae45..ba3495de 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestFullDTO.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestFullDTO.java @@ -1,10 +1,15 @@ package br.edu.utfpr.servicebook.model.dto; +import br.edu.utfpr.servicebook.model.entity.JobImages; +import br.edu.utfpr.servicebook.model.entity.User; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; @Data @NoArgsConstructor @@ -21,7 +26,11 @@ public class JobRequestFullDTO implements Serializable { private Long totalCandidates; private String textualDate; private Long amountOfCandidates; + private User user; public String status; + private MultipartFile imageFile; + private Set jobImages = new HashSet<>(); + } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestMinDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestMinDTO.java index 8e40a8fc..095225cb 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestMinDTO.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/JobRequestMinDTO.java @@ -19,6 +19,8 @@ public class JobRequestMinDTO implements Serializable { private ExpertiseDTO expertiseDTO; + private ClientDTO clientDTO; + private String dateCreated; private String dateTarget; diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/PayerDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/PayerDTO.java new file mode 100644 index 00000000..7258fda0 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/PayerDTO.java @@ -0,0 +1,29 @@ +package br.edu.utfpr.servicebook.model.dto; +import javax.validation.constraints.NotNull; + +public class PayerDTO { + @NotNull + private String email; + + @NotNull + private PayerIdentificationDTO identification; + + public PayerDTO() { + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public PayerIdentificationDTO getIdentification() { + return identification; + } + + public void setIdentification(PayerIdentificationDTO identification) { + this.identification = identification; + } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/PayerIdentificationDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/PayerIdentificationDTO.java new file mode 100644 index 00000000..29d066e5 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/PayerIdentificationDTO.java @@ -0,0 +1,28 @@ +package br.edu.utfpr.servicebook.model.dto; +import javax.validation.constraints.NotNull; +public class PayerIdentificationDTO { + @NotNull + private String type; + + @NotNull + private String number; + + public PayerIdentificationDTO() { + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentDTO.java new file mode 100644 index 00000000..be5a0cdb --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentDTO.java @@ -0,0 +1,18 @@ +package br.edu.utfpr.servicebook.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PaymentDTO { + @NotEmpty(message = "O identificador do pagamento é obrigatório") + private Integer paymentId; + + @NotEmpty(message = "O status do pagamento é obrigatório") + private String status; +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentJobDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentJobDTO.java new file mode 100644 index 00000000..673cb931 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentJobDTO.java @@ -0,0 +1,14 @@ +package br.edu.utfpr.servicebook.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PaymentJobDTO { + private Long id; + private Long jobRequestId; + private Long paymentId; +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentResponseDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentResponseDTO.java new file mode 100644 index 00000000..ba994ae5 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentResponseDTO.java @@ -0,0 +1,39 @@ +package br.edu.utfpr.servicebook.model.dto; + +import lombok.NonNull; + +public class PaymentResponseDTO { + private Long id; + private String status; + private String detail; + + public PaymentResponseDTO(Long id, String status, String detail) { + this.id = id; + this.status = status; + this.detail = detail; + } + + public @NonNull Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getDetail() { + return detail; + } + + public void setDetail(String detail) { + this.detail = detail; + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentVoucherDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentVoucherDTO.java new file mode 100644 index 00000000..43ce8d81 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/PaymentVoucherDTO.java @@ -0,0 +1,22 @@ +package br.edu.utfpr.servicebook.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class PaymentVoucherDTO implements Serializable { + private Long id; + private Long paymentId; + private Long clientId; + private Long professionalId; + private Long jobRequestId; + + private String code; +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/ProfessionalSearchItemDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/ProfessionalSearchItemDTO.java index 48eada24..27c502e7 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/dto/ProfessionalSearchItemDTO.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/ProfessionalSearchItemDTO.java @@ -1,5 +1,7 @@ package br.edu.utfpr.servicebook.model.dto; +import br.edu.utfpr.servicebook.model.entity.Expertise; +import br.edu.utfpr.servicebook.model.entity.Individual; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -20,10 +22,11 @@ public class ProfessionalSearchItemDTO extends UserDTO { private int rating; private int denounceAmount; - public String getOnlyNumbersFromPhone() { return getPhoneNumber().replaceAll("[^0-9]", ""); } public List expertises; + + public Expertise expertise; } \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/ProfessionalServiceOfferingDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/ProfessionalServiceOfferingDTO.java index 01c3d995..8e9428d6 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/dto/ProfessionalServiceOfferingDTO.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/ProfessionalServiceOfferingDTO.java @@ -1,11 +1,13 @@ package br.edu.utfpr.servicebook.model.dto; +import br.edu.utfpr.servicebook.model.entity.ProfessionalServicePackageOffering; import br.edu.utfpr.servicebook.model.entity.Service; import br.edu.utfpr.servicebook.model.entity.User; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.*; +import java.util.Set; /** * Classe que representa um serviço adicionado por um profissional ao seu portfólio. @@ -19,6 +21,13 @@ public class ProfessionalServiceOfferingDTO { private Long id; + public enum Type { + INDIVIDUAL, + COMBINED_PACKAGE, + SIMPLE_PACKAGE + } + + private Type type; /** * Nome do serviço. * O profissional pode customizar o nome do serviço cadastrado pelo administrador de várias maneiras, dependendo @@ -34,6 +43,17 @@ public class ProfessionalServiceOfferingDTO { * Caso ele não especifique a descrição do serviço, a descrição do serviço cadastrado pelo administrador será usada. */ private String description; + private Set descriptions; + + /** + * Unidade de preço do serviço. + */ + private String unit; + + /** + * Duração do serviço. + */ + private String duration; /** * Serviço cadastrado pelo administrador. @@ -41,9 +61,14 @@ public class ProfessionalServiceOfferingDTO { * do tipo de particularidade que o seu serviço tem. */ private ServiceDTO service; + private ExpertiseDTO expertise; private Long serviceId; - + private Long expertiseId; + /** + * Preço do serviço individual. + */ + private Long price; /** * Profissional que oferece o serviço. */ diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/ProfessionalServicePackageOfferingDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/ProfessionalServicePackageOfferingDTO.java new file mode 100644 index 00000000..d0e9e27e --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/ProfessionalServicePackageOfferingDTO.java @@ -0,0 +1,67 @@ +package br.edu.utfpr.servicebook.model.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.HashSet; +import java.util.Set; + +@Data +@NoArgsConstructor +public class ProfessionalServicePackageOfferingDTO { + private Long id; + + public enum Type { + INDIVIDUAL, + COMBINED_PACKAGE, + SIMPLE_PACKAGE + } + + private ProfessionalServiceOfferingDTO.Type type; + /** + * Nome do serviço. + * O profissional pode customizar o nome do serviço cadastrado pelo administrador de várias maneiras, dependendo + * do tipo de particularidade que o seu serviço tem. + * Caso ele não especifique o nome do serviço, o nome do serviço cadastrado pelo administrador será usado. + */ + private String name; + + /** + * Descrição do serviço em primeira pessoa. + * O profissional pode customizar a descrição do serviço cadastrado pelo administrador de várias maneiras, dependendo + * do tipo de particularidade que o seu serviço tem. + * Caso ele não especifique a descrição do serviço, a descrição do serviço cadastrado pelo administrador será usada. + */ + private String description; + + /** + * Unidade de preço do serviço. + */ + private String unit; + + /** + * Duração do serviço. + */ + private String duration; + + private Integer amount; + + /** + * Serviço cadastrado pelo administrador. + * O profissional pode customizar a descrição do serviço cadastrado pelo administrador de várias maneiras, dependendo + * do tipo de particularidade que o seu serviço tem. + */ + private ServiceDTO service; + private ExpertiseDTO expertise; + + private Long serviceId; + private Long expertiseId; + private Long price; + + /** + * Profissional que oferece o serviço. + */ + private UserDTO user; + + private Long userId; +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/dto/UserTokenDTO.java b/src/main/java/br/edu/utfpr/servicebook/model/dto/UserTokenDTO.java new file mode 100644 index 00000000..66b6c7cf --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/dto/UserTokenDTO.java @@ -0,0 +1,21 @@ +package br.edu.utfpr.servicebook.model.dto; + + +import br.edu.utfpr.servicebook.model.entity.User; +import br.edu.utfpr.servicebook.util.IWizardDTO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.io.Serializable; +@Data +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class UserTokenDTO implements IWizardDTO, Serializable { + private String token; + private String email; + private User user; + +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentProfessional.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentProfessional.java new file mode 100644 index 00000000..b90c58aa --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentProfessional.java @@ -0,0 +1,56 @@ +package br.edu.utfpr.servicebook.model.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; + +@Data +@NoArgsConstructor +@Table(name = "assessment_professionals") +@Entity +public class AssessmentProfessional { + private static final long serialVersionUID = 1L; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private float quality; + + private String comment; + + private LocalDate date; + + @PrePersist + public void onPersist() { + this.date = LocalDate.now(); + } + + @ManyToOne + @JoinColumn(name = "professional_id") + private User professional; + + @ManyToOne + @JoinColumn(name = "client_id") + private User client; + + @ManyToOne + @JoinColumn(name = "jobRequest_id") + private JobRequest jobRequest; + + @ManyToOne + @JoinColumn(name = "assessment_response") + private AssessmentResponse assessmentResponse; + + @ManyToOne + @JoinColumn(name = "assessment_files") + private AssessmentProfessionalFiles assessmentProfessionalFiles; + +// @OneToMany(mappedBy = "assessmentProfessional", cascade = CascadeType.REMOVE) +// Set assessmentResponses = new HashSet<>(); + +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentProfessionalFiles.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentProfessionalFiles.java new file mode 100644 index 00000000..e31764ad --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentProfessionalFiles.java @@ -0,0 +1,27 @@ +package br.edu.utfpr.servicebook.model.entity; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.multipart.MultipartFile; + +import javax.persistence.*; + +@Data +@NoArgsConstructor +@Table(name = "assessment_professionals_files") +@Entity +public class AssessmentProfessionalFiles { + private static final long serialVersionUID = 1L; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "assessment_professional_id") + private AssessmentProfessional assessmentProfessional; + + @Column(nullable = true) + private String pathImage; +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentResponse.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentResponse.java new file mode 100644 index 00000000..91fadae9 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentResponse.java @@ -0,0 +1,55 @@ +package br.edu.utfpr.servicebook.model.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.io.Serializable; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; + +@Data +@NoArgsConstructor +@EqualsAndHashCode(exclude={"assessmentProfessional"}) + +@Table(name = "assessment_responses") +@Entity +public class AssessmentResponse{ + + private static final long serialVersionUID = 1L; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private LocalDate date; + +// @EmbeddedId +// private AssessmentResponsePK id; + + @ManyToOne + @JoinColumn(name = "professional_id") + private User professional; + + private String response; + +// @ManyToOne +// @MapsId("assessmentProfessionalId") +// @JoinColumn(name = "assessment_professional") +// private AssessmentProfessional assessmentProfessional; + + @ManyToOne + @JoinColumn(name = "assessment_professional") + private AssessmentProfessional assessmentProfessional; + + + @PrePersist + public void onPersist() { + this.date = LocalDate.now(); + } + +// public AssessmentResponse(AssessmentProfessional assessmentProfessional) { +// this.assessmentProfessional = assessmentProfessional; +// this.id = new AssessmentResponsePK(assessmentProfessional.getId()); +// } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentResponsePK.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentResponsePK.java new file mode 100644 index 00000000..542c5b8f --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/AssessmentResponsePK.java @@ -0,0 +1,18 @@ +package br.edu.utfpr.servicebook.model.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Embeddable; +import java.io.Serializable; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Embeddable +public class AssessmentResponsePK implements Serializable { + + Long assessmentProfessionalId; + +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/CompanyProfessional.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/CompanyProfessional.java new file mode 100644 index 00000000..aea09155 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/CompanyProfessional.java @@ -0,0 +1,60 @@ +package br.edu.utfpr.servicebook.model.entity; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Cascade; + +import javax.persistence.*; + +/** + * Classe para armazenar as informações necessárias para a classe auxiliar n x n + */ +@Data +@NoArgsConstructor + +@Table(name = "company_professionals") +@Entity +public class CompanyProfessional { + private static final long serialVersionUID = 1L; + + @EmbeddedId + private CompanyProfessionalPK id; + private Integer rating; + private boolean isConfirmed; + private String email; + + @ManyToOne() + @MapsId("professionalId") + @JoinColumn(name = "professional_id") + private User professional; + + @ManyToOne() + @MapsId("companyId") + @JoinColumn(name = "company_id") + private User company; + + public CompanyProfessional(User company, User professional, boolean isConfirmed){ + this.professional = professional; + this.company = company; + this.isConfirmed = isConfirmed; + this.id = new CompanyProfessionalPK(company.getId(), professional.getId()); + } + + public CompanyProfessional(User company, User professional){ + this.professional = professional; + this.company = company; + this.id = new CompanyProfessionalPK(company.getId(), professional.getId()); + } + + public CompanyProfessional(User company, String email, User professional){ + this.company = company; + this.email = email; + this.professional = professional; + this.id = new CompanyProfessionalPK(company.getId(), professional.getId()); + } + + public CompanyProfessional(User company, String email){ + this.company = company; + this.email = email; + this.id = new CompanyProfessionalPK(company.getId(), professional.getId()); + } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/CompanyProfessionalPK.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/CompanyProfessionalPK.java new file mode 100644 index 00000000..40eb398f --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/CompanyProfessionalPK.java @@ -0,0 +1,19 @@ +package br.edu.utfpr.servicebook.model.entity; +import lombok.*; + +import javax.persistence.Embeddable; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import java.io.Serializable; + +/** + * Classe auxiliar para chave composta em um relacionamento n x n + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Embeddable +public class CompanyProfessionalPK implements Serializable { + Long companyId; + Long professionalId; +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/DurationService.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/DurationService.java new file mode 100644 index 00000000..6baf0682 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/DurationService.java @@ -0,0 +1,23 @@ +package br.edu.utfpr.servicebook.model.entity; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +import javax.persistence.*; + +@Data +@NoArgsConstructor +@RequiredArgsConstructor +@Table(name = "duration_services") +@Entity +public class DurationService { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NonNull + @Column(unique = true) + private String name; +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/JobRequest.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/JobRequest.java index 11a73c12..87d06093 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/entity/JobRequest.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/JobRequest.java @@ -6,6 +6,7 @@ import javax.persistence.*; +import br.edu.utfpr.servicebook.model.dto.ClientMinDTO; import lombok.*; @Data @@ -39,7 +40,7 @@ public enum Status { @ManyToOne @JoinColumn(name = "client_id") private User user; - + @ManyToOne @JoinColumn(name = "expertise_id") private Expertise expertise; @@ -76,6 +77,10 @@ public enum Status { @OneToMany(mappedBy = "jobRequest", cascade = CascadeType.REMOVE) Set jobCandidates = new HashSet<>(); + @ManyToOne + @JoinColumn(name = "professional_service_offering") + private ProfessionalServiceOffering serviceOffering; + @PrePersist public void onPersist(){ this.dateCreated = LocalDate.now(); diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/Payment.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/Payment.java new file mode 100644 index 00000000..72ff1206 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/Payment.java @@ -0,0 +1,31 @@ +package br.edu.utfpr.servicebook.model.entity; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +import javax.persistence.*; +import java.util.List; + +@Data +@NoArgsConstructor +@RequiredArgsConstructor +@Table(name = "payments") +@Entity +public class Payment { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NonNull + @Column(unique = true) + private Long paymentId; + + @NonNull + @Column() + private String status; + + @OneToMany(mappedBy = "payment", cascade = CascadeType.ALL) + private List paymentJobs; +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/PaymentJobRequest.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/PaymentJobRequest.java new file mode 100644 index 00000000..57fa8c8d --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/PaymentJobRequest.java @@ -0,0 +1,32 @@ +package br.edu.utfpr.servicebook.model.entity; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; + +import javax.persistence.*; +import java.util.Date; +import java.util.List; +@Data +@NoArgsConstructor +@Table(name = "payments_jobRequests") +@Entity +public class PaymentJobRequest { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NonNull + private Long jobRequestId; + + @ManyToOne + @JoinColumn(name = "payment_id", nullable = false) + private Payment payment; + + @ManyToOne + @JoinColumn(name = "jobrequest_id") + private JobRequest jobRequest; + + @Temporal(TemporalType.DATE) + private Date dateCreated; +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/PaymentVoucher.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/PaymentVoucher.java new file mode 100644 index 00000000..c01c7686 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/PaymentVoucher.java @@ -0,0 +1,32 @@ +package br.edu.utfpr.servicebook.model.entity; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.util.Date; + +@Data +@NoArgsConstructor +@Table(name = "payment_vouchers") +@Entity +public class PaymentVoucher { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String code; + + @ManyToOne + @JoinColumn(name = "client_id") + private User client; + + @ManyToOne + @JoinColumn(name = "professional_id") + private User professional; + + @ManyToOne + @JoinColumn(name = "jobrequest_id") + private JobRequest jobRequest; + +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/PriceUnit.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/PriceUnit.java new file mode 100644 index 00000000..68950fc4 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/PriceUnit.java @@ -0,0 +1,23 @@ +package br.edu.utfpr.servicebook.model.entity; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +import javax.persistence.*; + +@Data +@NoArgsConstructor +@RequiredArgsConstructor +@Table(name = "price_units") +@Entity +public class PriceUnit { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NonNull + @Column(unique = true) + private String name; +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServiceOffering.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServiceOffering.java index ff6474ec..ceedf876 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServiceOffering.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServiceOffering.java @@ -13,7 +13,7 @@ * Ele pode ter várias customizações para um mesmo serviço cadastrado pelo Administrador. */ @Data -@Table(name = "professional_service_offerings") + @Table(name = "professional_service_offerings") @NoArgsConstructor @Entity public class ProfessionalServiceOffering { @@ -23,6 +23,19 @@ public class ProfessionalServiceOffering { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + public enum Type { + INDIVIDUAL, + COMBINED_PACKAGE, + SIMPLE_PACKAGE + } + + /** + * Tipo de anúncio. + */ + @Enumerated(EnumType.STRING) + private ProfessionalServiceOffering.Type type; + + /** * Nome do serviço. * O profissional pode customizar o nome do serviço cadastrado pelo administrador de várias maneiras, dependendo @@ -46,6 +59,16 @@ public class ProfessionalServiceOffering { */ private Long price; + /** + * Unidade de preço do serviço. + */ + private String unit; + + /** + * Duração do serviço. + */ + private String duration; + /** * Serviço cadastrado pelo administrador. * O profissional pode customizar a descrição do serviço cadastrado pelo administrador de várias maneiras, dependendo @@ -55,6 +78,12 @@ public class ProfessionalServiceOffering { @JoinColumn(name = "service_id") private Service service; + /** + * Especialidade do anúncio. + */ + @ManyToOne + private Expertise expertise; + /** * Profissional que oferece o serviço. */ diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServiceOfferingAdItemPK.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServiceOfferingAdItemPK.java index a8aa64a2..ad03b0ab 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServiceOfferingAdItemPK.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServiceOfferingAdItemPK.java @@ -16,6 +16,7 @@ @AllArgsConstructor @Embeddable public class ProfessionalServiceOfferingAdItemPK implements Serializable { + Long professionalServiceOfferingId; Long professionalServiceOfferingAdId; diff --git a/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServicePackageOffering.java b/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServicePackageOffering.java index 88bc74f1..1a043cd5 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServicePackageOffering.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/entity/ProfessionalServicePackageOffering.java @@ -64,6 +64,21 @@ public enum Type { */ private Long price; + /** + * Unidade de preço do serviço. + */ + private String unit; + + /** + * Duração do serviço. + */ + private String duration; + + /** + * Quantidade, para o pacote de serviços. + * */ + private Integer amount; + /** * Usuário que criou o anúncio. */ @@ -75,4 +90,13 @@ public enum Type { */ @ManyToOne private Expertise expertise; + + /** + * Serviço cadastrado pelo administrador. + * O profissional pode customizar a descrição do serviço cadastrado pelo administrador de várias maneiras, dependendo + * do tipo de particularidade que o seu serviço tem. + */ + @ManyToOne + @JoinColumn(name = "service_id") + private Service service; } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/AssessmentProfessionalFileMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/AssessmentProfessionalFileMapper.java new file mode 100644 index 00000000..367692d9 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/AssessmentProfessionalFileMapper.java @@ -0,0 +1,28 @@ +package br.edu.utfpr.servicebook.model.mapper; + +import br.edu.utfpr.servicebook.model.dto.AssessmentProfessionalFileDTO; +import br.edu.utfpr.servicebook.model.dto.ServiceDTO; +import br.edu.utfpr.servicebook.model.entity.AssessmentProfessionalFiles; +import br.edu.utfpr.servicebook.model.entity.Service; +import org.modelmapper.ModelMapper; +import org.modelmapper.convention.MatchingStrategies; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class AssessmentProfessionalFileMapper { + @Autowired + private ModelMapper mapper; + + public AssessmentProfessionalFileDTO toDto(AssessmentProfessionalFiles entity){ + AssessmentProfessionalFileDTO dto = mapper.map(entity, AssessmentProfessionalFileDTO.class); + return dto; + } + + public AssessmentProfessionalFiles toEntity(AssessmentProfessionalFileDTO dto){ + mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); + AssessmentProfessionalFiles entity = mapper.map(dto, AssessmentProfessionalFiles.class); + return entity; + } + +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/AssessmentProfessionalMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/AssessmentProfessionalMapper.java new file mode 100644 index 00000000..2ad95435 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/AssessmentProfessionalMapper.java @@ -0,0 +1,62 @@ +package br.edu.utfpr.servicebook.model.mapper; + +import br.edu.utfpr.servicebook.model.dto.*; +import br.edu.utfpr.servicebook.model.entity.*; +import br.edu.utfpr.servicebook.util.DateUtil; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.List; + +@Component +public class AssessmentProfessionalMapper { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + + @Autowired + private ModelMapper mapper; + + @Autowired + private AssessmentProfessionalFileMapper assessmentProfessionalFileMapper; + public AssessmentProfessionalDTO toDTO(AssessmentProfessional entity) { + return mapper.map(entity, AssessmentProfessionalDTO.class); + } + + public AssessmentProfessionalDTO toResponseDTO(AssessmentProfessional entity) { + AssessmentProfessionalDTO dto = mapper.map(entity, AssessmentProfessionalDTO.class); + return dto; + } + + public AssessmentProfessional toEntity(AssessmentProfessionalDTO dto) { + return mapper.map(dto, AssessmentProfessional.class); + } + + public AssessmentProfessionalDTO toFullDto(AssessmentProfessional entity) { + AssessmentProfessionalDTO dto = mapper.map(entity, AssessmentProfessionalDTO.class); +// dto.setAssessmentProfessionalFiles(entity.getAssessmentProfessionalFiles()); + dto.setDate(this.dateTimeFormatter.format(entity.getDate())); + dto.setAssessmentProfessionalFiles(dto.getAssessmentProfessionalFiles()); + + dto.setAssessmentResponses(dto.getAssessmentResponses()); + return dto; + } + + + public AssessmentResponseDTO toResponseDto(AssessmentResponse entity) { + AssessmentResponseDTO dto = mapper.map(entity, AssessmentResponseDTO.class); + if(!entity.getResponse().isEmpty() ){ + dto.setResponse(entity.getResponse()); + } + + return dto; + } + + public AssessmentProfessionalFileDTO toFilesDto(AssessmentProfessionalFiles entity) { + AssessmentProfessionalFileDTO dto = mapper.map(entity, AssessmentProfessionalFileDTO.class); + dto.setImage(entity.getPathImage()); + + return dto; + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/AssessmentResponseMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/AssessmentResponseMapper.java new file mode 100644 index 00000000..d2befe96 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/AssessmentResponseMapper.java @@ -0,0 +1,25 @@ +package br.edu.utfpr.servicebook.model.mapper; + +import br.edu.utfpr.servicebook.model.dto.AssessmentProfessionalDTO; +import br.edu.utfpr.servicebook.model.dto.AssessmentResponseDTO; +import br.edu.utfpr.servicebook.model.entity.AssessmentProfessional; +import br.edu.utfpr.servicebook.model.entity.AssessmentResponse; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.format.DateTimeFormatter; + +@Component +public class AssessmentResponseMapper { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + + @Autowired + private ModelMapper mapper; + + public AssessmentResponseDTO toFullDto(AssessmentProfessional entity) { + AssessmentResponseDTO dto = mapper.map(entity, AssessmentResponseDTO.class); + + return dto; + } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/ClientMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/ClientMapper.java index c1e226a7..dddd63e5 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/mapper/ClientMapper.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/ClientMapper.java @@ -1,7 +1,11 @@ package br.edu.utfpr.servicebook.model.mapper; import br.edu.utfpr.servicebook.model.dto.ClientDTO; +import br.edu.utfpr.servicebook.model.dto.ClientMinDTO; +import br.edu.utfpr.servicebook.model.dto.ExpertiseMinDTO; +import br.edu.utfpr.servicebook.model.entity.Expertise; import br.edu.utfpr.servicebook.model.entity.Individual; +import br.edu.utfpr.servicebook.model.entity.User; import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -16,7 +20,10 @@ public ClientDTO toDto(Individual entity){ ClientDTO dto = mapper.map(entity, ClientDTO.class); return dto; } - + public ClientDTO toDto1(User entity){ + ClientDTO dto = mapper.map(entity, ClientDTO.class); + return dto; + } public ClientDTO toResponseDto(Individual entity) { ClientDTO dto = mapper.map(entity, ClientDTO.class); return dto; @@ -26,4 +33,9 @@ public Individual toEntity(ClientDTO dto) { Individual entity = mapper.map(dto, Individual.class); return entity; } + + public ClientMinDTO toMinDto(User entity){ + ClientMinDTO dto = mapper.map(entity, ClientMinDTO.class); + return dto; + } } \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/CompanyProfessionalMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/CompanyProfessionalMapper.java new file mode 100644 index 00000000..2779642d --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/CompanyProfessionalMapper.java @@ -0,0 +1,34 @@ +package br.edu.utfpr.servicebook.model.mapper; + +import br.edu.utfpr.servicebook.model.dto.CompanyProfessionalDTO; +import br.edu.utfpr.servicebook.model.dto.CompanyProfessionalDTO2; +import br.edu.utfpr.servicebook.model.dto.ProfessionalExpertiseDTO2; +import br.edu.utfpr.servicebook.model.entity.CompanyProfessional; +import br.edu.utfpr.servicebook.model.entity.ProfessionalExpertise; +import br.edu.utfpr.servicebook.model.entity.User; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +@Component +public class CompanyProfessionalMapper { + @Autowired + private ModelMapper mapper; + public CompanyProfessionalDTO2 toDTO(User entity) { + return mapper.map(entity, CompanyProfessionalDTO2.class); + } + + public CompanyProfessionalDTO2 toResponseDTO(CompanyProfessional entity) { + CompanyProfessionalDTO2 dto = mapper.map(entity, CompanyProfessionalDTO2.class); + dto.setId(entity.getId()); + dto.setName(entity.getProfessional().getName()); + dto.setEmail(entity.getProfessional().getEmail()); + dto.setProfilePicture(entity.getProfessional().getProfilePicture()); +// dto.setConfirmed(entity.getProfessional().isConfirmed())); + dto.setIsConfirmed(String.valueOf(entity.isConfirmed())); + return dto; + } + + public CompanyProfessional toEntity(CompanyProfessionalDTO dto) { + return mapper.map(dto, CompanyProfessional.class); + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/IndividualMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/IndividualMapper.java index 36cda32e..298cda4b 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/mapper/IndividualMapper.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/IndividualMapper.java @@ -2,6 +2,7 @@ import br.edu.utfpr.servicebook.model.dto.*; +import br.edu.utfpr.servicebook.model.entity.Expertise; import br.edu.utfpr.servicebook.model.entity.Individual; import br.edu.utfpr.servicebook.util.UserTemplateInfo; import org.modelmapper.ModelMapper; diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/JobContractedMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/JobContractedMapper.java index e3e6d201..12c55d64 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/mapper/JobContractedMapper.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/JobContractedMapper.java @@ -8,12 +8,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.time.format.DateTimeFormatter; import java.util.Optional; @Component public class JobContractedMapper { @Autowired private ModelMapper mapper; + private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); public JobContractedDTO toDto(JobContracted entity) { JobContractedDTO dto = mapper.map(entity, JobContractedDTO.class); @@ -40,7 +42,11 @@ public JobContractedFullDTO toFullDto(JobContracted entity, Optional total JobContractedFullDTO dto = mapper.map(entity, JobContractedFullDTO.class); dto.getJobRequest().setTotalCandidates(totalCandidates.get()); dto.getJobRequest().setTextualDate(DateUtil.getTextualDate((entity.getJobRequest().getDateTarget()))); - + dto.getJobRequest().setIndividual(dto.getJobRequest().getIndividual()); + if(entity.getJobRequest().getDateCreated() != null) { + dto.getJobRequest().setDateCreated(this.dateTimeFormatter.format(entity.getJobRequest().getDateCreated())); + } + dto.setTodoDate(this.dateTimeFormatter.format(entity.getTodoDate())); return dto; } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/JobRequestMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/JobRequestMapper.java index 80a722b7..5780cd30 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/mapper/JobRequestMapper.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/JobRequestMapper.java @@ -1,10 +1,7 @@ package br.edu.utfpr.servicebook.model.mapper; -import br.edu.utfpr.servicebook.model.dto.JobRequestDTO; -import br.edu.utfpr.servicebook.model.dto.JobRequestDetailsDTO; -import br.edu.utfpr.servicebook.model.dto.JobRequestFullDTO; -import br.edu.utfpr.servicebook.model.dto.JobRequestMinDTO; +import br.edu.utfpr.servicebook.model.dto.*; import br.edu.utfpr.servicebook.model.entity.JobRequest; import br.edu.utfpr.servicebook.util.DateUtil; import org.modelmapper.ModelMapper; @@ -25,6 +22,8 @@ public class JobRequestMapper { @Autowired private ExpertiseMapper expertiseMapper; + @Autowired + private ClientMapper clientMapper; public JobRequestDTO toDto(JobRequest entity) { return mapper.map(entity, JobRequestDTO.class); } @@ -48,6 +47,7 @@ public JobRequestMinDTO toMinDto(JobRequest entity, Long amountOfCandidates) { JobRequestMinDTO dto = mapper.map(entity, JobRequestMinDTO.class); dto.setAmountOfCandidates(amountOfCandidates); dto.setExpertiseDTO(expertiseMapper.toDto(entity.getExpertise())); +// dto.setClientDTO(clientMapper.toDto1(entity.getUser())); dto.setDateCreated(this.dateTimeFormatter.format(entity.getDateCreated())); dto.setDateTarget(this.dateTimeFormatter.format(entity.getDateTarget())); @@ -67,6 +67,8 @@ public JobRequestFullDTO toFullDto(JobRequest entity, Optional totalCandid dto.setDateCreated(this.dateTimeFormatter.format(entity.getDateCreated())); dto.setDateTarget(this.dateTimeFormatter.format(entity.getDateTarget())); dto.setTextualDate(DateUtil.getTextualDate((entity.getDateTarget()))); + dto.setUser(entity.getUser()); + dto.setJobImages(entity.getJobImages()); return dto; } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/PaymentJobMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/PaymentJobMapper.java new file mode 100644 index 00000000..09621867 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/PaymentJobMapper.java @@ -0,0 +1,24 @@ +package br.edu.utfpr.servicebook.model.mapper; + +import br.edu.utfpr.servicebook.model.dto.PaymentJobDTO; +import br.edu.utfpr.servicebook.model.dto.PaymentVoucherDTO; +import br.edu.utfpr.servicebook.model.entity.PaymentJobRequest; +import br.edu.utfpr.servicebook.model.entity.PaymentVoucher; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class PaymentJobMapper { + @Autowired + private ModelMapper mapper; + + public PaymentJobDTO toDTO(PaymentJobRequest entity) { + return mapper.map(entity, PaymentJobDTO.class); + } + + public PaymentJobRequest toEntity(PaymentJobDTO dto) { + PaymentJobRequest entity = mapper.map(dto, PaymentJobRequest.class); + return entity; + } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/PaymentMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/PaymentMapper.java new file mode 100644 index 00000000..a961716c --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/PaymentMapper.java @@ -0,0 +1,27 @@ +package br.edu.utfpr.servicebook.model.mapper; + + +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import br.edu.utfpr.servicebook.model.dto.PaymentDTO; +import br.edu.utfpr.servicebook.model.entity.Payment; + +@Component +public class PaymentMapper { + + @Autowired + private ModelMapper mapper; + + public PaymentDTO toDto(Payment entity) { + PaymentDTO dto = mapper.map(entity, PaymentDTO.class); + return dto; + } + + public Payment toEntity(PaymentDTO dto) { + Payment entity = mapper.map(dto, Payment.class); + return entity; + } + +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/PaymentVoucherMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/PaymentVoucherMapper.java new file mode 100644 index 00000000..886ec30d --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/PaymentVoucherMapper.java @@ -0,0 +1,24 @@ +package br.edu.utfpr.servicebook.model.mapper; + +import br.edu.utfpr.servicebook.model.dto.PaymentVoucherDTO; +import br.edu.utfpr.servicebook.model.dto.ProfessionalExpertiseDTO; +import br.edu.utfpr.servicebook.model.entity.PaymentVoucher; +import br.edu.utfpr.servicebook.model.entity.ProfessionalExpertise; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class PaymentVoucherMapper { + @Autowired + private ModelMapper mapper; + + public PaymentVoucherDTO toDTO(PaymentVoucher entity) { + return mapper.map(entity, PaymentVoucherDTO.class); + } + + public PaymentVoucher toEntity(PaymentVoucherDTO dto) { + PaymentVoucher entity = mapper.map(dto, PaymentVoucher.class); + return entity; + } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/ProfessionalServiceOfferingMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/ProfessionalServiceOfferingMapper.java index 80956a23..60a6f007 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/mapper/ProfessionalServiceOfferingMapper.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/ProfessionalServiceOfferingMapper.java @@ -1,9 +1,6 @@ package br.edu.utfpr.servicebook.model.mapper; -import br.edu.utfpr.servicebook.model.dto.AddressDTO; -import br.edu.utfpr.servicebook.model.dto.ProfessionalServiceOfferingDTO; -import br.edu.utfpr.servicebook.model.entity.Address; -import br.edu.utfpr.servicebook.model.entity.City; +import br.edu.utfpr.servicebook.model.dto.*; import br.edu.utfpr.servicebook.model.entity.ProfessionalServiceOffering; import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; @@ -25,4 +22,8 @@ public ProfessionalServiceOffering toEntity(ProfessionalServiceOfferingDTO dto){ return entity; } + public ProfessionalServiceOfferingDTO toSearchItemDto(ProfessionalServiceOffering entity){ + ProfessionalServiceOfferingDTO dto = mapper.map(entity, ProfessionalServiceOfferingDTO.class); + return dto; + } } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/mapper/UserTokenMapper.java b/src/main/java/br/edu/utfpr/servicebook/model/mapper/UserTokenMapper.java new file mode 100644 index 00000000..9b614bdb --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/mapper/UserTokenMapper.java @@ -0,0 +1,25 @@ +package br.edu.utfpr.servicebook.model.mapper; + +import br.edu.utfpr.servicebook.model.dto.UserCodeDTO; +import br.edu.utfpr.servicebook.model.dto.UserTokenDTO; +import br.edu.utfpr.servicebook.model.entity.UserCode; +import br.edu.utfpr.servicebook.model.entity.UserToken; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class UserTokenMapper { + @Autowired + private ModelMapper mapper; + + public UserTokenDTO toDto(UserToken entity) { + UserTokenDTO dto = mapper.map(entity, UserTokenDTO.class); + return dto; + } + + public UserToken toEntity(UserTokenDTO dto) { + UserToken entity = mapper.map(dto, UserToken.class); + return entity; + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/AssessmentProfessionalFileRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/AssessmentProfessionalFileRepository.java new file mode 100644 index 00000000..b54ba719 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/AssessmentProfessionalFileRepository.java @@ -0,0 +1,10 @@ +package br.edu.utfpr.servicebook.model.repository; + +import br.edu.utfpr.servicebook.model.entity.AssessmentProfessional; +import br.edu.utfpr.servicebook.model.entity.AssessmentProfessionalFiles; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface AssessmentProfessionalFileRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/AssessmentProfessionalRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/AssessmentProfessionalRepository.java new file mode 100644 index 00000000..75193fb4 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/AssessmentProfessionalRepository.java @@ -0,0 +1,29 @@ +package br.edu.utfpr.servicebook.model.repository; + +import br.edu.utfpr.servicebook.model.entity.*; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface AssessmentProfessionalRepository extends JpaRepository { + + List findAll(); + + List findAssessmentProfessionalById(Long id); + @Query("SELECT j FROM AssessmentProfessional j WHERE j.professional.id = :user_id AND j.jobRequest.id = :job_id") + List findAssessmentProfessionalByIdAndJobRequest(Long user_id, Long job_id); + +// @Query("SELECT j FROM AssessmentProfessional j WHERE j.professional.id = :user_id AND j.jobRequest.id = :job_id") +// List findAssessmentProfessionalByAssessmentResponses(Long user_id, Long job_id); + + @Query("SELECT j, ar FROM AssessmentProfessional j LEFT JOIN AssessmentResponse ar on ar.assessmentProfessional.id = j.id WHERE j.professional.id = :user_id AND j.jobRequest.id = :job_id") + List findAssessmentProfessionalByAssessmentResponses(Long user_id, Long job_id); + + @Query("SELECT j, ar, apf FROM AssessmentProfessional j LEFT JOIN AssessmentResponse ar on ar.assessmentProfessional.id = j.id "+ + " LEFT JOIN AssessmentProfessionalFiles apf on apf.assessmentProfessional.id = j.id WHERE j.professional.id = :user_id") + List findAssessmentProfessionalByProfessional(Long user_id); + +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/AssessmentResponseRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/AssessmentResponseRepository.java new file mode 100644 index 00000000..0e6710df --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/AssessmentResponseRepository.java @@ -0,0 +1,22 @@ +package br.edu.utfpr.servicebook.model.repository; + +import br.edu.utfpr.servicebook.model.entity.AssessmentProfessional; +import br.edu.utfpr.servicebook.model.entity.AssessmentResponse; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; +import java.util.Set; + +public interface AssessmentResponseRepository extends JpaRepository { + + List findAll(); + + List findAssessmentProfessionalById(Long id); + + Set findAllByAssessmentProfessional(AssessmentProfessional professional); + + @Query("SELECT j FROM AssessmentResponse j WHERE j.assessmentProfessional = :professional") + Set findAssessmentProfessionalById(AssessmentProfessional professional); + +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/CompanyProfessionalRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/CompanyProfessionalRepository.java new file mode 100644 index 00000000..1ba188a0 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/CompanyProfessionalRepository.java @@ -0,0 +1,56 @@ +package br.edu.utfpr.servicebook.model.repository; + +import br.edu.utfpr.servicebook.model.entity.*; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; +import java.util.Optional; +public interface CompanyProfessionalRepository extends JpaRepository { + + /** + * Retorna uma especialidade profissional, dado um profissional e sua especialidade + * + * @param user + * @param company + * @return Optional + */ + Optional findByProfessionalAndCompany(User company, User user); + + @Query("SELECT pe FROM CompanyProfessional pe WHERE pe.professional.id = :professional_id AND pe.company.id = :company_id") + Optional findByProfessionalAndCompany1(@Param("professional_id") Long professional_id, @Param("company_id") Long company_id); + + + @Query("select distinct p from User p left join CompanyProfessional pe on p.id = pe.professional.id where " + + "lower(p.name) like lower(concat('%', :term, '%'))" + + "or lower(p.email) like lower(concat('%', :term, '%')) " ) + List findDistinctByTermIgnoreCase(String term); + + List findByProfessional(User company); + + /** + * Retorna a avaliação da especialidade de um profissional + * + * @param professional_id + * @param company_id + * @return Optional + */ + @Query("SELECT pe.rating FROM CompanyProfessional pe WHERE pe.professional.id = :professional_id AND pe.company.id = :company_id") + Optional selectRatingByProfessionalAndExpertise(@Param("professional_id") Long professional_id, @Param("company_id") Long company_id); + + + @Query("SELECT pe FROM CompanyProfessional pe left join User u on pe.professional.id = u.id WHERE pe.company.id = :company_id") + List findByCompany(@Param("company_id") Long company_id); + + /** + * Retorna uma especialidade profissional, dado um profissional e sua especialidade + * + * @param company + * @param professional + * @return Optional + */ + Optional findByCompanyAndProfessional(User company, User professional); + + +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/IndividualRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/IndividualRepository.java index 93828008..409c7c50 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/repository/IndividualRepository.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/IndividualRepository.java @@ -1,6 +1,11 @@ package br.edu.utfpr.servicebook.model.repository; +import br.edu.utfpr.servicebook.model.dto.IndividualDTO; +import br.edu.utfpr.servicebook.model.dto.ProfessionalSearchItemDTO; +import br.edu.utfpr.servicebook.model.entity.Category; +import br.edu.utfpr.servicebook.model.entity.Expertise; import br.edu.utfpr.servicebook.model.entity.Individual; +import br.edu.utfpr.servicebook.model.entity.Service; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; @@ -53,4 +58,32 @@ Page findDistinctByTermIgnoreCaseWithPagination( "or lower(p.description) like lower(concat('%', :term, '%')) " + "or lower(pe.expertise.name) like lower(concat('%', :term, '%'))") List findDistinctByTermIgnoreCase(String term); + + @Query("select p from Individual p left join ProfessionalServiceOffering pe on p.id = pe.user.id where " + + "pe.service = :term") + Page findAllIndividualsByService( + Service term, + Pageable pageable); + + @Query("select p from Individual p left join ProfessionalExpertise pe on p.id = pe.professional.id " + + "where pe.expertise.id = 4") + List findAllIndividualsAutonomosByService( + Long term, + Pageable pageable); + + @Query("select distinct p from Individual p left join ProfessionalExpertise pe on p.id = pe.professional.id " + + " left join Expertise ex on pe.expertise.id = ex.id "+ + "where pe.expertise = :expertiseId ") + Page findDistinctByExpertiseAndCategoryPagination( + Expertise expertiseId, + Pageable pageable); + + @Query("select distinct ex from Individual p left join ProfessionalExpertise pe on p.id = pe.professional.id " + + " left join Expertise ex on pe.expertise.id = ex.id "+ + "where pe.expertise = :expertiseId or pe.expertise.category = :categoryId") + Page listByExpertiseAndCategory( + Expertise expertiseId, + Category categoryId, + Pageable pageable); + } \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/JobCandidateRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/JobCandidateRepository.java index 36365e67..4bffa6cf 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/repository/JobCandidateRepository.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/JobCandidateRepository.java @@ -88,7 +88,7 @@ public interface JobCandidateRepository extends JpaRepository findByJobIdAndUserId(Long jobId, Long userId); diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/JobImagesRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/JobImagesRepository.java index c30815e9..8b257431 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/repository/JobImagesRepository.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/JobImagesRepository.java @@ -1,9 +1,14 @@ package br.edu.utfpr.servicebook.model.repository; import br.edu.utfpr.servicebook.model.entity.JobImages; +import br.edu.utfpr.servicebook.model.entity.JobRequest; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface JobImagesRepository extends JpaRepository { + + List findJobImagesByJobRequest(JobRequest jobRequest); } \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/PaymentJobRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/PaymentJobRepository.java new file mode 100644 index 00000000..4125693f --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/PaymentJobRepository.java @@ -0,0 +1,22 @@ +package br.edu.utfpr.servicebook.model.repository; + +import br.edu.utfpr.servicebook.model.entity.JobRequest; +import br.edu.utfpr.servicebook.model.entity.PaymentJobRequest; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface PaymentJobRepository extends JpaRepository { + List findAll(); + + Page findAll(Pageable pageable); + + List findAllById(Iterable longs); + + Optional findByJobRequest(JobRequest id); +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/PaymentRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/PaymentRepository.java new file mode 100644 index 00000000..68bfd1c7 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/PaymentRepository.java @@ -0,0 +1,18 @@ +package br.edu.utfpr.servicebook.model.repository; + +import br.edu.utfpr.servicebook.model.entity.JobRequest; +import br.edu.utfpr.servicebook.model.entity.Payment; + +import br.edu.utfpr.servicebook.model.entity.PaymentJobRequest; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface PaymentRepository extends JpaRepository{ + + Optional findByPaymentId(Long id); + +} + diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/PaymentVoucherRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/PaymentVoucherRepository.java new file mode 100644 index 00000000..db2bf473 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/PaymentVoucherRepository.java @@ -0,0 +1,22 @@ +package br.edu.utfpr.servicebook.model.repository; + +import br.edu.utfpr.servicebook.model.entity.PaymentVoucher; +import br.edu.utfpr.servicebook.model.entity.Service; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface PaymentVoucherRepository extends JpaRepository { + + List findAll(); + + + Page findAll(Pageable pageable); + + List findAllById(Iterable longs); +} diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServiceOfferingAdItemRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServiceOfferingAdItemRepository.java index 9abab248..f3229144 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServiceOfferingAdItemRepository.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServiceOfferingAdItemRepository.java @@ -1,9 +1,8 @@ package br.edu.utfpr.servicebook.model.repository; -import br.edu.utfpr.servicebook.model.entity.ProfessionalServicePackageOffering; -import br.edu.utfpr.servicebook.model.entity.ProfessionalServiceOfferingAdItem; -import br.edu.utfpr.servicebook.model.entity.ProfessionalServiceOfferingAdItemPK; +import br.edu.utfpr.servicebook.model.entity.*; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import java.util.List; @@ -17,9 +16,23 @@ public interface ProfessionalServiceOfferingAdItemRepository extends JpaReposito */ List findAllByProfessionalServicePackageOffering(ProfessionalServicePackageOffering professionalServicePackageOffering); + /** + * Retorna os serviços que o usuário possui. + * @param user + * @return + */ +// @Query("SELECT u FROM ProfessionalServiceOffering u WHERE EXISTS (SELECT pe FROM ProfessionalServicePackageOffering pe WHERE pe.user = :user)") +// List findProfessionalServiceOfferingAdItemsByUser(User user); +// @Query("SELECT u FROM ProfessionalServiceOffering u JOIN u.packageOfferings pe WHERE pe.user = :user") +// List findProfessionalServiceOfferingAdItemsByUser(User user); +// + @Query("SELECT u FROM ProfessionalServiceOfferingAdItem u JOIN u.professionalServiceOffering pso JOIN u.professionalServicePackageOffering jspo") + List findProfessionalServiceOfferingAdItemsByUserJoin(User user); - - + @Query("SELECT psa FROM ProfessionalServiceOfferingAdItem psa " + + "JOIN FETCH psa.professionalServiceOffering pso WHERE pso.user = :user") +// List findDistinctByProfessionalServiceOfferingAdItemsByProfessionalServiceOfferingEndingWithAndProfessionalServicePackageOffering(User user); + List findProfessionalServiceOfferingAdItemsWithRelatedEntities(User user); } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServiceOfferingRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServiceOfferingRepository.java index b792a723..b40c6fd5 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServiceOfferingRepository.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServiceOfferingRepository.java @@ -1,6 +1,8 @@ package br.edu.utfpr.servicebook.model.repository; import br.edu.utfpr.servicebook.model.entity.*; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @@ -18,6 +20,8 @@ public interface ProfessionalServiceOfferingRepository extends JpaRepository findProfessionalServiceOfferingByUser(User user); + public List findFirst3ByUserAndType(User user, Enum type); + public List findByUserAndType(User user, Enum type); /** * Busca todas os serviços de um profissional @@ -63,6 +67,51 @@ public interface ProfessionalServiceOfferingRepository extends JpaRepository findProfessionalServiceOfferingByName(String name); + @Query("select distinct p from ProfessionalServiceOffering p left join Service pe on p.service = pe where " + + "lower(p.name) like lower(concat('%', :term, '%'))" + + "or lower(p.description) like lower(concat('%', :term, '%')) " + + "or lower(pe.expertise.name) like lower(concat('%', :term, '%'))") + Page findDistinctByTermIgnoreCaseWithPagination( + String term, + Pageable pageable); + @Query("SELECT e FROM ProfessionalServiceOffering e WHERE e.service = :id") + public Optional findProfessionalServiceOfferingById(Long id); + /** + * Busca o serviço atraves dos anuncios gravados. + * @param term + * @param pageable + * @return + */ + @Query("select pe from Individual p left join ProfessionalServiceOffering pe on p = pe.user where " + + "pe.service = :term") + Page findAllIndividualsByService( + Service term, + Pageable pageable); + + /** + * Retorna os serviços que o usuário possui. + * @param user + * @return + */ + @Query("SELECT u FROM ProfessionalServiceOfferingAdItem u WHERE EXISTS (SELECT pe FROM ProfessionalServiceOffering pe WHERE pe.user = :user)") + List findProfessionalServiceOfferingAdItemsByUser(User user); + + @Query("SELECT u FROM ProfessionalServiceOffering u JOIN ProfessionalServiceOfferingAdItem r WHERE r.professionalServiceOffering.id = u.id") + public List findProfessionalServiceOfferingAdItemsByUserJoin(User user); + + @Query("SELECT u FROM ProfessionalServiceOfferingAdItem u JOIN FETCH u.professionalServicePackageOffering") + List findDistinctProfessionalServiceOfferings(); + + @Query("SELECT e FROM ProfessionalServiceOffering e WHERE e.user.id = :userId AND e.service.expertise.id = :expertiseId") + public Optional findProfessionalServiceOfferingByExpertiseAAndUser(Long userId, Long expertiseId); + + @Query("SELECT e FROM ProfessionalServiceOffering e WHERE e.user.id = :user and e.service.id = :service") + public List findProfessionalServiceOfferingByServiceAndUser(Long service, Long user); + + public Optional findById(Long id); + + @Query("SELECT e FROM ProfessionalServiceOffering e WHERE e.id = :id and e.user.id = :user") + public Optional findProfessionalServiceOfferingByIdAndUser(Long id, Long user); } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServicePackageOfferingRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServicePackageOfferingRepository.java index ab0a9054..7fcfdd2d 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServicePackageOfferingRepository.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/ProfessionalServicePackageOfferingRepository.java @@ -24,5 +24,10 @@ public interface ProfessionalServicePackageOfferingRepository extends JpaReposit /** * Busca os anúncios de um dado profissional. */ - public List findAllByUser(User user); + public List findFirst3ByUserAndType(User user, Enum type); + + public List findByUserAndType(User user, Enum type); + + @Query("SELECT po FROM ProfessionalServiceOfferingAdItem poa INNER JOIN ProfessionalServiceOffering po ON poa.professionalServiceOffering = po WHERE po.user = :userId") + public List findAllByCombinedAndItems(User userId); } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/UserRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/UserRepository.java index 5d0f727d..681de995 100644 --- a/src/main/java/br/edu/utfpr/servicebook/model/repository/UserRepository.java +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/UserRepository.java @@ -55,5 +55,6 @@ public interface UserRepository extends JpaRepository { @Query("SELECT u FROM User u WHERE EXISTS (SELECT pe FROM ProfessionalExpertise pe WHERE pe.professional = u AND pe.expertise = :expertise)") List findByExpertise(Expertise expertise); - + @Query("SELECT e FROM User e WHERE e.profile = 'ROLE_USER'") + List findProfessionals(); } diff --git a/src/main/java/br/edu/utfpr/servicebook/model/repository/UserTokenRepository.java b/src/main/java/br/edu/utfpr/servicebook/model/repository/UserTokenRepository.java new file mode 100644 index 00000000..74df2221 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/model/repository/UserTokenRepository.java @@ -0,0 +1,18 @@ +package br.edu.utfpr.servicebook.model.repository; + +import br.edu.utfpr.servicebook.model.entity.Company; +import br.edu.utfpr.servicebook.model.entity.User; +import br.edu.utfpr.servicebook.model.entity.UserToken; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +public interface UserTokenRepository extends JpaRepository { + + @Query("SELECT t FROM UserToken t WHERE t.token = :token") + UserToken findByToken(@Param("token")String token); +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/service/AssessmentProfessionalFileService.java b/src/main/java/br/edu/utfpr/servicebook/service/AssessmentProfessionalFileService.java new file mode 100644 index 00000000..50e289bf --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/service/AssessmentProfessionalFileService.java @@ -0,0 +1,29 @@ +package br.edu.utfpr.servicebook.service; + +import br.edu.utfpr.servicebook.model.entity.AssessmentProfessionalFiles; +import br.edu.utfpr.servicebook.model.repository.AssessmentProfessionalFileRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +public class AssessmentProfessionalFileService { + + @Autowired + private AssessmentProfessionalFileRepository repository; + + public AssessmentProfessionalFiles save(AssessmentProfessionalFiles entity){ + return repository.save(entity); + } + + public void delete(Long id){ + repository.deleteById(id); + } + + public List findAll(){ + return this.repository.findAll(); + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/service/AssessmentProfessionalService.java b/src/main/java/br/edu/utfpr/servicebook/service/AssessmentProfessionalService.java new file mode 100644 index 00000000..54b4bb6a --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/service/AssessmentProfessionalService.java @@ -0,0 +1,45 @@ +package br.edu.utfpr.servicebook.service; + +import br.edu.utfpr.servicebook.model.entity.*; +import br.edu.utfpr.servicebook.model.repository.AssessmentProfessionalRepository; +import br.edu.utfpr.servicebook.model.repository.ProfessionalExpertiseRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class AssessmentProfessionalService { + + @Autowired + private AssessmentProfessionalRepository assessmentProfessionalRepository; + + public List findAll() { + return this.assessmentProfessionalRepository.findAll(); + } + + public AssessmentProfessional save(AssessmentProfessional assessmentProfessional) { + return this.assessmentProfessionalRepository.save(assessmentProfessional); + } + + public Optional findById(Long assessmentProfessional){ + return this.assessmentProfessionalRepository.findById(assessmentProfessional); + } + + public List findByProfessionalId(Long professional_id){ + return this.assessmentProfessionalRepository.findAssessmentProfessionalById(professional_id); + } + + public List findAssessmentProfessionalByIdAndJobRequest(Long professional_id, Long job_id){ + return this.assessmentProfessionalRepository.findAssessmentProfessionalByIdAndJobRequest(professional_id, job_id); + } + + public List findAssessmentProfessionalByAssessmentResponses(Long professional_id, Long job_id){ + return this.assessmentProfessionalRepository.findAssessmentProfessionalByAssessmentResponses(professional_id, job_id); + } + + public List findAssessmentProfessionalByProfessional(Long professional_id){ + return this.assessmentProfessionalRepository.findAssessmentProfessionalByProfessional(professional_id); + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/service/AssessmentResponseService.java b/src/main/java/br/edu/utfpr/servicebook/service/AssessmentResponseService.java new file mode 100644 index 00000000..0e00ec09 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/service/AssessmentResponseService.java @@ -0,0 +1,38 @@ +package br.edu.utfpr.servicebook.service; + +import br.edu.utfpr.servicebook.model.entity.AssessmentProfessional; +import br.edu.utfpr.servicebook.model.entity.AssessmentResponse; +import br.edu.utfpr.servicebook.model.repository.AssessmentResponseRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Set; + +@Service +public class AssessmentResponseService { + @Autowired + + private AssessmentResponseRepository assessmentResponseRepository; + + public List findAll() { + return this.assessmentResponseRepository.findAll(); + } + + public AssessmentResponse save(AssessmentResponse assessmentProfessional) { + return this.assessmentResponseRepository.save(assessmentProfessional); + } + + public List findAssessmentProfessionalById(Long id) { + return this.assessmentResponseRepository.findAssessmentProfessionalById(id); + } + + public Set findAllByAssessmentProfessional(AssessmentProfessional assessmentProfessional) { + return this.assessmentResponseRepository.findAllByAssessmentProfessional(assessmentProfessional); + } + + + public Set findAssessmentProfessionalById(AssessmentProfessional assessmentProfessional) { + return this.assessmentResponseRepository.findAssessmentProfessionalById(assessmentProfessional); + } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/service/CompanyProfessionalService.java b/src/main/java/br/edu/utfpr/servicebook/service/CompanyProfessionalService.java new file mode 100644 index 00000000..22c310a1 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/service/CompanyProfessionalService.java @@ -0,0 +1,49 @@ +package br.edu.utfpr.servicebook.service; + + +import br.edu.utfpr.servicebook.model.entity.*; +import br.edu.utfpr.servicebook.model.repository.CompanyProfessionalRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class CompanyProfessionalService { + + @Autowired + private CompanyProfessionalRepository companyProfessionalRepository; + + public Optional findByProfessionalAndCompany(User company, User individual) { + return this.companyProfessionalRepository.findByProfessionalAndCompany(company, individual); + } + + public CompanyProfessional save(CompanyProfessional companyProfessional) { + return this.companyProfessionalRepository.save(companyProfessional); + } + + public void delete(CompanyProfessionalPK professional_id){ + companyProfessionalRepository.deleteById(professional_id); + } + + public List findDistinctByTermIgnoreCase(String searchTerm){ + return this.companyProfessionalRepository.findDistinctByTermIgnoreCase(searchTerm); + } + + public Optional selectRatingByProfessionalAndExpertise(Long professional_id, Long expertise_id) { + return this.companyProfessionalRepository.selectRatingByProfessionalAndExpertise(professional_id, expertise_id); + } + + public List findByCompany(Long user) {return this.companyProfessionalRepository.findByCompany(user);} + + public List findByProfessional(User individual) { + return this.companyProfessionalRepository.findByProfessional(individual); + } + + public Optional findByCompanyAndProfessional(User company, User professional) { + return this.companyProfessionalRepository.findByCompanyAndProfessional(company, professional); + } + + +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/service/EmailSenderService.java b/src/main/java/br/edu/utfpr/servicebook/service/EmailSenderService.java index 1dadb022..d6f389ce 100644 --- a/src/main/java/br/edu/utfpr/servicebook/service/EmailSenderService.java +++ b/src/main/java/br/edu/utfpr/servicebook/service/EmailSenderService.java @@ -2,14 +2,17 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.ByteArrayResource; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; +import java.io.IOException; @Service public class EmailSenderService { @@ -53,4 +56,18 @@ public void sendHTMLEmail(String to, String subject, String html) throws Messagi mailSender.send(message); } + public void sendEmailWithAttachment(String to, String subject, String html, byte[] pdfBytes, String pdfFileName) throws MessagingException, IOException { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true); + + helper.setTo(to); + helper.setSubject(subject); + helper.setText(html, true); + + // Adicionar o anexo ao email + helper.addAttachment(pdfFileName, new ByteArrayResource(pdfBytes)); + + mailSender.send(message); + + } } diff --git a/src/main/java/br/edu/utfpr/servicebook/service/IndividualService.java b/src/main/java/br/edu/utfpr/servicebook/service/IndividualService.java index 59d2fa0f..a201c701 100644 --- a/src/main/java/br/edu/utfpr/servicebook/service/IndividualService.java +++ b/src/main/java/br/edu/utfpr/servicebook/service/IndividualService.java @@ -1,6 +1,8 @@ package br.edu.utfpr.servicebook.service; import br.edu.utfpr.servicebook.model.dto.ExpertiseDTO; +import br.edu.utfpr.servicebook.model.dto.IndividualDTO; +import br.edu.utfpr.servicebook.model.dto.ProfessionalSearchItemDTO; import br.edu.utfpr.servicebook.model.entity.*; import br.edu.utfpr.servicebook.model.mapper.ExpertiseMapper; import br.edu.utfpr.servicebook.model.repository.CompanyRepository; @@ -129,11 +131,30 @@ public User getAuthenticated(){ return null; } + public Page findAllIndividualsByService(br.edu.utfpr.servicebook.model.entity.Service searchTerm, Integer page, Integer size){ + PageRequest pageRequest = PageRequest.of(page - 1, size); + return this.individualRepository.findAllIndividualsByService(searchTerm, pageRequest); + } + public List findAllIndividualsAutonomosByService(Long searchTerm, Integer page, Integer size){ + PageRequest pageRequest = PageRequest.of(page - 1, size); + return this.individualRepository.findAllIndividualsAutonomosByService(searchTerm, pageRequest); + } @Transactional public void saveExpertisesCompany(Company company, ProfessionalExpertise professionalExpertise) { professionalExpertiseRepository.save(professionalExpertise); companyRepository.save(company); } + + public Page findDistinctByExpertiseAndCategoryPagination(Expertise expertiseId, Integer page, Integer size){ + PageRequest pageRequest = PageRequest.of(page - 1, size); + return this.individualRepository.findDistinctByExpertiseAndCategoryPagination(expertiseId, pageRequest); + } + + public Page listByExpertiseAndCategory(Expertise expertiseId, Category categoryId, Integer page, Integer size){ + PageRequest pageRequest = PageRequest.of(page - 1, size); + return this.individualRepository.listByExpertiseAndCategory(expertiseId, categoryId, pageRequest); + } + } \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/service/JobImagesService.java b/src/main/java/br/edu/utfpr/servicebook/service/JobImagesService.java index 01d1adeb..f7557eb4 100644 --- a/src/main/java/br/edu/utfpr/servicebook/service/JobImagesService.java +++ b/src/main/java/br/edu/utfpr/servicebook/service/JobImagesService.java @@ -1,6 +1,7 @@ package br.edu.utfpr.servicebook.service; import br.edu.utfpr.servicebook.model.entity.JobImages; +import br.edu.utfpr.servicebook.model.entity.JobRequest; import br.edu.utfpr.servicebook.model.repository.JobImagesRepository; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -26,4 +27,9 @@ public void delete(Long id){ public List findAll(){ return this.repository.findAll(); } + + public List findJobImagesByJobRequest(JobRequest jobRequest){ + return this.repository.findJobImagesByJobRequest(jobRequest); + } + } diff --git a/src/main/java/br/edu/utfpr/servicebook/service/JobRequestService.java b/src/main/java/br/edu/utfpr/servicebook/service/JobRequestService.java index 84fdcead..286ba396 100644 --- a/src/main/java/br/edu/utfpr/servicebook/service/JobRequestService.java +++ b/src/main/java/br/edu/utfpr/servicebook/service/JobRequestService.java @@ -1,6 +1,7 @@ package br.edu.utfpr.servicebook.service; import br.edu.utfpr.servicebook.model.entity.Expertise; +import br.edu.utfpr.servicebook.model.entity.JobImages; import br.edu.utfpr.servicebook.model.entity.JobRequest; import br.edu.utfpr.servicebook.model.entity.User; import br.edu.utfpr.servicebook.model.repository.JobRequestRepository; @@ -13,8 +14,10 @@ import java.sql.Date; import java.time.LocalDate; +import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Set; @Slf4j @Service @@ -125,4 +128,9 @@ public long countByExpertise(Expertise expertise){ public long countByStatusAndExpertise(JobRequest.Status status, Expertise expertise){ return this.jobRequestRepository.countByStatusAndExpertise(status, expertise); } + + public Set getJobImagesById(Long jobId) { + Optional optionalJobRequest = jobRequestRepository.findById(jobId); + return optionalJobRequest.map(JobRequest::getJobImages).orElse(Collections.emptySet()); + } } \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/service/PaymentJobService.java b/src/main/java/br/edu/utfpr/servicebook/service/PaymentJobService.java new file mode 100644 index 00000000..0c07761e --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/service/PaymentJobService.java @@ -0,0 +1,32 @@ +package br.edu.utfpr.servicebook.service; + +import br.edu.utfpr.servicebook.model.entity.JobRequest; +import br.edu.utfpr.servicebook.model.entity.PaymentJobRequest; +import br.edu.utfpr.servicebook.model.repository.PaymentJobRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class PaymentJobService { + @Autowired + private PaymentJobRepository paymentJobRepository; + + public void save(PaymentJobRequest entity) { + paymentJobRepository.save(entity); + } + + public List findAll() { + return this.paymentJobRepository.findAll(); + } + + public Optional findById(Long id) { + return this.paymentJobRepository.findById(id); + } + + public Optional findByJobRequest(JobRequest id) { + return this.paymentJobRepository.findByJobRequest(id); + } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/service/PaymentService.java b/src/main/java/br/edu/utfpr/servicebook/service/PaymentService.java new file mode 100644 index 00000000..435a3757 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/service/PaymentService.java @@ -0,0 +1,92 @@ +package br.edu.utfpr.servicebook.service; +import java.math.BigDecimal; +import java.util.Map; +import java.util.Optional; +//import br.edu.utfpr.servicebook.model.entity.Payment; +import br.edu.utfpr.servicebook.exception.MercadoPagoException; +import br.edu.utfpr.servicebook.model.dto.CardPaymentDTO; +import br.edu.utfpr.servicebook.model.dto.PaymentResponseDTO; +import com.mercadopago.client.common.IdentificationRequest; +import com.mercadopago.client.payment.PaymentClient; +import com.mercadopago.client.payment.PaymentCreateRequest; +import com.mercadopago.client.payment.PaymentPayerRequest; +import com.mercadopago.exceptions.MPApiException; +import com.mercadopago.exceptions.MPException; +import com.mercadopago.resources.payment.Payment; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.http.*; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; +// SDK do Mercado Pago +import com.mercadopago.MercadoPagoConfig; +import br.edu.utfpr.servicebook.model.repository.PaymentRepository; + + +@Service +public class PaymentService { + + private final Environment environment; + + @Autowired + private PaymentRepository paymentRepository; + + private static final String API_URL = "https://api.mercadopago.com/v1/payments"; + private static final String ACCESS_TOKEN = "TEST-2738533774159236-052518-f4e09de99516f8d7b2adb21186313d1b-494777183"; // Substitua pelo seu token de acesso + + @Value("TEST-2738533774159236-052518-f4e09de99516f8d7b2adb21186313d1b-494777183") + private String mercadoPagoAccessToken; + + @Autowired + public PaymentService(Environment environment){ + this.environment = environment; + } + + public PaymentResponseDTO pay(CardPaymentDTO cardPaymentDTO){ + try { + MercadoPagoConfig.setAccessToken(mercadoPagoAccessToken); + + System.out.println("cardPaymentDTO"); + System.out.println(cardPaymentDTO); + + PaymentClient paymentClient = new PaymentClient(); + + PaymentCreateRequest paymentCreateRequest = + PaymentCreateRequest.builder() + .transactionAmount(BigDecimal.valueOf(1000)) + .token(cardPaymentDTO.getToken()) + .installments(cardPaymentDTO.getInstallments()) + .paymentMethodId(cardPaymentDTO.getPaymentMethodId()) + .payer( + PaymentPayerRequest.builder() + .email(cardPaymentDTO.getPayer().getEmail()) + .identification( + IdentificationRequest.builder() + .type(cardPaymentDTO.getPayer().getIdentification().getType()) + .number(cardPaymentDTO.getPayer().getIdentification().getNumber()) + .build()) + .build()) + .build(); + + Payment createdPayment = paymentClient.create(paymentCreateRequest); + + return new PaymentResponseDTO( + createdPayment.getId(), + String.valueOf(createdPayment.getStatus()), + createdPayment.getStatusDetail()); + } catch (MPApiException apiException) { + System.out.println(apiException.getApiResponse().getContent()); + throw new MercadoPagoException(apiException.getApiResponse().getContent()); + } catch (MPException exception) { + System.out.println(exception.getMessage()); + throw new MercadoPagoException(exception.getMessage()); + } + } + + public br.edu.utfpr.servicebook.model.entity.Payment save(br.edu.utfpr.servicebook.model.entity.Payment entity){ return paymentRepository.save(entity); } + + public Optional find(Long payment){ return paymentRepository.findById(payment); } + + public Optional findByPaymentId(Long payment){ return paymentRepository.findByPaymentId(payment); } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/service/PaymentServiceOLd.java b/src/main/java/br/edu/utfpr/servicebook/service/PaymentServiceOLd.java new file mode 100644 index 00000000..8af2aec5 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/service/PaymentServiceOLd.java @@ -0,0 +1,70 @@ +package br.edu.utfpr.servicebook.service; + +import br.edu.utfpr.servicebook.model.entity.Payment; +import br.edu.utfpr.servicebook.model.repository.PaymentRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.http.*; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; +import java.util.Optional; + + +@Service +public class PaymentServiceOLd { + + private final Environment environment; + + @Autowired + private PaymentRepository paymentRepository; + + private static final String API_URL = "https://api.mercadopago.com/v1/payments"; + private static final String ACCESS_TOKEN = "TEST-2738533774159236-052518-f4e09de99516f8d7b2adb21186313d1b-494777183"; // Substitua pelo seu token de acesso + + @Autowired + public PaymentServiceOLd(Environment environment){ + this.environment = environment; + } + + public ResponseEntity pay(Map paymentData){ + RestTemplate restTemplate = new RestTemplate(); + String apiUrl = "https://api.mercadopago.com/v1/payments"; + + System.out.println("restTemplate"); + System.out.println(restTemplate); + + try { + String accessToken = "TEST-2738533774159236-052518-f4e09de99516f8d7b2adb21186313d1b-494777183"; + + System.out.println("accessToken"); + System.out.println(accessToken); + + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.setBearerAuth(accessToken); + + HttpEntity> requestEntity = new HttpEntity<>(paymentData, headers); + + System.out.println("requestEntity"); + System.out.println(requestEntity); + + ResponseEntity response = restTemplate.exchange(apiUrl, HttpMethod.POST, requestEntity, Object.class); + + System.out.println("response"); + System.out.println(response); + + return response; + + } catch (Exception e) { + throw new RuntimeException("Algo deu errado! Tente novamente."); + } + + } + + public Payment save(Payment entity){ return paymentRepository.save(entity); } + + public Optional find(Long payment){ return paymentRepository.findById(payment); } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/service/PaymentVoucherService.java b/src/main/java/br/edu/utfpr/servicebook/service/PaymentVoucherService.java new file mode 100644 index 00000000..2e558ec4 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/service/PaymentVoucherService.java @@ -0,0 +1,226 @@ +package br.edu.utfpr.servicebook.service; + +import br.edu.utfpr.servicebook.model.entity.PaymentVoucher; +import br.edu.utfpr.servicebook.model.repository.PaymentVoucherRepository; +import org.apache.batik.transcoder.TranscoderException; +import org.apache.fop.configuration.ConfigurationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.w3c.dom.Document; + +import javax.xml.transform.TransformerException; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.WriterException; +import com.google.zxing.client.j2se.MatrixToImageWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import org.apache.batik.anim.dom.SAXSVGDocumentFactory; +import org.apache.batik.anim.dom.SVGDOMImplementation; +import org.apache.batik.svggen.SVGGraphics2D; +import org.apache.batik.svggen.SVGGraphics2DIOException; +import org.apache.batik.transcoder.TranscoderException; +import org.apache.batik.transcoder.TranscoderInput; +import org.apache.batik.transcoder.TranscoderOutput; +import org.apache.batik.util.XMLResourceDescriptor; +import org.apache.fop.activity.ContainerUtil; +import org.apache.fop.configuration.Configuration; +import org.apache.fop.configuration.ConfigurationException; +import org.apache.fop.configuration.DefaultConfigurationBuilder; +import org.apache.fop.svg.PDFTranscoder; +import org.springframework.stereotype.Service; +import org.springframework.util.ResourceUtils; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.svg.SVGDocument; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.awt.*; +import java.io.*; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +@Service +public class PaymentVoucherService { + + @Autowired + private PaymentVoucherRepository paymentVoucherRepository; + + public void save(PaymentVoucher entity) { + paymentVoucherRepository.save(entity); + } + + public List findAll() { + return this.paymentVoucherRepository.findAll(); + } + + public Optional findById(Long id) { + return this.paymentVoucherRepository.findById(id); + } + + /** + * Recebe a URL do template em SVG e gera o certificado em PDF, com as alterações devidas, retornando + * o File do PDF armazenado no diretório temporário local. + * @param svgCertificateTemplate + * @param name + * @param year + * @return + * @throws TranscoderException + * @throws IOException + * @throws ConfigurationException + * @throws TransformerException + */ + public File generateCertificate(String svgCertificateTemplate, String voucher, String service, String date, String date_due, + String name_client, String document_client, String fone_client, String mail_client, + String name_professional, String document_professional,String mail_professional, + String fone_professional, String endereco_pro, String payment_type, String payment_value, String qrCode, String date_document) throws TranscoderException, IOException, ConfigurationException, TransformerException { + + //busca o template de certificado em SVG na nuvem + URL url = new URL(svgCertificateTemplate); + + //realiza a customização + Document doc = updateCertificate(url.openStream(), voucher, service,date, date_due,name_client,document_client,fone_client,mail_client,name_professional, document_professional, + mail_professional, fone_professional, endereco_pro, payment_type, payment_value, qrCode, date_document); + + //persiste as alterções em um SVG temporário + File fileSVG = convertDocumentToFile(doc); + + File filePDF = convertSVGToPDF(fileSVG); + + return filePDF; + } + + /** + * Recebe o SVG de certificado e realiza as edições de texto no DOM + * @param svgInputStream + * @return + * @throws IOException + */ + private Document updateCertificate(InputStream svgInputStream, String voucher, String service, String date, String date_due, + String name_client, String document_client, String fone_client, String mail_client, + String name_professional, String document_professional,String mail_professional, + String fone_professional, String endereco_pro, String payment_type, String payment_value, String qrCodeBase64,String date_document) throws IOException { + String parser = XMLResourceDescriptor.getXMLParserClassName(); + SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser); + + Document doc = f.createDocument(null, svgInputStream); + Element dateDocument = doc.getElementById("date-document"); + dateDocument.setTextContent(date_document); + + Element numberVoucher = doc.getElementById("number-voucher"); + numberVoucher.setTextContent(voucher); + + Element nameService = doc.getElementById("service-name"); + nameService.setTextContent(service); + + Element datePurchase = doc.getElementById("date-service"); + datePurchase.setTextContent(date); + + Element dateDue = doc.getElementById("date-due"); + dateDue.setTextContent(date_due); + + Element nameClient = doc.getElementById("name-client"); + nameClient.setTextContent(name_client); + + Element documentClient = doc.getElementById("document-client"); + documentClient.setTextContent(document_client); + + Element foneClient = doc.getElementById("fone-client"); + foneClient.setTextContent(fone_client); + + Element emailClient = doc.getElementById("mail_client"); + emailClient.setTextContent(mail_client); + + Element nameProfessional = doc.getElementById("name_professional"); + nameProfessional.setTextContent(name_professional); + + Element documentProfessional = doc.getElementById("document-professional"); + documentProfessional.setTextContent(document_professional); + + Element emailProfessional = doc.getElementById("mail_professional"); + emailProfessional.setTextContent(mail_professional); + + Element foneProfessional = doc.getElementById("fone-professional"); + foneProfessional.setTextContent(fone_professional); + + Element endereco = doc.getElementById("endereco"); + endereco.setTextContent(endereco_pro); + + Element valor = doc.getElementById("valor"); + valor.setTextContent(payment_value); + +// Element qrElement = doc.getElementById("image0"); +// qrElement.setAttribute("xlink:href", qrCodeBase64); + + return doc; + } + + /** + * Recebe um document DOM e realiza a transformação em um arquivo persistido temporáriamente + * @param doc + * @return + * @throws IOException + * @throws TransformerException + */ + private File convertDocumentToFile(Document doc) throws IOException, TransformerException { + Path pathSVG = Files.createTempFile("certificado", ".svg"); + File fileSVG = pathSVG.toFile(); + FileWriter fileWriter = new FileWriter(fileSVG); + + DOMSource source = new DOMSource(doc); + StreamResult result = new StreamResult(fileWriter); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.transform(source, result); + return fileSVG; + } + + /** + * Converte um SVG para PDF + * @param fileSVG + * @return + * @throws IOException + * @throws ConfigurationException + * @throws TranscoderException + */ + private File convertSVGToPDF(File fileSVG) throws IOException, ConfigurationException, TranscoderException { + + File filePDF = null; + + PDFTranscoder transcoder = new PDFTranscoder(); + + //carrega o arquivo de configuração + DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); + //File configFile = ResourceUtils.getFile("classpath:fop-config.xml"); + Configuration cfg = cfgBuilder.buildFromFile(ResourceUtils.getFile("classpath:fop-config.xml")); + ContainerUtil.configure(transcoder, cfg); + + //Faz a leitura do novo SVG + TranscoderInput transcoderInput = new TranscoderInput(new FileInputStream(fileSVG)); + + //define o diretório temporário e o prefixo e sufixo do arquivo + Path pathPDF = Files.createTempFile("certificado", ".pdf"); + filePDF = pathPDF.toFile(); + + //realiza a transformação de SVG para PDF e guarda na pasta temporária + OutputStream outputStream = new FileOutputStream(filePDF); + TranscoderOutput transcoderOutput = new TranscoderOutput(outputStream); + transcoder.transcode(transcoderInput, transcoderOutput); + outputStream.flush(); + outputStream.close(); + + + return filePDF; + } +} diff --git a/src/main/java/br/edu/utfpr/servicebook/service/PerspectiveAPIService.java b/src/main/java/br/edu/utfpr/servicebook/service/PerspectiveAPIService.java new file mode 100644 index 00000000..6ba2838a --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/service/PerspectiveAPIService.java @@ -0,0 +1,74 @@ +package br.edu.utfpr.servicebook.service; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; +import org.springframework.http.ResponseEntity; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Service +public class PerspectiveAPIService { + //chave da api deve ser inserida em .env + @Value("${perspective.api.key}") + private String apiKey; + + @Autowired + private RestTemplate restTemplate; + + private final ObjectMapper objectMapper; + + public PerspectiveAPIService(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + public String analyzeComment(String comment) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + // Construa o corpo da solicitação conforme a documentação da API do Perspective + // Aqui está um exemplo simples para análise de toxicidade + String requestBody = "{\"comment\":{\"text\":\"" + comment + "\"},\"languages\":[\"en\"], \"requestedAttributes\":{\"TOXICITY\":{}, \"UNSUBSTANTIAL\":{}}}"; + + HttpEntity requestEntity = new HttpEntity<>(requestBody, headers); + + // Faça a solicitação POST para a API do Perspective + String apiUrl = "https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=" + apiKey; + + ResponseEntity responseEntity = restTemplate.exchange(apiUrl, HttpMethod.POST, requestEntity, String.class); + + String responseBody = responseEntity.getBody(); + boolean isOffensive = isCommentOffensive(responseBody, 0.5); // Ajuste o limiar conforme necessário + + return isOffensive ? "Comentário Ofensivo" : "Comentário Não Ofensivo"; + } + + // valida retornando true ou false + private boolean isCommentOffensive(String responseJson, double toxicityThreshold) { + try { + JsonNode rootNode = objectMapper.readTree(responseJson); + + if (rootNode.has("attributeScores")) { + JsonNode attributeScoresNode = rootNode.get("attributeScores"); + + if (attributeScoresNode.has("TOXICITY")) { + JsonNode toxicityNode = attributeScoresNode.get("TOXICITY"); + double toxicityScore = toxicityNode.get("summaryScore").get("value").asDouble(); + + // Compara a pontuação de toxicidade com o limite definido + return toxicityScore > toxicityThreshold; + } + } + + // Se o nó ou atributo não estiver presente, considera como não ofensivo + return false; + } catch (Exception e) { + e.printStackTrace(); + // Em caso de erro, considere como não ofensivo + return false; + } + } +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServiceOfferingAdItemService.java b/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServiceOfferingAdItemService.java index f115142b..547c0701 100644 --- a/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServiceOfferingAdItemService.java +++ b/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServiceOfferingAdItemService.java @@ -1,7 +1,9 @@ package br.edu.utfpr.servicebook.service; +import br.edu.utfpr.servicebook.model.entity.ProfessionalServiceOffering; import br.edu.utfpr.servicebook.model.entity.ProfessionalServicePackageOffering; import br.edu.utfpr.servicebook.model.entity.ProfessionalServiceOfferingAdItem; +import br.edu.utfpr.servicebook.model.entity.User; import br.edu.utfpr.servicebook.model.repository.ProfessionalServiceOfferingAdItemRepository; import org.springframework.beans.factory.annotation.Autowired; @@ -16,4 +18,17 @@ public class ProfessionalServiceOfferingAdItemService { public List findAllByProfessionalServicePackageOffering(ProfessionalServicePackageOffering professionalServicePackageOffering){ return professionalServiceOfferingAdItemRepository.findAllByProfessionalServicePackageOffering(professionalServicePackageOffering); } + +// /** +// * Salva uma oferta de serviço de um profissional +// * @param professionalServiceOfferingAdItem +// */ + public ProfessionalServiceOfferingAdItem save(ProfessionalServiceOfferingAdItem professionalServiceOfferingAdItem){ + return this.professionalServiceOfferingAdItemRepository.save(professionalServiceOfferingAdItem); + } + + public List findAllByProfessionalServicePackageOfferingUser(User user){ + return professionalServiceOfferingAdItemRepository.findProfessionalServiceOfferingAdItemsWithRelatedEntities(user); + } + } diff --git a/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServiceOfferingService.java b/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServiceOfferingService.java index 59ca9a31..337c75d7 100644 --- a/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServiceOfferingService.java +++ b/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServiceOfferingService.java @@ -1,12 +1,11 @@ package br.edu.utfpr.servicebook.service; -import br.edu.utfpr.servicebook.model.entity.Expertise; -import br.edu.utfpr.servicebook.model.entity.ProfessionalServiceOffering; -import br.edu.utfpr.servicebook.model.entity.Service; -import br.edu.utfpr.servicebook.model.entity.User; +import br.edu.utfpr.servicebook.model.entity.*; import br.edu.utfpr.servicebook.model.repository.CategoryRepository; import br.edu.utfpr.servicebook.model.repository.ProfessionalServiceOfferingRepository; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.repository.Query; import java.util.List; import java.util.Optional; @@ -22,8 +21,8 @@ public class ProfessionalServiceOfferingService { * @param id * @return */ - public ProfessionalServiceOffering findById(Long id) { - return professionalServiceOfferingRepository.findById(id).orElse(null); + public Optional findById(Long id) { + return professionalServiceOfferingRepository.findById(id); } /** @@ -50,6 +49,13 @@ public List findProfessionalServiceOfferingByUser(U return professionalServiceOfferingRepository.findProfessionalServiceOfferingByUser(user); } + public List findFirst3ProfessionalServiceOfferingByUserAndType(User user, Enum type){ + return professionalServiceOfferingRepository.findFirst3ByUserAndType(user, type); + } + + public List findProfessionalServiceOfferingByUserAndType(User user, Enum type){ + return professionalServiceOfferingRepository.findByUserAndType(user, type); + } /** * Busca todas as ofertas de serviços de um profissional * @param id @@ -68,6 +74,11 @@ public List findProfessionalServiceOfferingByServic return professionalServiceOfferingRepository.findProfessionalServiceOfferingByService(service); } + public Page findDistinctByTermIgnoreCaseWithPagination(String searchTerm, Integer page, Integer size){ + PageRequest pageRequest = PageRequest.of(page - 1, size); + return this.professionalServiceOfferingRepository.findDistinctByTermIgnoreCaseWithPagination(searchTerm, pageRequest); + } + /** * Busca todas os serviços de um profissional por serviço cadastrado pelo administrador. */ @@ -97,4 +108,39 @@ public List findProfessionalServiceOfferingByUserAn public Optional findProfessionalServiceOfferingByName(String name){ return professionalServiceOfferingRepository.findProfessionalServiceOfferingByName(name); } + + public Page findAllIndividualsByService(Service searchTerm, Integer page, Integer size){ + PageRequest pageRequest = PageRequest.of(page - 1, size); + return this.professionalServiceOfferingRepository.findAllIndividualsByService(searchTerm, pageRequest); + } + + + /** + * Busca o serviço pelo id. + * @param id + * @return + */ + public Optional findProfessionalServiceOfferingById(Long id){ + return professionalServiceOfferingRepository.findProfessionalServiceOfferingById(id); + } + + public List findAllByProfessionalServicePackageOfferingUser(User professionalServicePackageOffering){ + return professionalServiceOfferingRepository.findProfessionalServiceOfferingAdItemsByUser(professionalServicePackageOffering); + } + + public List findAll(){ + return professionalServiceOfferingRepository.findDistinctProfessionalServiceOfferings(); + } + + public Optional findProfessionalServiceOfferingByExpertiseAAndUser(Long user, Long expertise){ + return professionalServiceOfferingRepository.findProfessionalServiceOfferingByExpertiseAAndUser(user, expertise); + } + + public List findProfessionalServiceOfferingByServiceAndUser(Long service, Long user) { + return professionalServiceOfferingRepository.findProfessionalServiceOfferingByServiceAndUser(service, user); + } + + public Optional findProfessionalServiceOfferingByIdAndUser(Long id, Long user) { + return professionalServiceOfferingRepository.findProfessionalServiceOfferingByIdAndUser(id, user); + } } diff --git a/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServicePackageOfferingService.java b/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServicePackageOfferingService.java index 2dd243c3..01b0a3fb 100644 --- a/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServicePackageOfferingService.java +++ b/src/main/java/br/edu/utfpr/servicebook/service/ProfessionalServicePackageOfferingService.java @@ -32,7 +32,27 @@ public List findAllByUserAndExpertise(User u /** * Busca os anúncios de pacote de serviços de um dado profissional. */ - public List findAllByUser(User user){ - return this.professionalServicePackageOfferingRepository.findAllByUser(user); + public List findAllByUserAndType(User user, Enum type){ + return this.professionalServicePackageOfferingRepository.findFirst3ByUserAndType(user, type); + } + + /** + * Salva uma oferta de serviço de um profissional + * @param professionalServicePackageOffering + */ + public void save(ProfessionalServicePackageOffering professionalServicePackageOffering){ + professionalServicePackageOfferingRepository.save(professionalServicePackageOffering); + } + + public ProfessionalServicePackageOffering findById(Long id) { + return professionalServicePackageOfferingRepository.findById(id).orElse(null); + } + + public List findByTypeAndUser(User user, Enum type) { + return professionalServicePackageOfferingRepository.findByUserAndType(user,type); + } + + public List findAllByCombinedAndItems(User user) { + return professionalServicePackageOfferingRepository.findAllByCombinedAndItems(user); } } diff --git a/src/main/java/br/edu/utfpr/servicebook/service/QuartzService.java b/src/main/java/br/edu/utfpr/servicebook/service/QuartzService.java index de9d2e74..c485f8bc 100644 --- a/src/main/java/br/edu/utfpr/servicebook/service/QuartzService.java +++ b/src/main/java/br/edu/utfpr/servicebook/service/QuartzService.java @@ -213,4 +213,73 @@ public void deleteJobsAvailableToHide() { System.out.println(e.getMessage()); } } + + /** Envio de email para o cliente e profissional com o comprovante de pagamento*/ + public void sendEmailPaymentVoucher(String codePayment, Long client, Long professional, String service, String date, String voucher) { + try { + System.out.println("clientId---------------------"); + System.out.println(client); + JobDetail job = JobBuilder.newJob(SendEmailVoucher.class) + .withIdentity(SendEmailVoucher.class.getSimpleName(), GROUP).build(); + job.getJobDataMap().put(SendEmailVoucher.PAYMENT_KEY, codePayment); + job.getJobDataMap().put(String.valueOf((Long) SendEmailVoucher.CLIENT_ID), client); + job.getJobDataMap().put(String.valueOf(SendEmailVoucher.PROFESSIONAL_ID), professional); + job.getJobDataMap().put(SendEmailVoucher.SERVICE_KEY, service); + job.getJobDataMap().put(SendEmailVoucher.DATE_KEY, date); + job.getJobDataMap().put(SendEmailVoucher.VOUCHER_KEY, voucher); + + Trigger trigger = getTrigger(SendEmailWithVerificationCodeJob.class.getSimpleName(), GROUP); + + scheduler.scheduleJob(job, trigger); + + if (!scheduler.isStarted()) { + scheduler.start(); + } + + }catch (SchedulerException e){ + System.out.println(e.getMessage()); + } + } + + public void sendEmailToRegisterUser(String email, String company, String link) { + try { + JobDetail job = JobBuilder.newJob(SendEmailToRegisterUser.class) + .withIdentity(SendEmailToRegisterUser.class.getSimpleName(), GROUP).build(); + job.getJobDataMap().put(SendEmailToRegisterUser.RECIPIENT_KEY, email); + job.getJobDataMap().put(SendEmailToRegisterUser.USER_KEY, company); + job.getJobDataMap().put(SendEmailToRegisterUser.LINK_KEY, link); + + Trigger trigger = getTrigger(SendEmailToRegisterUser.class.getSimpleName(), GROUP); + + scheduler.scheduleJob(job, trigger); + + if (!scheduler.isStarted()) { + scheduler.start(); + } + + }catch (SchedulerException e){ + System.out.println(e.getMessage()); + } + } + + public void sendEmailWithConfirmationUser(String email, String company, String link) { + try { + JobDetail job = JobBuilder.newJob(SendEmailWithConfirmationUser.class) + .withIdentity(SendEmailWithConfirmationUser.class.getSimpleName(), GROUP).build(); + job.getJobDataMap().put(SendEmailWithConfirmationUser.RECIPIENT_KEY, email); + job.getJobDataMap().put(SendEmailWithConfirmationUser.USER_KEY, company); + job.getJobDataMap().put(SendEmailWithConfirmationUser.LINK_KEY, link); + + Trigger trigger = getTrigger(SendEmailWithConfirmationUser.class.getSimpleName(), GROUP); + + scheduler.scheduleJob(job, trigger); + + if (!scheduler.isStarted()) { + scheduler.start(); + } + + }catch (SchedulerException e){ + System.out.println(e.getMessage()); + } + } } diff --git a/src/main/java/br/edu/utfpr/servicebook/service/ServiceService.java b/src/main/java/br/edu/utfpr/servicebook/service/ServiceService.java index 09450fe8..ba373f91 100644 --- a/src/main/java/br/edu/utfpr/servicebook/service/ServiceService.java +++ b/src/main/java/br/edu/utfpr/servicebook/service/ServiceService.java @@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/src/main/java/br/edu/utfpr/servicebook/service/UserService.java b/src/main/java/br/edu/utfpr/servicebook/service/UserService.java index 8bd03cc1..34701603 100644 --- a/src/main/java/br/edu/utfpr/servicebook/service/UserService.java +++ b/src/main/java/br/edu/utfpr/servicebook/service/UserService.java @@ -1,6 +1,7 @@ package br.edu.utfpr.servicebook.service; import br.edu.utfpr.servicebook.model.dto.ExpertiseDTO; +import br.edu.utfpr.servicebook.model.dto.UserDTO; import br.edu.utfpr.servicebook.model.entity.Expertise; import br.edu.utfpr.servicebook.model.entity.Individual; import br.edu.utfpr.servicebook.model.entity.ProfessionalExpertise; @@ -74,6 +75,10 @@ public Long countUsersWithoutExpertise(){ return this.userRepository.countUsersWithoutExpertise(); } + public List findProfessionalsNotExist() { + return this.userRepository.findProfessionals(); + } + /** * Retorna uma lista de ExpertiseDTOs de um profissional * @param professional diff --git a/src/main/java/br/edu/utfpr/servicebook/service/UserTokenService.java b/src/main/java/br/edu/utfpr/servicebook/service/UserTokenService.java new file mode 100644 index 00000000..d3e450b9 --- /dev/null +++ b/src/main/java/br/edu/utfpr/servicebook/service/UserTokenService.java @@ -0,0 +1,29 @@ +package br.edu.utfpr.servicebook.service; + +import br.edu.utfpr.servicebook.model.entity.UserToken; +import br.edu.utfpr.servicebook.model.repository.UserTokenRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class UserTokenService { + + @Autowired + private UserTokenRepository userTokenRepository; + + public UserToken save(UserToken entity) { + userTokenRepository.save(entity); + return entity; + } + + public void deleteById(Long id) { + userTokenRepository.deleteById(id); + } + + public UserToken findByUserToken(String token) { + return this.userTokenRepository.findByToken(token); + } + +} \ No newline at end of file diff --git a/src/main/java/br/edu/utfpr/servicebook/util/TemplateUtil.java b/src/main/java/br/edu/utfpr/servicebook/util/TemplateUtil.java index 0249973c..a02a9bf6 100644 --- a/src/main/java/br/edu/utfpr/servicebook/util/TemplateUtil.java +++ b/src/main/java/br/edu/utfpr/servicebook/util/TemplateUtil.java @@ -109,4 +109,50 @@ public UserTemplateStatisticInfo getProfessionalStatisticInfo(User oProfessional oProfessionalExpertise.get().getRating() ); } + + public UserTemplateStatisticInfo getCompanyStatisticInfo(User oProfessional, Long expertiseId) { + + if (expertiseId == 0L) { + ProfessionalDTO professional = professionalMapper.toResponseDto(oProfessional); + + return new UserTemplateStatisticInfo( + jobContractedService.countByProfessional(oProfessional).orElse(0L), + jobContractedService.countRatingByProfessional(oProfessional).orElse(0L), + jobContractedService.countCommentsByProfessional(oProfessional).orElse(0L), + professional.getRating() + ); + } + + if (expertiseId < 0) { + throw new InvalidParamsException("O identificador da especialidade não pode ser negativo. Por favor, tente novamente."); + } + + Optional oExpertise = expertiseService.findById(expertiseId); + if (!oExpertise.isPresent()) { + throw new EntityNotFoundException("A especialidade não foi encontrada pelo id informado. Por favor, tente novamente."); + } + + Optional oProfessionalExpertise = professionalExpertiseService.findByProfessionalAndExpertise( + oProfessional, + oExpertise.get() + ); + + if (!oProfessionalExpertise.isPresent()) { + throw new InvalidParamsException("A especialidade profissional não foi encontrada. Por favor, tente novamente."); + } + + Long totalJobsByExpertise = jobContractedService.countByProfessionalAndJobRequest_Expertise( + oProfessional, oExpertise.get()).orElse(0L); + Long totalRatingsByExpertise = jobContractedService.countRatingByProfessionalAndJobRequest_Expertise( + oProfessional, oExpertise.get()).orElse(0L); + Long totalCommentsByExpertise = jobContractedService.countCommentsByProfessionalAndJobRequest_Expertise( + oProfessional, oExpertise.get()).orElse(0L); + + return new UserTemplateStatisticInfo( + totalJobsByExpertise, + totalRatingsByExpertise, + totalCommentsByExpertise, + oProfessionalExpertise.get().getRating() + ); + } } \ No newline at end of file diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 1f86fa9c..9f450eb5 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -12,6 +12,7 @@ spring.jpa.database-platform=org.hibernate.dialect.H2Dialect #suporta a inicialização via data.sql no Spring >2.5 spring.sql.init.mode=always +spring.h2.console.enabled=true #evita que o data.sql execute antes do hibernate gerar as tabelas spring.jpa.defer-datasource-initialization=true diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 54d5d60b..8376f8ca 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -88,9 +88,30 @@ pagination.size.visitor=4 #******************************** # Perspective API - Moderador de Texto #******************************** +perspective.api.url=https://commentanalyzer.googleapis.com + perspective.api.key=${PERSPECTIVE_API_KEY} #******************************** # Profile: Active. #******************************** spring.profiles.active=dev +#******************************** +# Outros +#******************************** +svg.certificate.template:https://res.cloudinary.com/dgueb0wir/image/upload/v1718144961/servicebook/voucher/svg_voucher_fbanzk.svg + + +#******************************** +# moderador de texto +#******************************** + +api.key=AIzaSyApd2uNDxNDqcFGRLcpITliQmSNXEXncC0 + +#************ MERCADO PAGO +mercadopago.access_token=TEST-2738533774159236-052518-f4e09de99516f8d7b2adb21186313d1b-494777183 +mercadopago.public_key=TEST-4f0ff070-df15-44df-9d79-90269d190835 + +spring.datasource.url=${JDBC_DATASOURCE_URL} +spring.jpa.show-sql=true +spring.jpa.generate-ddl=true \ No newline at end of file diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 82ffd9c3..1a577e52 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -3,7 +3,8 @@ VALUES ('Paraná', 'PR'), ('Santa Catarina', 'SC'); INSERT INTO cities (path_image, name, state_id) -VALUES ('https://i.imgur.com/qMKc4rf.png', 'Guarapuava', '1'); +-- VALUES ('https://i.imgur.com/qMKc4rf.png', 'Guarapuava', '1'); +VALUES ('https://i.imgur.com/qMKc4rf.png', 'Guarapuava', '1'), ('https://www.viajeparana.com/sites/viaje-parana/arquivos_restritos/files/imagem/2019-04/igreja_nossa_senhora_da_gloria_ca.jpg', 'Pitanga', '1'); INSERT INTO addresses (neighborhood, number, postal_code, street, city_id) VALUES ('Industrial', '800', '85053525', 'Avenida Professora Laura Pacheco Bastos', '1'); @@ -23,16 +24,18 @@ VALUES ('admin@mail.com', 'true', 'Administrador', '(42) 99999-9995', 'true', INSERT INTO users (email, email_verified, name, phone_number, phone_verified, profile_picture, profile_verified, address_id, rating, profile, password, description) -VALUES ('profissional1@mail.com', 'true', 'Nome do Primeiro Profissional', '(42) 99999-9991', 'true', - 'https://i.imgur.com/owhNAKK.png', 'true', '1', 2, 'ROLE_USER','$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Descrição profissional 1'), - ('profissional2@mail.com', 'true', 'Nome do Segundo Profissional', '(42) 99999-9992', 'true', - 'https://i.imgur.com/sHAg9pz.png', 'true', '1', 4,'ROLE_USER', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Descrição profissional 1'), - ('cliente1@mail.com', 'true', 'Nome do Primeiro Cliente', '(42) 99999-9993', 'true', - 'https://i.imgur.com/y9dH2bJ.jpeg', 'true', '1', 5, 'ROLE_USER', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Descrição profissional 1'), - ('cliente2@mail.com', 'true', 'Nome do Segundo Cliente', '(42) 99999-9994', 'true', - 'https://i.imgur.com/owhNAKK.png', 'true', '1', 1, 'ROLE_USER', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Descrição profissional 1'), - ('profissional3@mail.com', 'true', 'Nome do Terceiro Profissional', '(42) 99999-9995', 'false', - null, 'false', '1', 3, 'ROLE_USER', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Descrição profissional 1'); +VALUES ('duarte@mail.com', 'true', 'Duarte Trindade', '(42) 99999-9991', 'true', + 'https://res.cloudinary.com/dgueb0wir/image/upload/v1717708789/images/perfil01_bpevao.png', 'true', '1', 2, 'ROLE_USER','$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Realizo serviços de qualidade.'), + ('marcelo@mail.com', 'true', 'Marcelo Macedo', '(42) 99999-9992', 'true', + 'https://res.cloudinary.com/dgueb0wir/image/upload/v1717708789/images/perfil04_kq1jfw.png', 'true', '1', 4,'ROLE_USER', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Há 10 anos no mercado se prestação de serviços!'), + ('luis@mail.com', 'true', 'Luís Almeida', '(42) 99999-9993', 'true', + 'https://res.cloudinary.com/dgueb0wir/image/upload/v1717708790/images/perfil03_ymoozz.png', 'true', '1', 5, 'ROLE_USER', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Possuo uma loja na cidade, onde acabo utilizando os serviços do sistema para encontrar os profissionais.'), + ('lucas@mail.com', 'true', 'Lucas Santos', '(42) 99999-9994', 'true', + 'https://i.imgur.com/owhNAKK.png', 'true', '1', 1, 'ROLE_USER', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Quando preciso utilizo a plataforma.'), + ('guilherme@mail.com', 'true', 'Guilherme Oliveira', '(42) 99999-9995', 'false', + null, 'false', '1', 3, 'ROLE_USER', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Natural de Guarapuava.'), + ('tais.hrissay@unisaude.co.ao', 'true', 'Michele', '(42) 99993-5496', 'true', + 'https://res.cloudinary.com/dgueb0wir/image/upload/v1717708790/images/perfil03_ymoozz.png', 'true', '1', 1, 'ROLE_USER', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Atuo em diversas áreas!'); --ROLE_COMPANY: Empresa -- Senha: qwerty123 @@ -40,10 +43,10 @@ VALUES ('profissional1@mail.com', 'true', 'Nome do Primeiro Profissional', '(42) INSERT INTO users (email, email_verified, name, phone_number, phone_verified, profile_picture, profile_verified, address_id, rating, profile, password, description) -VALUES ('empresa@mail.com', 'true', 'Nome Empresa', '(42) 99999-9994', 'true', - 'https://i.imgur.com/owhNAKK.png', 'true', '1', 1, 'ROLE_COMPANY', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Descrição empresa 1'), - ('empresa1@mail.com', 'true', 'Alguma Empresa', '(42) 99999-9996', 'true', - 'https://i.imgur.com/owhNAKK.png', 'true', '1', 2, 'ROLE_COMPANY', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Descrição profissional 1'); +VALUES ('casacontrucao@mail.com', 'true', 'Casa Construção', '(42) 99999-9994', 'true', + 'https://i.imgur.com/owhNAKK.png', 'true', '1', 1, 'ROLE_COMPANY', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Prestação de serviço na área de construção'), + ('faztudo@mail.com', 'true', 'Faz Tudo', '(42) 99999-9996', 'true', + null, 'true', '1', 2, 'ROLE_COMPANY', '$2a$10$ZqgnFnwi6/8qjELs5.Y7rOXacIu/vbudYDl4vA55KDvDuGcpaEFzS', 'Empresa com diversos profissionais de todas as áreas!'); INSERT INTO individuals (cpf, gender, birth_date, id) VALUES ('982.988.640-93', 'MASCULINE', '2003-01-01', '2'), @@ -73,7 +76,7 @@ INSERT INTO expertises (name, description, path_icon, category_id) VALUES ('Encanador', 'Realiza serviço como encanador', 'https://res.cloudinary.com/dgueb0wir/image/upload/v1689176874/servicebook/expertises/encanador_q7b9vg.svg', 7), ('Eletricista', 'Realiza serviço como eletricista', 'https://res.cloudinary.com/dgueb0wir/image/upload/v1689176874/servicebook/expertises/eletricista_tlqro5.svg', 7), ('Pintor', 'Realiza serviço como pintor', 'https://res.cloudinary.com/dgueb0wir/image/upload/v1689176875/servicebook/expertises/pintor_kfl3de.svg', 7), - ('Mecânico', 'Realiza serviço como mecânico', 'https://res.cloudinary.com/dgueb0wir/image/upload/v1689176876/servicebook/expertises/mecanico_quczum.svg', 7); + ('Mecânico', 'Realiza serviço como mecânico', 'https://res.cloudinary.com/dgueb0wir/image/upload/v1689176876/servicebook/expertises/mecanico_quczum.svg', 5); INSERT INTO professional_expertises (expertise_id, professional_id, rating, description) VALUES (1, 2, 1, 'descrição'), @@ -82,78 +85,140 @@ VALUES (1, 2, 1, 'descrição'), (4, 2, 4, 'descrição'), (2, 5, 4, 'descrição'), (2, 7, 4, 'descrição'), - (2, 4, 4, 'descrição'); + (2, 4, 4, 'descrição'), + (1, 9, 5, 'descrição'); INSERT INTO services (name, description, allow_scheduling, path_icon, expertise_id) VALUES ('Balanceamento', 'Balanceamento das rodas', false, 'https://res.cloudinary.com/dgueb0wir/image/upload/v1689176876/servicebook/expertises/mecanico_quczum.svg', 4), ('Troca de óleo', 'Troca do óleo do motor', false, 'https://res.cloudinary.com/dgueb0wir/image/upload/v1689176876/servicebook/expertises/mecanico_quczum.svg', 4); -INSERT INTO professional_service_offerings (name, description, service_id, user_id) -VALUES ('Balanceamento com máquina importada', 'O balanceamento com 100% de garantia', 1, 2), - (null, null, 2, 2); - -INSERT INTO companies (cnpj, id) -VALUES ('98.988.640/0001-91', 7); - -INSERT INTO job_requests -(client_confirmation, date_created, date_target, description, professional_confirmation, quantity_candidators_max, - status, client_id, expertise_id) -VALUES ('false', '2021-01-01', '2021-01-01', 'Preciso de um Encanador 1!', 'true', '5', 'AVAILABLE', '2', '1'), - ('false', '2021-01-01', '2021-01-02', 'Preciso de um Encanador 2!', 'true', '10', 'AVAILABLE', '2', '1'), - ('false', '2021-01-01', '2021-01-07', 'Preciso de um Encanador 3!', 'true', '15', 'AVAILABLE', '2', '1'), - ('true', '2021-01-01', '2021-01-07', 'Preciso de um Encanador 30!', 'true', '15', 'TO_HIRED', '2', '1'), - ('false', '2021-01-01', '2021-01-08', 'Preciso de um Encanador 4!', 'true', '20', 'TO_DO', '2', '1'), -- 4 - ('false', '2021-01-01', '2021-01-08', 'Preciso de um Encanador 5!', 'true', '20', 'DOING', '2', '1'), - ('false', '2021-01-01', '2021-01-08', 'Preciso de um Encanador 6!', 'true', '20', 'CANCELED', '2', '1'), - ('false', '2022-11-29', '2022-12-13', 'Preciso de um Encanador 7!', 'true', '20', 'DOING', '3', '1'), - ('false', '2021-01-01', '2021-01-08', 'Preciso de um Encanador 8!', 'true', '20', 'DOING', '3', '1'), - ('false', '2021-01-01', '2021-01-30', 'Preciso de um Eletricista 1!', 'true', '5', 'TO_HIRED', '3', '2'),--10 - ('false', '2021-01-01', '2021-02-02', 'Preciso de um Eletricista 2!', 'true', '10', 'CLOSED', '3', '2'), - ('true', '2021-01-01', '2021-03-01', 'Preciso de um Eletricista 3!', 'true', '15', 'TO_HIRED', '4', '2'), - ('false', '2021-01-01', '2021-04-01', 'Preciso de um Eletricista 4!', 'true', '20', 'TO_DO', '4', '2'), -- 13 - ('false', '2021-01-01', '2021-04-01', 'Preciso de um Eletricista 5!', 'true', '20', 'CLOSED', '4', '2'), - ('false', '2021-01-01', '2021-04-01', 'Preciso de um Eletricista 6!', 'true', '20', 'CLOSED', '4', '2'), - ('true', '2021-01-01', '2021-01-01', 'Preciso de um Pintor 1!', 'true', '5', 'TO_HIRED', '4', '3'), - ('true', '2021-01-01', '2021-01-02', 'Preciso de um Pintor 2!', 'true', '10', 'AVAILABLE', '4', '3'), - ('true', '2021-01-01', '2021-01-03', 'Preciso de um Pintor 3!', 'true', '15', 'TO_HIRED', '4', '3'), - ('true', '2023-01-01', '2021-01-04', 'Preciso de um Pintor 4!', 'true', '20', 'TO_DO', '3', '3'), -- 19 - ('true', '2023-07-01', '2021-01-04', 'Preciso de um Pintor 5!', 'true', '20', 'CLOSED', '4', '3'), - ('true', '2023-04-01', '2021-01-04', 'Preciso de um Pintor 6!', 'true', '20', 'DOING', '4', '3'), - ('true', '2023-04-26', '2021-08-27', 'Preciso de um Mecânico 1!', 'true', '5', 'AVAILABLE', '4', '4'), - ('true', '2023-05-26', '2021-08-28', 'Preciso de um Mecânico 2!', 'true', '10', 'AVAILABLE', '4', '4'), - ('true', '2023-03-26', '2021-09-01', 'Preciso de um Mecânico 3!', 'true', '15', 'AVAILABLE', '4', '4'), - ('true', '2023-02-26', '2021-09-10', 'Preciso de um Mecânico 4!', 'true', '20', 'AVAILABLE', '4', '4'), - ('true', '2023-02-16', '2023-01-17', 'Preciso de um Mecânico 5!', 'true', '20', 'CLOSED', '4', '4'); - - - -INSERT INTO job_contracted (comments, rating, job_request, professional, hired_date, todo_date) -VALUES ('Ótimo Encanador!', '5', '19', '5', '2021-04-01', '2021-08-26'), - ('Ótimo Eletricista!', '5', '10', '2', '2021-04-01', '2021-08-26'), - ('Ótimo Pintor!', '5', '16', '2', '2021-04-01', '2021-08-26'), - ('Bom Encanador!', '3', '5', '2', '2021-04-01', '2021-08-26'), - ('Bom Encanador!', '3', '8', '2', '2021-04-01', '2021-08-26'), - ('Bom Encanador!', '3', '9', '2', '2021-04-01', '2021-08-26'), - ('Péssimo Encanador!', '1', '6', '2', '2021-04-01', '2021-08-26'), - ('Bom Eletricista!', '3', '11', '2', '2021-04-01', '2021-08-26'), - ('Péssimo Eletricista!', '1', '12', '2', '2021-04-01', '2021-08-26'), - ('Bom Pintor!', '3', '15', '2', '2021-04-01','2021-08-26'), - ('Bom Pintor!', '3', '20', '2', '2021-04-01', '2021-08-26'), - ('Bom Pintor!', '3', '21', '2', '2021-04-01', '2021-08-26'), - ('Péssimo Pintor!', '1', '14', '2', '2021-04-01', '2021-08-26'); - - - -INSERT INTO job_candidates (job_id, professional_id, chosen_by_budget) -VALUES ('1', '2', 'false'), - ('1', '3', 'true'), - ('1', '6', 'false'), - ('2', '2', 'false'), - ('3', '2', 'true'), - ('17', '2', 'false'); +-- INSERT INTO PROFESSIONAL_SERVICE_OFFERINGS (DESCRIPTION,DURATION,NAME,PRICE,TYPE,UNIT,SERVICE_ID, USER_ID, EXPERTISE_ID, ID) +-- values ('Balanceamento Teste', '1 Hora','Balanceamento', 9.00, 'INDIVIDUAL', 'Hora', 1, 5, 4, 1), +-- ('Balanceamento com máquina importada1', '2 Horas', 'O balanceamento com 100% de garantia',219000,'COMBINED_PACKAGE','Hora', 2, 5, 4, 2); +-- INSERT INTO professional_service_offerings (name, description, price, unit, duration, service_id, user_id, type, id) +-- VALUES ('Balanceamento com máquina importada', 'O balanceamento com 100% de garantia', 19000, 'Hora', '2 Horas', 1, 2, 'INDIVIDUAL', 1), +-- ('Balanceamento com máquina importada1', 'O balanceamento com 100% de garantia', 219000, 'Hora', '2 Horas', 1, 2, 'COMBINED_PACKAGE', 2); +-- ('Balanceamento com máquina importada2', 'O balanceamento com 100% de garantia', 19000, 'Hora', '2 Horas', 1, 2, 'INDIVIDUAL', 3), +-- ('Balanceamento com máquina importada3', 'O balanceamento com 100% de garantia', 19000, 'Hora', '2 Horas', 1, 2, 'INDIVIDUAL', 4); +-- (null, null, 2, 2); -INSERT INTO follows (client_id, professional_id) -VALUES (4, 2) +-- INSERT INTO professional_service_package_offering (name, description, price, unit, duration, service_id, user_id, type, amount,id) +-- VALUES ('Balanceamento com máquina importada', 'O balanceamento com 100% de garantia', 19000, 'Hora', '2 Horas', 1, 2, 'SIMPLE_PACKAGE', 2, 1), +-- ('Balanceamento com máquina importada', 'O balanceamento com 100% de garantia', 19000, 'Hora', '2 Horas', 1, 2, 'COMBINED_PACKAGE', 2, 2); +-- ('Balanceamento com máquina importada', 'O balanceamento com 100% de garantia', 19000, 'Hora', '2 Horas', 1, 2, 'SIMPLE_PACKAGE', 2, 3), +-- ('Balanceamento com máquina importada', 'O balanceamento com 100% de garantia', 19000, 'Hora', '2 Horas', 1, 2, 'SIMPLE_PACKAGE', 2, 4), +-- ('Balanceamento com máquina importada', 'O balanceamento com 100% de garantia', 19000, 'Hora', '2 Horas', 1, 2, 'SIMPLE_PACKAGE', 2, 5); +INSERT INTO companies (cnpj, id) +VALUES ('98.988.640/0001-91', 8), + ('98.988.640/0001-91', 9); + +INSERT INTO company_professionals (company_id, professional_id, rating, is_confirmed) +VALUES (8, 2, 1, true), + (9, 3, 1, true), + (9, 2, 1, false); + +-- INSERT INTO job_requests +-- (client_confirmation, date_created, date_target, description, professional_confirmation, quantity_candidators_max, +-- status, client_id, expertise_id) +-- VALUES ('false', '2024-01-01', '2024-01-01', 'Preciso de um Encanador 1!', 'true', '5', 'AVAILABLE', '2', '1'), +-- ('false', '2024-01-01', '2024-01-02', 'Preciso de um Encanador 2!', 'true', '10', 'AVAILABLE', '2', '1'), +-- ('false', '2024-01-01', '2024-01-07', 'Preciso de um Encanador 3!', 'true', '15', 'AVAILABLE', '2', '1'), +-- ('true', '2024-01-01', '2024-01-07', 'Preciso de um Encanador 30!', 'true', '15', 'TO_HIRED', '2', '1'), +-- ('false', '2024-01-01', '2024-01-08', 'Preciso de um Encanador 4!', 'true', '20', 'TO_DO', '2', '1'), -- 4 +-- ('false', '2024-01-01', '2024-01-08', 'Preciso de um Encanador 5!', 'true', '20', 'DOING', '2', '1'), +-- ('false', '2024-01-01', '2024-01-08', 'Preciso de um Encanador 6!', 'true', '20', 'CANCELED', '2', '1'), +-- ('false', '2022-11-29', '2022-12-13', 'Preciso de um Encanador 7!', 'true', '20', 'DOING', '3', '1'), +-- ('false', '2024-01-01', '2024-01-08', 'Preciso de um Encanador 8!', 'true', '20', 'DOING', '3', '1'), +-- ('false', '2024-01-01', '2024-01-30', 'Preciso de um Eletricista 1!', 'true', '5', 'TO_HIRED', '3', '2'),--10 +-- ('false', '2024-01-01', '2024-02-02', 'Preciso de um Eletricista 2!', 'true', '10', 'CLOSED', '3', '2'), +-- ('true', '2024-01-01', '2024-03-01', 'Preciso de um Eletricista 3!', 'true', '15', 'TO_HIRED', '4', '2'), +-- ('false', '2024-01-01', '2024-04-01', 'Preciso de um Eletricista 4!', 'true', '20', 'TO_DO', '4', '2'), -- 13 +-- ('false', '2024-01-01', '2024-04-01', 'Preciso de um Eletricista 5!', 'true', '20', 'CLOSED', '4', '2'), +-- ('false', '2024-01-01', '2024-04-01', 'Preciso de um Eletricista 6!', 'true', '20', 'CLOSED', '4', '2'), +-- ('true', '2024-01-01', '2024-01-01', 'Preciso de um Pintor 1!', 'true', '5', 'TO_HIRED', '4', '3'), +-- ('true', '2024-01-01', '2024-01-02', 'Preciso de um Pintor 2!', 'true', '10', 'CLOSED', '4', '4'), +-- ('true', '2024-01-01', '2024-01-03', 'Preciso de um Pintor 3!', 'true', '15', 'TO_HIRED', '4', '3'), +-- ('true', '2023-01-01', '2024-01-04', 'Preciso de um Pintor 4!', 'true', '20', 'TO_DO', '3', '3'), -- 19 +-- ('true', '2023-07-01', '2024-01-04', 'Preciso de um Pintor 5!', 'true', '20', 'CLOSED', '4', '3'), +-- ('true', '2023-04-01', '2024-01-04', 'Preciso de um Pintor 6!', 'true', '20', 'DOING', '4', '3'), +-- ('true', '2023-04-26', '2024-08-27', 'Preciso de um Mecânico 1!', 'true', '5', 'AVAILABLE', '4', '4'), +-- ('true', '2023-05-26', '2024-08-28', 'Preciso de um Mecânico 2!', 'true', '10', 'AVAILABLE', '4', '4'), +-- ('true', '2023-03-26', '2024-09-01', 'Preciso de um Mecânico 3!', 'true', '15', 'AVAILABLE', '4', '4'), +-- ('true', '2023-02-26', '2024-09-10', 'Preciso de um Mecânico 4!', 'true', '20', 'AVAILABLE', '4', '4'), +-- ('true', '2023-02-16', '2023-01-17', 'Preciso de um Mecânico 5!', 'true', '20', 'CLOSED', '4', '4'); + + +-- +-- INSERT INTO job_contracted (comments, rating, job_request, professional, hired_date, todo_date) +-- VALUES ('Ótimo Encanador!', '5', '19', '5', '2024-04-01', '2024-08-26'), +-- ('Ótimo Eletricista!', '5', '10', '2', '2024-04-01', '2024-08-26'), +-- ('Ótimo Pintor!', '5', '16', '2', '2024-04-01', '2024-08-26'), +-- ('Bom Encanador!', '3', '5', '2', '2024-04-01', '2024-08-26'), +-- ('Bom Encanador!', '3', '8', '2', '2024-04-01', '2024-08-26'), +-- ('Bom Encanador!', '3', '9', '2', '2024-04-01', '2024-08-26'), +-- ('Péssimo Encanador!', '1', '6', '6', '2024-04-01', '2024-08-26'), +-- ('Bom Eletricista!', '3', '13', '2', '2024-06-20', '2024-06-24'), +-- ('Péssimo Eletricista!', '1', '12', '2', '2024-04-01', '2024-08-26'), +-- ('Bom Pintor!', '3', '15', '2', '2024-04-01','2024-08-26'), +-- ('Bom Pintor!', '3', '20', '2', '2024-04-01', '2024-08-26'), +-- ('Bom Pintor!', '3', '17', '2', '2024-04-01', '2024-08-26'), +-- ('Bom Pintor!', '3', '1', '2', '2024-05-01', '2024-05-26'), +-- ('Bom Pintor!', '3', '4', '2', '2024-05-01', '2024-05-26'), +-- ('Péssimo Pintor!', '1', '14', '2', '2024-04-01', '2024-08-26'); +-- +-- INSERT INTO job_candidates (job_id, professional_id, chosen_by_budget) +-- VALUES ('1', '2', 'false'), +-- ('1', '3', 'true'), +-- ('1', '6', 'false'), +-- ('2', '2', 'false'), +-- ('3', '2', 'true'), +-- ('6', '2', 'false'), +-- ('17', '2', 'false'), +-- ('4', '2', 'false'), +-- ('6', '6', 'true'), +-- ('13', '2', 'true'); +INSERT INTO follows (client_id, professional_id) +VALUES (4, 2); + +-- DURAÇÃO DE SERVIÇOS +INSERT INTO duration_services (name) +VALUES ('Sem agendamento'), + ('30 minutos'), + ('1 hora'), + ('1 hora e meia'), + ('2 horas'), + ('3 horas'), + ('Um período do dia'), + ('O dia inteiro'); + +-- UNIDADE DE PREÇO +INSERT INTO price_units (name) +VALUES ('Hora'), + ('Metro quadrado'), + ('Unidade'); + + +-- INSERT INTO payments (id, payment_id, status) +-- VALUES (1, 1, 'approved'); +-- +-- INSERT INTO assessment_professionals (id, comment, date, quality, client_id, job_request_id, professional_id) +-- VALUES (1, 'Serviço de eletricista impecável: pontual, profissional e com excelente qualidade, garantindo segurança e satisfação. Recomendo fortemente!', '2024-06-01', 4, 4, 14, 2), +-- (2, 'Pontual', '2024-06-02', 4, 4, 14, 5); +-- +-- INSERT INTO assessment_responses (id,response, date, assessment_professional, professional_id) +-- VALUES (1,'Muito obrigado pela preferência', '2024-06-01', 1, 2), +-- (2,'Muito obrigada', '2024-06-01', 2, 5); +-- +-- INSERT INTO assessment_professionals_files (id,path_image, assessment_professional_id) +-- VALUES (1,'http://res.cloudinary.com/dgueb0wir/image/upload/v1718155628/txvfo0gilijknjsrnsqr.jpg', 1), +-- (2,'http://res.cloudinary.com/dgueb0wir/image/upload/v1718155628/txvfo0gilijknjsrnsqr.jpg', 2); + +-- INSERT INTO job_images (id, path, job_request_id) +-- VALUES (1,'https://res.cloudinary.com/dgueb0wir/image/upload/v1713823542/jobs/yof94o7nvsmeay8g1xto.jpg', 14), +-- (2,'https://res.cloudinary.com/dgueb0wir/image/upload/v1713823339/jobs/hghg8tnxh96zz5yo7nva.jpg', 14), +-- (3,'https://res.cloudinary.com/dgueb0wir/image/upload/v1713823542/jobs/yof94o7nvsmeay8g1xto.jpg', 1), +-- (4,'https://res.cloudinary.com/dgueb0wir/image/upload/v1713823542/jobs/yof94o7nvsmeay8g1xto.jpg', 2), +-- (5,'https://res.cloudinary.com/dgueb0wir/image/upload/v1713823339/jobs/hghg8tnxh96zz5yo7nva.jpg', 3); diff --git a/src/main/resources/fop-config.xml b/src/main/resources/fop-config.xml new file mode 100644 index 00000000..28ef8b0c --- /dev/null +++ b/src/main/resources/fop-config.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/images/svg_voucher.svg b/src/main/resources/images/svg_voucher.svg new file mode 100644 index 00000000..cc3c4efc --- /dev/null +++ b/src/main/resources/images/svg_voucher.svg @@ -0,0 +1,68 @@ + + + + + +Data Documento: +22/05/2024 + +Detalhes da compraVOUCHER: +AD12541V + +Serviço: +Lavar o carro + +Data Compra: +02/04/2024 + +Data Vencimento: +17/04/2024 + +Comprador(a): +Nome comprador + +Documento: +111.111.111-11 + +Email: +thryssai@gmail.com + +Telefone: +42999935496 + +Vendedor(a): +Nome vendedor + +Documento: +111.111.111-11 + +Email: +thryssai@gmail.com + +Telefone: +42999935496 + +Endereço: +Jundiai , 241 - Guarapuava/PR + +Obeservações: + + + + + + +Valor Pago: R$ +150,00 + + + + + + + + + + + + diff --git a/src/main/resources/images/voucher-copia.svg b/src/main/resources/images/voucher-copia.svg new file mode 100644 index 00000000..fda689fd --- /dev/null +++ b/src/main/resources/images/voucher-copia.svg @@ -0,0 +1,64 @@ + + + + +Detalhes da compra + + VOUCHER + numero + + Serviço: + nome servico + + Data Compra: + 02/04/2024 + + Data Vencimento: + 17/04/2024 + +Comprador(a): +Nome comprador + + Documento: +111.111.111-11 + + Telefone: +42999935496 + + Telefone: + 42999935496 + + Documento: +111.111.111-11 + + Vendedor(a): +Nome vendedor + +Email: +thryssai@gmail.com + + Email: +thryssai@gmail.com + +Endereço: +Jundiai , 241 - Guarapuava/PR + +Obeservações: + + + + + +Pagamento: + PIX + +Valor Pago: R$ +150,00 + + + + + + + + diff --git a/src/main/resources/images/voucher.svg b/src/main/resources/images/voucher.svg new file mode 100644 index 00000000..f3d4148d --- /dev/null +++ b/src/main/resources/images/voucher.svg @@ -0,0 +1,57 @@ + + + + +Detalhes da compra + + VOUCHER + numero + + Serviço: + nome servico + + Data Compra: + 02/04/2024 + +Comprador(a): + +Nome comprador +111.111.111-11 +111.111.111-11 +42999935496 +42999935496 +111.111.111-11 +Nome vendedor +Documento: +Telefone: +Telefone: +Documento: +Vendedor(a): +Email: +thryssai@gmail.com +thryssai@gmail.com +Endereço: +Jundiai , 241 - Guarapuava/PR +Obeservações: +Email: + +Data Vencimento: +17/04/2024 + + + + + + +Pagamento: +Valor Pago: R$ +150,00 +PIX + + + + + + + + diff --git a/src/main/resources/images/voucher_pagamento.svg b/src/main/resources/images/voucher_pagamento.svg new file mode 100644 index 00000000..034d9c3c --- /dev/null +++ b/src/main/resources/images/voucher_pagamento.svg @@ -0,0 +1,8 @@ + + + + CERTIFICADO + NOME + + ANO + \ No newline at end of file diff --git a/src/main/resources/static/fonts/Roboto-Black.ttf b/src/main/resources/static/fonts/Roboto-Black.ttf new file mode 100644 index 00000000..43a00e0d Binary files /dev/null and b/src/main/resources/static/fonts/Roboto-Black.ttf differ diff --git a/src/main/resources/static/fonts/Roboto-Bold.ttf b/src/main/resources/static/fonts/Roboto-Bold.ttf new file mode 100644 index 00000000..37424579 Binary files /dev/null and b/src/main/resources/static/fonts/Roboto-Bold.ttf differ diff --git a/src/main/resources/static/fonts/Roboto-Regular.ttf b/src/main/resources/static/fonts/Roboto-Regular.ttf new file mode 100644 index 00000000..3d6861b4 Binary files /dev/null and b/src/main/resources/static/fonts/Roboto-Regular.ttf differ diff --git a/src/main/webapp/WEB-INF/tags/banner.tag b/src/main/webapp/WEB-INF/tags/banner.tag index edcd0049..84b343e8 100644 --- a/src/main/webapp/WEB-INF/tags/banner.tag +++ b/src/main/webapp/WEB-INF/tags/banner.tag @@ -13,7 +13,7 @@ diff --git a/src/main/webapp/WEB-INF/tags/my-ads-combined.tag b/src/main/webapp/WEB-INF/tags/my-ads-combined.tag new file mode 100644 index 00000000..af929528 --- /dev/null +++ b/src/main/webapp/WEB-INF/tags/my-ads-combined.tag @@ -0,0 +1,38 @@ +<%@tag description="Servicebook - Banner template" pageEncoding="UTF-8" %> +<%@attribute name="cities" type="java.util.List" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %> + +<%@ attribute name="items" required="false" type="java.util.ArrayList"%> + + +
+ Serviços Combinados + ver mais navigate_next +
+ +
+

${service.professionalServiceOffering.service.expertise.name}

+
+
+ ${service.professionalServicePackageOffering.duration} +
+
+
+ +
+ +
+
+
+ ${service.professionalServicePackageOffering.description} +
+
+
+
+

+
+
+

${service.professionalServiceOffering.service.name}

+
+
diff --git a/src/main/webapp/WEB-INF/tags/my-ads-package.tag b/src/main/webapp/WEB-INF/tags/my-ads-package.tag new file mode 100644 index 00000000..869e5de4 --- /dev/null +++ b/src/main/webapp/WEB-INF/tags/my-ads-package.tag @@ -0,0 +1,44 @@ +<%@tag description="Servicebook - Banner template" pageEncoding="UTF-8" %> +<%@attribute name="cities" type="java.util.List" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %> + +<%@ attribute name="itemsService" required="false" type="java.util.ArrayList" %> + + +
+ Pacote de Serviços + ver mais navigate_next +
+ +
+

${service.service.expertise.name}

+ +
+
+ ${service.duration} +
+
+
+ +
+ +
+
+ +
+

${service.description}

+

Pacote com ${service.amount}

+
+
+ +
+
+

+
+
+

${service.service.name}

+
+
diff --git a/src/main/webapp/WEB-INF/tags/navbar-client.tag b/src/main/webapp/WEB-INF/tags/navbar-client.tag index dbb0b2b3..5aeb1b9a 100644 --- a/src/main/webapp/WEB-INF/tags/navbar-client.tag +++ b/src/main/webapp/WEB-INF/tags/navbar-client.tag @@ -10,9 +10,6 @@