Skip to content

Commit

Permalink
VKT(Frontend & Backend): enrollment appointment continues
Browse files Browse the repository at this point in the history
  • Loading branch information
jrkkp committed Oct 2, 2024
1 parent b36b02f commit 1845ba1
Show file tree
Hide file tree
Showing 27 changed files with 615 additions and 98 deletions.
19 changes: 18 additions & 1 deletion backend/vkt/src/main/java/fi/oph/vkt/api/PublicController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import fi.oph.vkt.api.dto.PublicEducationDTO;
import fi.oph.vkt.api.dto.PublicEnrollmentAppointmentDTO;
import fi.oph.vkt.api.dto.PublicEnrollmentAppointmentUpdateDTO;
import fi.oph.vkt.api.dto.PublicEnrollmentCreateDTO;
import fi.oph.vkt.api.dto.PublicEnrollmentDTO;
import fi.oph.vkt.api.dto.PublicEnrollmentInitialisationDTO;
Expand All @@ -29,6 +30,7 @@
import fi.oph.vkt.util.SessionUtil;
import fi.oph.vkt.util.UIRouteUtil;
import fi.oph.vkt.util.exception.APIException;
import fi.oph.vkt.util.exception.APIExceptionType;
import fi.oph.vkt.util.exception.NotFoundException;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
Expand Down Expand Up @@ -160,6 +162,21 @@ public PublicEnrollmentAppointmentDTO getEnrollmentAppointment(
return publicEnrollmentService.getEnrollmentAppointment(enrollmentAppointmentId, person);
}

@PostMapping(path = "/enrollment/appointment/{enrollmentAppointmentId:\\d+}")
@ResponseStatus(HttpStatus.CREATED)
public PublicEnrollmentAppointmentDTO saveEnrollmentAppointment(
@RequestBody @Valid final PublicEnrollmentAppointmentUpdateDTO dto,
@PathVariable final long enrollmentAppointmentId,
final HttpSession session) {
final Person person = publicAuthService.getPersonFromSession(session);

if (enrollmentAppointmentId != dto.id()) {
throw new APIException(APIExceptionType.RESERVATION_PERSON_SESSION_MISMATCH);
}

return publicEnrollmentService.saveEnrollmentAppointment(dto, person);
}

