11package io .k2dv .garden .fulfillment .service ;
22
3+ import io .k2dv .garden .config .AppProperties ;
34import io .k2dv .garden .fulfillment .dto .CreateFulfillmentRequest ;
45import io .k2dv .garden .fulfillment .dto .FulfillmentItemResponse ;
56import io .k2dv .garden .fulfillment .dto .FulfillmentResponse ;
67import io .k2dv .garden .fulfillment .dto .UpdateFulfillmentRequest ;
8+ import io .k2dv .garden .fulfillment .event .FulfillmentDeliveredEvent ;
9+ import io .k2dv .garden .fulfillment .event .FulfillmentShippedEvent ;
710import io .k2dv .garden .fulfillment .model .Fulfillment ;
811import io .k2dv .garden .fulfillment .model .FulfillmentItem ;
912import io .k2dv .garden .fulfillment .model .FulfillmentStatus ;
10- import io .k2dv .garden .auth .service .EmailService ;
11- import io .k2dv .garden .config .AppProperties ;
1213import io .k2dv .garden .fulfillment .repository .FulfillmentItemRepository ;
1314import io .k2dv .garden .fulfillment .repository .FulfillmentRepository ;
15+ import io .k2dv .garden .notification .model .NotificationType ;
16+ import io .k2dv .garden .notification .service .NotificationPreferenceService ;
17+ import io .k2dv .garden .order .model .Order ;
1418import io .k2dv .garden .order .model .OrderEventType ;
1519import io .k2dv .garden .order .model .OrderItem ;
1620import io .k2dv .garden .order .model .OrderStatus ;
2226import io .k2dv .garden .shared .exception .ValidationException ;
2327import io .k2dv .garden .user .model .User ;
2428import io .k2dv .garden .user .repository .UserRepository ;
25- import io .k2dv .garden .notification .model .NotificationType ;
26- import io .k2dv .garden .notification .service .NotificationPreferenceService ;
2729import io .k2dv .garden .webhook .model .WebhookEventType ;
2830import io .k2dv .garden .webhook .service .OutboundWebhookService ;
2931import lombok .RequiredArgsConstructor ;
32+ import org .springframework .context .ApplicationEventPublisher ;
3033import org .springframework .stereotype .Service ;
3134import org .springframework .transaction .annotation .Transactional ;
3235
33- import io .k2dv .garden .order .model .Order ;
34-
3536import java .util .List ;
3637import java .util .Map ;
3738import java .util .UUID ;
@@ -53,10 +54,10 @@ public class FulfillmentService {
5354 private final OrderItemRepository orderItemRepo ;
5455 private final OrderEventService orderEventService ;
5556 private final UserRepository userRepo ;
56- private final EmailService emailService ;
5757 private final AppProperties appProperties ;
5858 private final OutboundWebhookService outboundWebhookService ;
5959 private final NotificationPreferenceService notificationPreferenceService ;
60+ private final ApplicationEventPublisher eventPublisher ;
6061
6162 /**
6263 * Records a new shipment against a paid order, validating that each requested line-item quantity
@@ -157,13 +158,13 @@ public FulfillmentResponse update(UUID orderId, UUID fulfillmentId, UpdateFulfil
157158 "Fulfillment updated" , null , "admin" , null );
158159
159160 if (transitioningToShipped ) {
160- sendShippingNotificationEmail (orderId , f );
161+ publishShippedEvent (orderId , f );
161162 outboundWebhookService .scheduleDelivery (WebhookEventType .FULFILLMENT_SHIPPED ,
162163 Map .of ("orderId" , orderId .toString (), "fulfillmentId" , f .getId ().toString (),
163164 "trackingNumber" , f .getTrackingNumber () != null ? f .getTrackingNumber () : "" ));
164165 }
165166 if (transitioningToDelivered ) {
166- sendDeliveredEmail (orderId );
167+ publishDeliveredEvent (orderId );
167168 outboundWebhookService .scheduleDelivery (WebhookEventType .FULFILLMENT_DELIVERED ,
168169 Map .of ("orderId" , orderId .toString (), "fulfillmentId" , f .getId ().toString ()));
169170 }
@@ -201,34 +202,36 @@ public FulfillmentResponse getById(UUID orderId, UUID fulfillmentId) {
201202 return toResponse (f );
202203 }
203204
204- private void sendDeliveredEmail (UUID orderId ) {
205+ private void publishDeliveredEvent (UUID orderId ) {
205206 orderRepo .findById (orderId ).ifPresent (order -> {
206207 if (!notificationPreferenceService .isEnabled (order .getUserId (), NotificationType .ORDER_DELIVERED )) return ;
207- String to = order .getGuestEmail () != null ? order .getGuestEmail ()
208- : (order .getUserId () != null
209- ? userRepo .findById (order .getUserId ()).map (User ::getEmail ).orElse (null )
210- : null );
208+ String to = resolveEmail (order );
211209 if (to == null ) return ;
212210 String orderRef = "#" + orderId .toString ().substring (0 , 8 ).toUpperCase ();
213- emailService . sendOrderDelivered ( to , orderRef , null , appProperties .getFrontendUrl ());
211+ eventPublisher . publishEvent ( new FulfillmentDeliveredEvent ( to , orderRef , appProperties .getFrontendUrl () ));
214212 });
215213 }
216214
217- private void sendShippingNotificationEmail (UUID orderId , Fulfillment f ) {
215+ private void publishShippedEvent (UUID orderId , Fulfillment f ) {
218216 orderRepo .findById (orderId ).ifPresent (order -> {
219217 if (!notificationPreferenceService .isEnabled (order .getUserId (), NotificationType .ORDER_SHIPPED )) return ;
220- String to = order .getGuestEmail () != null ? order .getGuestEmail ()
221- : (order .getUserId () != null
222- ? userRepo .findById (order .getUserId ()).map (User ::getEmail ).orElse (null )
223- : null );
218+ String to = resolveEmail (order );
224219 if (to == null ) return ;
225220 String orderRef = "#" + orderId .toString ().substring (0 , 8 ).toUpperCase ();
226- emailService . sendShippingNotification ( to , orderRef ,
227- f . getTrackingNumber (), f . getTrackingCompany (), f .getTrackingUrl (),
228- appProperties .getFrontendUrl ());
221+ eventPublisher . publishEvent ( new FulfillmentShippedEvent (
222+ to , orderRef , f . getTrackingNumber (), f .getTrackingCompany (),
223+ f . getTrackingUrl (), appProperties .getFrontendUrl () ));
229224 });
230225 }
231226
227+ private String resolveEmail (Order order ) {
228+ if (order .getGuestEmail () != null ) return order .getGuestEmail ();
229+ if (order .getUserId () != null ) {
230+ return userRepo .findById (order .getUserId ()).map (User ::getEmail ).orElse (null );
231+ }
232+ return null ;
233+ }
234+
232235 private void recalculateOrderStatus (UUID orderId ) {
233236 List <OrderItem > orderItems = orderItemRepo .findByOrderId (orderId );
234237 if (orderItems .isEmpty ()) return ;
0 commit comments