diff --git a/backend/vkt/src/main/java/fi/oph/vkt/api/PublicController.java b/backend/vkt/src/main/java/fi/oph/vkt/api/PublicController.java index f46656219..df437d1c8 100644 --- a/backend/vkt/src/main/java/fi/oph/vkt/api/PublicController.java +++ b/backend/vkt/src/main/java/fi/oph/vkt/api/PublicController.java @@ -321,20 +321,22 @@ public void logout(final HttpSession session, final HttpServletResponse httpResp httpResponse.sendRedirect(publicAuthService.createCasLogoutUrl()); } - @GetMapping(path = "/payment/create/{enrollmentId:\\d+}/redirect") + @GetMapping(path = "/payment/create/{targetId:\\d+}/{type:\\w}/redirect") public void createPaymentAndRedirect( - @PathVariable final Long enrollmentId, + @PathVariable final Long targetId, + @PathVariable final String type, @RequestParam final Optional locale, final HttpSession session, final HttpServletResponse httpResponse ) throws IOException { try { + final EnrollmentType enrollmentType = EnrollmentType.fromString(type); final Person person = publicPersonService.getPerson(SessionUtil.getPersonId(session)); - final String redirectUrl = paymentService.createPaymentForEnrollment( - enrollmentId, - person, - locale.isPresent() ? AppLocale.fromString(locale.get()) : AppLocale.FI - ); + final AppLocale localeOrDefault = locale.isPresent() ? AppLocale.fromString(locale.get()) : AppLocale.FI; + + final String redirectUrl = enrollmentType.equals(EnrollmentType.APPOINTMENT) + ? paymentService.createPaymentForEnrollmentAppointment(targetId, person, localeOrDefault) + : paymentService.createPaymentForEnrollment(targetId, person, localeOrDefault); httpResponse.sendRedirect(redirectUrl); } catch (final APIException e) { diff --git a/backend/vkt/src/main/java/fi/oph/vkt/service/PaymentService.java b/backend/vkt/src/main/java/fi/oph/vkt/service/PaymentService.java index cd7b03ced..ecf64357c 100644 --- a/backend/vkt/src/main/java/fi/oph/vkt/service/PaymentService.java +++ b/backend/vkt/src/main/java/fi/oph/vkt/service/PaymentService.java @@ -2,6 +2,7 @@ import fi.oph.vkt.api.dto.FreeEnrollmentDetails; import fi.oph.vkt.model.Enrollment; +import fi.oph.vkt.model.EnrollmentAppointment; import fi.oph.vkt.model.ExamEvent; import fi.oph.vkt.model.Payment; import fi.oph.vkt.model.Person; @@ -14,6 +15,7 @@ import fi.oph.vkt.payment.paytrail.Item; import fi.oph.vkt.payment.paytrail.PaytrailConfig; import fi.oph.vkt.payment.paytrail.PaytrailResponseDTO; +import fi.oph.vkt.repository.EnrollmentAppointmentRepository; import fi.oph.vkt.repository.EnrollmentRepository; import fi.oph.vkt.repository.PaymentRepository; import fi.oph.vkt.util.EnrollmentUtil; @@ -24,6 +26,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,6 +43,7 @@ public class PaymentService { private final PaymentProvider paymentProvider; private final PaymentRepository paymentRepository; private final EnrollmentRepository enrollmentRepository; + private final EnrollmentAppointmentRepository enrollmentAppointmentRepository; private final Environment environment; private final PublicEnrollmentEmailService publicEnrollmentEmailService; @@ -53,6 +57,24 @@ private Item getItem(final EnrollmentSkill enrollmentSkill, final int unitPrice) .build(); } + private List getItems(final EnrollmentAppointment enrollmentAppointment) { + final List itemList = new ArrayList<>(); + + if (enrollmentAppointment.isTextualSkill()) { + itemList.add(getItem(EnrollmentSkill.TEXTUAL, EnrollmentUtil.getTextualSkillFee(enrollmentAppointment))); + } + if (enrollmentAppointment.isOralSkill()) { + itemList.add(getItem(EnrollmentSkill.ORAL, EnrollmentUtil.getOralSkillFee(enrollmentAppointment))); + } + if (enrollmentAppointment.isUnderstandingSkill()) { + itemList.add( + getItem(EnrollmentSkill.UNDERSTANDING, EnrollmentUtil.getUnderstandingSkillFee(enrollmentAppointment)) + ); + } + + return itemList; + } + private List getItems(final Enrollment enrollment, final FreeEnrollmentDetails freeEnrollmentDetails) { final List itemList = new ArrayList<>(); @@ -164,6 +186,53 @@ private String getFinalizePaymentRedirectUrl(final Long paymentId, final String return String.format("%s/ilmoittaudu/%d/maksu/%s", baseUrl, examEvent.getId(), state); } + @Transactional + public String createPaymentForEnrollmentAppointment( + final Long enrollmentId, + final Person person, + final AppLocale appLocale + ) { + final EnrollmentAppointment enrollmentAppointment = enrollmentAppointmentRepository + .findById(enrollmentId) + .orElseThrow(() -> new NotFoundException("Enrollment not found")); + + if (enrollmentAppointment.getPerson() == null || enrollmentAppointment.getPerson().getId() != person.getId()) { + throw new APIException(APIExceptionType.PAYMENT_PERSON_SESSION_MISMATCH); + } + + final List itemList = getItems(enrollmentAppointment); + final Customer customer = Customer + .builder() + .email(getCustomerField(enrollmentAppointment.getEmail(), Customer.EMAIL_MAX_LENGTH)) + .phone(getCustomerField(enrollmentAppointment.getPhoneNumber(), Customer.PHONE_MAX_LENGTH)) + .firstName(getCustomerField(person.getFirstName(), Customer.FIRST_NAME_MAX_LENGTH)) + .lastName(getCustomerField(person.getLastName(), Customer.LAST_NAME_MAX_LENGTH)) + .build(); + + final int amount = EnrollmentUtil.getTotalFee(enrollmentAppointment); + + final Payment payment = new Payment(); + payment.setEnrollmentAppointment(enrollmentAppointment); + payment.setAmount(amount); + paymentRepository.saveAndFlush(payment); + + final PaytrailResponseDTO response = paymentProvider.createPayment( + itemList, + payment.getId(), + customer, + amount, + appLocale + ); + + payment.setTransactionId(response.getTransactionId()); + payment.setReference(response.getReference()); + payment.setPaymentUrl(response.getHref()); + payment.setPaymentStatus(PaymentStatus.NEW); + paymentRepository.saveAndFlush(payment); + + return payment.getPaymentUrl(); + } + @Transactional public String createPaymentForEnrollment(final Long enrollmentId, final Person person, final AppLocale appLocale) { final Enrollment enrollment = enrollmentRepository diff --git a/backend/vkt/src/main/java/fi/oph/vkt/util/EnrollmentUtil.java b/backend/vkt/src/main/java/fi/oph/vkt/util/EnrollmentUtil.java index 779705bfa..4b1e507b6 100644 --- a/backend/vkt/src/main/java/fi/oph/vkt/util/EnrollmentUtil.java +++ b/backend/vkt/src/main/java/fi/oph/vkt/util/EnrollmentUtil.java @@ -2,6 +2,7 @@ import fi.oph.vkt.api.dto.FreeEnrollmentDetails; import fi.oph.vkt.model.Enrollment; +import fi.oph.vkt.model.EnrollmentAppointment; import fi.oph.vkt.model.Person; import fi.oph.vkt.model.type.ExamLevel; import java.util.regex.Matcher; @@ -12,6 +13,14 @@ public class EnrollmentUtil { private static final int SKILL_FEE = 25700; public static final Integer FREE_ENROLLMENT_LIMIT = 3; + public static int getTotalFee(final EnrollmentAppointment enrollmentAppointment) { + return ( + getTextualSkillFee(enrollmentAppointment) + + getOralSkillFee(enrollmentAppointment) + + getUnderstandingSkillFee(enrollmentAppointment) + ); + } + public static int getTotalFee(final Enrollment enrollment, final FreeEnrollmentDetails freeEnrollmentDetails) { return ( getTextualSkillFee(enrollment, freeEnrollmentDetails) + @@ -20,6 +29,10 @@ public static int getTotalFee(final Enrollment enrollment, final FreeEnrollmentD ); } + public static int getTextualSkillFee(final EnrollmentAppointment enrollmentAppointment) { + return enrollmentAppointment.isTextualSkill() ? SKILL_FEE : 0; + } + public static int getTextualSkillFee(final Enrollment enrollment, final FreeEnrollmentDetails freeEnrollmentDetails) { if (!enrollment.isTextualSkill()) { return 0; @@ -30,6 +43,10 @@ public static int getTextualSkillFee(final Enrollment enrollment, final FreeEnro : SKILL_FEE; } + public static int getOralSkillFee(final EnrollmentAppointment enrollmentAppointment) { + return enrollmentAppointment.isOralSkill() ? SKILL_FEE : 0; + } + public static int getOralSkillFee(final Enrollment enrollment, final FreeEnrollmentDetails freeEnrollmentDetails) { if (!enrollment.isOralSkill()) { return 0; @@ -52,6 +69,14 @@ public static boolean validateAttachmentId(final String attachmentId, final Pers return parsedExamEventId.equals(examEventId) && matcher.group(2).equals(person.getUuid().toString()); } + public static int getUnderstandingSkillFee(final EnrollmentAppointment enrollmentAppointment) { + if (enrollmentAppointment.isTextualSkill() && enrollmentAppointment.isOralSkill()) { + return 0; + } + + return SKILL_FEE; + } + public static int getUnderstandingSkillFee(final Enrollment enrollment) { if (enrollment.isTextualSkill() && enrollment.isOralSkill()) { return 0;