@GetMapping(path = "/education")
public List<PublicEducationDTO> getEducation(final HttpSession session) throws JsonProcessingException {
final Person person = publicAuthService.getPersonFromSession(session);
Expand Down Expand Up @@ -332,7 +349,7 @@ public void logout(final HttpSession session, final HttpServletResponse httpResp
httpResponse.sendRedirect(publicAuthService.createCasLogoutUrl());
}

@GetMapping(path = "/payment/create/{targetId:\\d+}/{type:\\w}/redirect")
@GetMapping(path = "/payment/create/{targetId:\\d+}/{type:\\w+}/redirect")
public void createPaymentAndRedirect(
@PathVariable final Long targetId,
@PathVariable final String type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ public record PublicEnrollmentAppointmentDTO(
String street,
String postalCode,
String town,
String country
String country,
@NonNull @NotNull PublicPersonDTO person
) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package fi.oph.vkt.api.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.NonNull;

@Builder
public record PublicEnrollmentAppointmentUpdateDTO(
@NotNull long id,
String previousEnrollment,
@NonNull @NotNull Boolean digitalCertificateConsent,
@NonNull @NotBlank String phoneNumber,
String street,
String postalCode,
String town,
String country
) {
}
42 changes: 33 additions & 9 deletions backend/vkt/src/main/java/fi/oph/vkt/service/PaymentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@ private EnrollmentStatus getPaymentSuccessEnrollmentNextStatus(final Enrollment
return enrollment.enrollmentNeedsApproval() ? EnrollmentStatus.AWAITING_APPROVAL : EnrollmentStatus.COMPLETED;
}

private void setEnrollmentStatus(final EnrollmentAppointment enrollmentAppointment, final PaymentStatus paymentStatus) {
switch (paymentStatus) {
case NEW, PENDING, DELAYED -> {}
case OK -> enrollmentAppointment.setStatus(EnrollmentStatus.COMPLETED);
case FAIL -> {
enrollmentAppointment.setStatus(EnrollmentStatus.CANCELED_UNFINISHED_ENROLLMENT);
}
}
}

private void setEnrollmentStatus(final Enrollment enrollment, final PaymentStatus paymentStatus) {
switch (paymentStatus) {
case NEW -> {
Expand Down Expand Up @@ -153,14 +163,27 @@ public Payment finalizePayment(final Long paymentId, final Map<String, String> p
throw new APIException(APIExceptionType.PAYMENT_REFERENCE_MISMATCH);
}

final Enrollment enrollment = payment.getEnrollment();
setEnrollmentStatus(enrollment, newStatus);
if (payment.getEnrollment() != null) {
final Enrollment enrollment = payment.getEnrollment();
setEnrollmentStatus(enrollment, newStatus);

payment.setPaymentStatus(newStatus);
paymentRepository.saveAndFlush(payment);
payment.setPaymentStatus(newStatus);
paymentRepository.saveAndFlush(payment);

if (newStatus == PaymentStatus.OK) {
publicEnrollmentEmailService.sendEnrollmentConfirmationEmail(enrollment);
}
} else {
final EnrollmentAppointment enrollmentAppointment = payment.getEnrollmentAppointment();
setEnrollmentStatus(enrollmentAppointment, newStatus);

if (newStatus == PaymentStatus.OK) {
publicEnrollmentEmailService.sendEnrollmentConfirmationEmail(enrollment);
payment.setPaymentStatus(newStatus);
paymentRepository.saveAndFlush(payment);

// FIXME
if (newStatus == PaymentStatus.OK) {
//publicEnrollmentEmailService.sendEnrollmentConfirmationEmail(enrollmentAppointment);
}
}

return payment;
Expand All @@ -181,9 +204,10 @@ private String getFinalizePaymentRedirectUrl(final Long paymentId, final String
final Payment payment = paymentRepository
.findById(paymentId)
.orElseThrow(() -> new NotFoundException("Payment not found"));
final ExamEvent examEvent = payment.getEnrollment().getExamEvent();

return String.format("%s/ilmoittaudu/%d/maksu/%s", baseUrl, examEvent.getId(), state);

return payment.getEnrollment() != null
? String.format("%s/ilmoittaudu/%d/maksu/%s", baseUrl, payment.getEnrollment().getExamEvent().getId(), state)
: String.format("%s/markkinapaikka/%d/maksu/%s", baseUrl, payment.getEnrollmentAppointment().getId(), state);
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import fi.oph.vkt.api.dto.FreeEnrollmentDetailsDTO;
import fi.oph.vkt.api.dto.PublicEducationDTO;
import fi.oph.vkt.api.dto.PublicEnrollmentAppointmentDTO;
import fi.oph.vkt.api.dto.PublicEnrollmentAppointmentUpdateDTO;
import fi.oph.vkt.api.dto.PublicEnrollmentCreateDTO;
import fi.oph.vkt.api.dto.PublicEnrollmentDTO;
import fi.oph.vkt.api.dto.PublicEnrollmentInitialisationDTO;
Expand Down Expand Up @@ -474,6 +475,13 @@ private void clearAddress(final Enrollment enrollment) {
enrollment.setCountry(null);
}

private void clearAddress(final EnrollmentAppointment enrollmentAppointment) {
enrollmentAppointment.setStreet(null);
enrollmentAppointment.setPostalCode(null);
enrollmentAppointment.setTown(null);
enrollmentAppointment.setCountry(null);
}

@Transactional
public PublicEnrollmentDTO createEnrollmentToQueue(
final PublicEnrollmentCreateDTO dto,
Expand Down Expand Up @@ -590,6 +598,8 @@ public Map<String, String> getPresignedPostRequest(
private PublicEnrollmentAppointmentDTO createEnrollmentAppointmentDTO(
final EnrollmentAppointment enrollmentAppointment
) {
final PublicPersonDTO personDTO = PersonUtil.createPublicPersonDTO(enrollmentAppointment.getPerson());

return PublicEnrollmentAppointmentDTO
.builder()
.id(enrollmentAppointment.getId())
Expand All @@ -608,6 +618,7 @@ private PublicEnrollmentAppointmentDTO createEnrollmentAppointmentDTO(
.town(enrollmentAppointment.getTown())
.country(enrollmentAppointment.getCountry())
.status(enrollmentAppointment.getStatus())
.person(personDTO)
.build();
}

Expand All @@ -626,4 +637,29 @@ public PublicEnrollmentAppointmentDTO getEnrollmentAppointment(

return createEnrollmentAppointmentDTO(enrollmentAppointment);
}

@Transactional
public PublicEnrollmentAppointmentDTO saveEnrollmentAppointment(final PublicEnrollmentAppointmentUpdateDTO dto, final Person person) {
final EnrollmentAppointment enrollmentAppointment = enrollmentAppointmentRepository.getReferenceById(
dto.id()
);

if (person.getId() != enrollmentAppointment.getPerson().getId()) {
throw new APIException(APIExceptionType.RESERVATION_PERSON_SESSION_MISMATCH);
}

enrollmentAppointment.setPerson(person);
enrollmentAppointment.setStreet(dto.street());
enrollmentAppointment.setPostalCode(dto.postalCode());
enrollmentAppointment.setTown(dto.town());
enrollmentAppointment.setCountry(dto.country());

if (dto.digitalCertificateConsent()) {
clearAddress(enrollmentAppointment);
}

enrollmentAppointmentRepository.saveAndFlush(enrollmentAppointment);

return createEnrollmentAppointmentDTO(enrollmentAppointment);
}
}
1 change: 1 addition & 0 deletions frontend/packages/vkt/public/i18n/fi-FI/public.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"EducationDetails": "Koulutustiedot",
"FillContactDetails": "Täytä yhteystietosi",
"Payment": "Maksu",
"PaymentFail": "Maksu",
"PaymentSuccess": "Valmis",
"Preview": "Esikatsele",
"SelectExam": "Valitse tutkinto"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,36 @@ import { useDialog } from 'shared/hooks';
import { useCommonTranslation, usePublicTranslation } from 'configs/i18n';
import { useAppDispatch } from 'configs/redux';
import { PublicEnrollmentAppointmentFormStep } from 'enums/publicEnrollment';
import {
loadPublicEnrollmentSave,
setLoadingPayment,
} from 'redux/reducers/publicEnrollmentAppointment';
import { RouteUtils } from 'utils/routes';

export const PublicEnrollmentAppointmentControlButtons = ({
activeStep,
enrollment,
isStepValid,
setShowValidation,
submitStatus,
}: {
activeStep: PublicEnrollmentAppointmentFormStep;
enrollment: PublicEnrollmentAppointment;
isStepValid: boolean;
setShowValidation: (showValidation: boolean) => void;
submitStatus: APIResponseStatus;
}) => {
const { t } = usePublicTranslation({
keyPrefix: 'vkt.component.publicEnrollment.controlButtons',
});
const translateCommon = useCommonTranslation();
const [isPaymentLoading, setIsPaymentLoading] = useState(false);

// FIXME
const submitStatus = APIResponseStatus.NotStarted;
const dispatch = useAppDispatch();
const navigate = useNavigate();

const { showDialog } = useDialog();

Check warning on line 42 in frontend/packages/vkt/src/components/publicEnrollmentAppointment/PublicEnrollmentAppointmentControlButtons.tsx

View workflow job for this annotation

GitHub Actions / frontend / common-frontend (20.9.0)

'showDialog' is assigned a value but never used. Allowed unused vars must match /^_/u

const submitButtonText = () => {
return t('pay');
};

const handleCancelBtnClick = () => {
// FIXME
};
Expand All @@ -51,6 +51,7 @@ export const PublicEnrollmentAppointmentControlButtons = ({
setTimeout(() => {
window.location.href = RouteUtils.getPaymentCreateApiRoute(
enrollment.id,
'appointment',
);
}, 200);
dispatch(setLoadingPayment());
Expand All @@ -76,12 +77,7 @@ export const PublicEnrollmentAppointmentControlButtons = ({
if (isStepValid) {
setIsPaymentLoading(true);
setShowValidation(false);
dispatch(
loadPublicEnrollmentUpdate({
enrollment,
examEventId,
}),
);
dispatch(loadPublicEnrollmentSave(enrollment));
} else {
setShowValidation(true);
}
Expand Down Expand Up @@ -142,14 +138,16 @@ export const PublicEnrollmentAppointmentControlButtons = ({
data-testid="public-enrollment__controlButtons__submit"
disabled={isPaymentLoading}
>
{submitButtonText()}
{t('pay')}
</CustomButton>
</LoadingProgressIndicator>
);

const renderBack = true;
const renderNext = activeStep === PublicEnrollmentAppointmentFormStep.FillContactDetails;
const renderSubmit = activeStep === PublicEnrollmentAppointmentFormStep.Preview;
const renderNext =
activeStep === PublicEnrollmentAppointmentFormStep.FillContactDetails;
const renderSubmit =
activeStep === PublicEnrollmentAppointmentFormStep.Preview;

return (
<div className="columns flex-end gapped margin-top-lg">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import { PublicEnrollmentAppointmentStepContents } from 'components/publicEnroll
import { PublicEnrollmentAppointmentStepHeading } from 'components/publicEnrollmentAppointment/PublicEnrollmentAppointmentStepHeading';
import { PublicEnrollmentAppointmentStepper } from 'components/publicEnrollmentAppointment/PublicEnrollmentAppointmentStepper';
import { useCommonTranslation } from 'configs/i18n';
import { PublicEnrollmentFormStep } from 'enums/publicEnrollment';
import { useAppSelector } from 'configs/redux';
import { PublicEnrollmentAppointmentFormStep } from 'enums/publicEnrollment';
import { PublicEnrollmentAppointment } from 'interfaces/publicEnrollment';
import { publicEnrollmentAppointmentSelector } from 'redux/selectors/publicEnrollmentAppointment';

export const PublicEnrollmentAppointmentDesktopGrid = ({
activeStep,
Expand All @@ -27,6 +29,16 @@ export const PublicEnrollmentAppointmentDesktopGrid = ({
}) => {
const translateCommon = useCommonTranslation();

const { enrollmentSubmitStatus } = useAppSelector(
publicEnrollmentAppointmentSelector,
);

const showPaymentSum =
activeStep === PublicEnrollmentAppointmentFormStep.Preview;
const showControlButtons =
activeStep > PublicEnrollmentAppointmentFormStep.Authenticate &&
activeStep <= PublicEnrollmentAppointmentFormStep.Preview;

return (
<>
<Grid className="public-enrollment__grid" item>
Expand All @@ -45,16 +57,14 @@ export const PublicEnrollmentAppointmentDesktopGrid = ({
showValidation={showValidation}
setIsStepValid={setIsStepValid}
/>
{activeStep > PublicEnrollmentFormStep.Authenticate && (
<PublicEnrollmentAppointmentPaymentSum />
)}
{activeStep > PublicEnrollmentFormStep.Authenticate && (
{showPaymentSum && <PublicEnrollmentAppointmentPaymentSum />}
{showControlButtons && (
<PublicEnrollmentAppointmentControlButtons
activeStep={activeStep}
enrollment={enrollment}
setShowValidation={setShowValidation}
isStepValid={isStepValid}
enrollment={enrollment}
submitStatus={enrollmentSubmitStatus}
/>
)}
</div>
Expand Down
Loading

0 comments on commit 1845ba1

Please sign in to comment.