diff --git a/pom.xml b/pom.xml index 9c12dc2..e54883c 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ com.github.Podzilla podzilla-utils-lib - v1.1.7 + v1.1.8 diff --git a/src/main/java/com/podzilla/courier/controllers/DeliveryTaskController.java b/src/main/java/com/podzilla/courier/controllers/DeliveryTaskController.java index 56dcec7..dba0b29 100644 --- a/src/main/java/com/podzilla/courier/controllers/DeliveryTaskController.java +++ b/src/main/java/com/podzilla/courier/controllers/DeliveryTaskController.java @@ -1,13 +1,14 @@ package com.podzilla.courier.controllers; -import com.podzilla.courier.dtos.delivery_tasks.SubmitCourierRatingResponseDto; -import com.podzilla.courier.dtos.delivery_tasks.SubmitCourierRatingRequestDto; -import com.podzilla.courier.dtos.delivery_tasks.CancelDeliveryTaskRequestDto; -import com.podzilla.courier.dtos.delivery_tasks.LocationUpdateDto; -import com.podzilla.courier.dtos.delivery_tasks.CancelDeliveryTaskResponseDto; import com.podzilla.courier.dtos.delivery_tasks.CreateDeliveryTaskRequestDto; import com.podzilla.courier.dtos.delivery_tasks.DeliveryTaskResponseDto; import com.podzilla.courier.dtos.delivery_tasks.UpdateDeliveryStatusRequestDto; +import com.podzilla.courier.dtos.delivery_tasks.SubmitCourierRatingResponseDto; +import com.podzilla.courier.dtos.delivery_tasks.CancelDeliveryTaskRequestDto; +import com.podzilla.courier.dtos.delivery_tasks.CancelDeliveryTaskResponseDto; +import com.podzilla.courier.dtos.delivery_tasks.ConfirmDeliveryDto; +import com.podzilla.courier.dtos.delivery_tasks.LocationUpdateDto; +import com.podzilla.courier.dtos.delivery_tasks.SubmitCourierRatingRequestDto; import com.podzilla.courier.models.DeliveryStatus; import com.podzilla.courier.services.delivery_task.DeliveryTaskService; import io.swagger.v3.oas.annotations.Operation; @@ -183,9 +184,9 @@ public ResponseEntity confirmDelivery( @Parameter(description = "ID of the delivery task") @PathVariable final String id, @RequestBody(description = "Confirmation input (e.g., OTP, QR code, or signature)") - @org.springframework.web.bind.annotation.RequestBody final String confirmationInput) { + @org.springframework.web.bind.annotation.RequestBody final ConfirmDeliveryDto confirmDeliveryDto) { LOGGER.info("Received request to confirm delivery for task ID: {}", id); - return deliveryTaskService.confirmDelivery(id, confirmationInput) + return deliveryTaskService.confirmDelivery(id, confirmDeliveryDto.getConfirmationInput()) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } diff --git a/src/main/java/com/podzilla/courier/dtos/delivery_tasks/ConfirmDeliveryDto.java b/src/main/java/com/podzilla/courier/dtos/delivery_tasks/ConfirmDeliveryDto.java new file mode 100644 index 0000000..65b9560 --- /dev/null +++ b/src/main/java/com/podzilla/courier/dtos/delivery_tasks/ConfirmDeliveryDto.java @@ -0,0 +1,12 @@ +package com.podzilla.courier.dtos.delivery_tasks; + +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ConfirmDeliveryDto { + @NotNull(message = "Confirmation input in required") + private String confirmationInput; +} diff --git a/src/main/java/com/podzilla/courier/dtos/delivery_tasks/CreateDeliveryTaskRequestDto.java b/src/main/java/com/podzilla/courier/dtos/delivery_tasks/CreateDeliveryTaskRequestDto.java index 1c89841..be29a6e 100644 --- a/src/main/java/com/podzilla/courier/dtos/delivery_tasks/CreateDeliveryTaskRequestDto.java +++ b/src/main/java/com/podzilla/courier/dtos/delivery_tasks/CreateDeliveryTaskRequestDto.java @@ -1,5 +1,6 @@ package com.podzilla.courier.dtos.delivery_tasks; +import com.podzilla.mq.events.OrderAssignedToCourierEvent.ConfirmationType; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; @@ -15,12 +16,17 @@ public class CreateDeliveryTaskRequestDto { @NotNull(message = "Courier ID is required") private String courierId; - @NotNull(message = "Price is required") - private BigDecimal price; + @NotNull(message = "Total amount is required") + private BigDecimal totalAmount; @NotNull(message = "Order latitude is required") private double orderLatitude; @NotNull(message = "Order longitude is required") private double orderLongitude; + + @NotNull(message = "Confirmation type is required") + private ConfirmationType confirmationType; + + private String signature; } diff --git a/src/main/java/com/podzilla/courier/dtos/delivery_tasks/DeliveryTaskResponseDto.java b/src/main/java/com/podzilla/courier/dtos/delivery_tasks/DeliveryTaskResponseDto.java index 25c6f16..ecfbeac 100644 --- a/src/main/java/com/podzilla/courier/dtos/delivery_tasks/DeliveryTaskResponseDto.java +++ b/src/main/java/com/podzilla/courier/dtos/delivery_tasks/DeliveryTaskResponseDto.java @@ -2,10 +2,12 @@ import com.podzilla.courier.models.DeliveryStatus; +import com.podzilla.mq.events.OrderAssignedToCourierEvent.ConfirmationType; import java.math.BigDecimal; -public record DeliveryTaskResponseDto(String id, String orderId, String courierId, BigDecimal price, +public record DeliveryTaskResponseDto(String id, String orderId, String courierId, BigDecimal totalAmount, DeliveryStatus status, Double orderLatitude, Double orderLongitude, - Double courierLatitude, Double courierLongitude) { + Double courierLatitude, Double courierLongitude, + ConfirmationType confirmationType) { } diff --git a/src/main/java/com/podzilla/courier/dtos/delivery_tasks/SubmitCourierRatingRequestDto.java b/src/main/java/com/podzilla/courier/dtos/delivery_tasks/SubmitCourierRatingRequestDto.java index 76e40ea..7a6bf0d 100644 --- a/src/main/java/com/podzilla/courier/dtos/delivery_tasks/SubmitCourierRatingRequestDto.java +++ b/src/main/java/com/podzilla/courier/dtos/delivery_tasks/SubmitCourierRatingRequestDto.java @@ -6,6 +6,8 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import java.math.BigDecimal; + @Getter @AllArgsConstructor public class SubmitCourierRatingRequestDto { @@ -13,5 +15,5 @@ public class SubmitCourierRatingRequestDto { @NotNull(message = "Rating is required") @Min(value = 1, message = "Rating must be at least 1") @Max(value = 5, message = "Rating must be at most 5") - private Double rating; + private BigDecimal rating; } diff --git a/src/main/java/com/podzilla/courier/dtos/delivery_tasks/SubmitCourierRatingResponseDto.java b/src/main/java/com/podzilla/courier/dtos/delivery_tasks/SubmitCourierRatingResponseDto.java index f6ea97f..dfddda9 100644 --- a/src/main/java/com/podzilla/courier/dtos/delivery_tasks/SubmitCourierRatingResponseDto.java +++ b/src/main/java/com/podzilla/courier/dtos/delivery_tasks/SubmitCourierRatingResponseDto.java @@ -1,4 +1,6 @@ package com.podzilla.courier.dtos.delivery_tasks; -public record SubmitCourierRatingResponseDto(String id, String orderId, String courierId, Double courierRating) { +import java.math.BigDecimal; + +public record SubmitCourierRatingResponseDto(String id, String orderId, String courierId, BigDecimal courierRating) { } diff --git a/src/main/java/com/podzilla/courier/events/CourierAssignmentEventConsumer.java b/src/main/java/com/podzilla/courier/events/CourierAssignmentEventConsumer.java index e4f2a6b..1fc8444 100644 --- a/src/main/java/com/podzilla/courier/events/CourierAssignmentEventConsumer.java +++ b/src/main/java/com/podzilla/courier/events/CourierAssignmentEventConsumer.java @@ -16,7 +16,6 @@ public CourierAssignmentEventConsumer(final DeliveryTaskService deliveryTaskServ this.deliveryTaskService = deliveryTaskService; } - @RabbitListener(queues = EventsConstants.COURIER_ORDER_EVENT_QUEUE) @RabbitListener(queues = EventsConstants.COURIER_ORDER_EVENT_QUEUE) public void handleEvent(final BaseEvent event) { if (event instanceof OrderAssignedToCourierEvent) { @@ -24,10 +23,11 @@ public void handleEvent(final BaseEvent event) { CreateDeliveryTaskRequestDto deliveryTask = new CreateDeliveryTaskRequestDto( courierEvent.getOrderId(), courierEvent.getCourierId(), - courierEvent.getPrice(), + courierEvent.getTotalAmount(), courierEvent.getOrderLatitude(), - courierEvent.getOrderLongitude() - ); + courierEvent.getOrderLongitude(), + courierEvent.getConfirmationType(), + courierEvent.getSignature()); deliveryTaskService.createDeliveryTask(deliveryTask); } } diff --git a/src/main/java/com/podzilla/courier/mappers/DeliveryTaskMapper.java b/src/main/java/com/podzilla/courier/mappers/DeliveryTaskMapper.java index 48a6f9c..8eac27f 100644 --- a/src/main/java/com/podzilla/courier/mappers/DeliveryTaskMapper.java +++ b/src/main/java/com/podzilla/courier/mappers/DeliveryTaskMapper.java @@ -8,31 +8,33 @@ public class DeliveryTaskMapper { - public static DeliveryTask toEntity(CreateDeliveryTaskRequestDto dto) { + public static DeliveryTask toEntity(final CreateDeliveryTaskRequestDto dto) { DeliveryTask task = new DeliveryTask(); task.setOrderId(dto.getOrderId()); task.setCourierId(dto.getCourierId()); - task.setPrice(dto.getPrice()); + task.setTotalAmount(dto.getTotalAmount()); task.setOrderLatitude(dto.getOrderLatitude()); task.setOrderLongitude(dto.getOrderLongitude()); + task.setConfirmationType(dto.getConfirmationType()); return task; } - public static DeliveryTaskResponseDto toCreateResponseDto(DeliveryTask task) { + public static DeliveryTaskResponseDto toCreateResponseDto(final DeliveryTask task) { return new DeliveryTaskResponseDto( task.getId(), task.getOrderId(), task.getCourierId(), - task.getPrice(), + task.getTotalAmount(), task.getStatus(), task.getOrderLatitude(), task.getOrderLongitude(), task.getCourierLatitude(), - task.getCourierLongitude() + task.getCourierLongitude(), + task.getConfirmationType() ); } - public static CancelDeliveryTaskResponseDto toCancelResponseDto(DeliveryTask task) { + public static CancelDeliveryTaskResponseDto toCancelResponseDto(final DeliveryTask task) { return new CancelDeliveryTaskResponseDto( task.getId(), task.getOrderId(), @@ -41,7 +43,7 @@ public static CancelDeliveryTaskResponseDto toCancelResponseDto(DeliveryTask tas ); } - public static SubmitCourierRatingResponseDto toSubmitCourierRatingResponseDto(DeliveryTask task) { + public static SubmitCourierRatingResponseDto toSubmitCourierRatingResponseDto(final DeliveryTask task) { return new SubmitCourierRatingResponseDto( task.getId(), task.getOrderId(), @@ -49,4 +51,4 @@ public static SubmitCourierRatingResponseDto toSubmitCourierRatingResponseDto(De task.getCourierRating() ); } -} \ No newline at end of file +} diff --git a/src/main/java/com/podzilla/courier/models/ConfirmationType.java b/src/main/java/com/podzilla/courier/models/ConfirmationType.java deleted file mode 100644 index 1fe3be3..0000000 --- a/src/main/java/com/podzilla/courier/models/ConfirmationType.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.podzilla.courier.models; - -public enum ConfirmationType { - OTP, - QR_CODE, - SIGNATURE -} diff --git a/src/main/java/com/podzilla/courier/models/DeliveryTask.java b/src/main/java/com/podzilla/courier/models/DeliveryTask.java index 448a848..831b3c2 100644 --- a/src/main/java/com/podzilla/courier/models/DeliveryTask.java +++ b/src/main/java/com/podzilla/courier/models/DeliveryTask.java @@ -1,5 +1,6 @@ package com.podzilla.courier.models; +import com.podzilla.mq.events.OrderAssignedToCourierEvent.ConfirmationType; import lombok.Data; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @@ -14,7 +15,7 @@ public class DeliveryTask { private String id; private String orderId; private String courierId; - private BigDecimal price; + private BigDecimal totalAmount; private DeliveryStatus status; private Double orderLatitude; private Double orderLongitude; @@ -24,7 +25,7 @@ public class DeliveryTask { private String qrCode; private String signature; private String cancellationReason; - private Double courierRating; + private BigDecimal courierRating; private LocalDateTime ratingTimestamp; private LocalDateTime createdAt; private LocalDateTime updatedAt; diff --git a/src/main/java/com/podzilla/courier/services/delivery_task/DeliveryTaskService.java b/src/main/java/com/podzilla/courier/services/delivery_task/DeliveryTaskService.java index af246cd..3de58b1 100644 --- a/src/main/java/com/podzilla/courier/services/delivery_task/DeliveryTaskService.java +++ b/src/main/java/com/podzilla/courier/services/delivery_task/DeliveryTaskService.java @@ -5,7 +5,6 @@ import com.podzilla.courier.dtos.delivery_tasks.DeliveryTaskResponseDto; import com.podzilla.courier.dtos.delivery_tasks.SubmitCourierRatingResponseDto; import com.podzilla.courier.mappers.DeliveryTaskMapper; -import com.podzilla.courier.models.ConfirmationType; import com.podzilla.courier.models.DeliveryStatus; import com.podzilla.courier.models.DeliveryTask; import com.podzilla.courier.repositories.delivery_task.IDeliveryTaskRepository; @@ -17,6 +16,7 @@ import com.podzilla.courier.services.delivery_task.poll_command.StopPollingCommand; import com.podzilla.courier.services.delivery_task.poll_command.StartPollingCommand; import com.podzilla.mq.EventPublisher; +import com.podzilla.mq.events.OrderAssignedToCourierEvent.ConfirmationType; import com.podzilla.mq.events.OrderCancelledEvent; import com.podzilla.mq.events.OrderOutForDeliveryEvent; import org.slf4j.Logger; @@ -25,6 +25,7 @@ import org.springframework.data.util.Pair; import org.springframework.stereotype.Service; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -119,7 +120,8 @@ public Optional updateDeliveryTaskStatus(final String i task.getCourierId()); Command startPollingCommand = new StartPollingCommand( eventPublisher, - event + event, + deliveryTaskRepository ); startPollingCommand.execute(); @@ -233,7 +235,7 @@ public Optional confirmDelivery(final String id, final String confirmati return result; } - public SubmitCourierRatingResponseDto submitCourierRating(final String id, final Double rating) { + public SubmitCourierRatingResponseDto submitCourierRating(final String id, final BigDecimal rating) { LOGGER.info("Submitting courier rating for delivery task with ID: {}", id); Optional deliveryTask = deliveryTaskRepository.findById(id); if (deliveryTask.isPresent()) { diff --git a/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/OtpConfirmationStrategy.java b/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/OtpConfirmationStrategy.java index 5c23693..f97383c 100644 --- a/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/OtpConfirmationStrategy.java +++ b/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/OtpConfirmationStrategy.java @@ -9,7 +9,6 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import java.math.BigDecimal; import java.util.Optional; @Component @@ -35,7 +34,7 @@ public Optional confirmDelivery(final DeliveryTask task, final String co OrderDeliveredEvent event = new OrderDeliveredEvent( task.getOrderId(), task.getCourierId(), - task.getCourierRating() != null ? BigDecimal.valueOf(task.getCourierRating()) : null + task.getCourierRating() ); StopPollingCommand stopPollingCommand = new StopPollingCommand(eventPublisher, event); stopPollingCommand.execute(); diff --git a/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/QrCodeConfirmationStrategy.java b/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/QrCodeConfirmationStrategy.java index 8b3a135..5cce106 100644 --- a/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/QrCodeConfirmationStrategy.java +++ b/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/QrCodeConfirmationStrategy.java @@ -9,7 +9,6 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import java.math.BigDecimal; import java.util.Optional; @Component @@ -38,7 +37,7 @@ public Optional confirmDelivery(final DeliveryTask task, final String co OrderDeliveredEvent event = new OrderDeliveredEvent( task.getOrderId(), task.getCourierId(), - task.getCourierRating() != null ? BigDecimal.valueOf(task.getCourierRating()) : null + task.getCourierRating() ); StopPollingCommand stopPollingCommand = new StopPollingCommand(eventPublisher, event); stopPollingCommand.execute(); diff --git a/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/SignatureConfirmationStrategy.java b/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/SignatureConfirmationStrategy.java index 330fcdc..e6702a7 100644 --- a/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/SignatureConfirmationStrategy.java +++ b/src/main/java/com/podzilla/courier/services/delivery_task/confirmation_strategy/SignatureConfirmationStrategy.java @@ -9,7 +9,6 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import java.math.BigDecimal; import java.util.Optional; @Component @@ -38,7 +37,7 @@ public Optional confirmDelivery(final DeliveryTask task, final String co OrderDeliveredEvent event = new OrderDeliveredEvent( task.getOrderId(), task.getCourierId(), - task.getCourierRating() != null ? BigDecimal.valueOf(task.getCourierRating()) : null + task.getCourierRating() ); StopPollingCommand stopPollingCommand = new StopPollingCommand(eventPublisher, event); stopPollingCommand.execute(); diff --git a/src/main/java/com/podzilla/courier/services/delivery_task/poll_command/StartPollingCommand.java b/src/main/java/com/podzilla/courier/services/delivery_task/poll_command/StartPollingCommand.java index a3835c0..900bd5e 100644 --- a/src/main/java/com/podzilla/courier/services/delivery_task/poll_command/StartPollingCommand.java +++ b/src/main/java/com/podzilla/courier/services/delivery_task/poll_command/StartPollingCommand.java @@ -1,5 +1,7 @@ package com.podzilla.courier.services.delivery_task.poll_command; +import com.podzilla.courier.models.DeliveryTask; +import com.podzilla.courier.repositories.delivery_task.IDeliveryTaskRepository; import com.podzilla.mq.EventPublisher; import com.podzilla.mq.EventsConstants; import com.podzilla.mq.events.OrderOutForDeliveryEvent; @@ -8,14 +10,37 @@ public class StartPollingCommand implements Command { private final EventPublisher eventPublisher; private final OrderOutForDeliveryEvent event; + private final IDeliveryTaskRepository deliveryTaskRepository; - public StartPollingCommand(final EventPublisher eventPublisher, final OrderOutForDeliveryEvent event) { + public StartPollingCommand(final EventPublisher eventPublisher, final OrderOutForDeliveryEvent event, + final IDeliveryTaskRepository deliveryTaskRepository) { this.eventPublisher = eventPublisher; this.event = event; + this.deliveryTaskRepository = deliveryTaskRepository; } + @SuppressWarnings({"checkstyle:MagicNumber", "checkstyle:MissingSwitchDefault"}) @Override public void execute() { + DeliveryTask deliveryTask = deliveryTaskRepository.findByOrderId(event.getOrderId()) + .stream() + .findFirst() + .orElseThrow(() -> new IllegalStateException("No DeliveryTask found for orderId: " + + event.getOrderId())); + + switch (deliveryTask.getConfirmationType()) { + case OTP: + String taskId = deliveryTask.getId(); + String otp = taskId.length() >= 4 ? taskId.substring(taskId.length() - 4) : taskId; + deliveryTask.setOtp(otp); + deliveryTaskRepository.save(deliveryTask); + break; + case QR_CODE: + deliveryTask.setQrCode("qr-code " + deliveryTask.getId()); + deliveryTaskRepository.save(deliveryTask); + break; + } + // publish out_for_delivery event so that the order service start tracking courier location eventPublisher.publishEvent(EventsConstants.ORDER_OUT_FOR_DELIVERY, event); }