Skip to content
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
package com.shipping.freightops.controller;

import com.itextpdf.text.DocumentException;
import com.shipping.freightops.dto.CreateFreightOrderRequest;
import com.shipping.freightops.dto.FreightOrderResponse;
import com.shipping.freightops.dto.PageResponse;
import com.shipping.freightops.dto.UpdateDiscountRequest;
import com.shipping.freightops.dto.*;
import com.shipping.freightops.entity.FreightOrder;
import com.shipping.freightops.entity.TrackingEvent;
import com.shipping.freightops.repository.FreightOrderRepository;
import com.shipping.freightops.service.FreightOrderService;
import com.shipping.freightops.service.InvoiceService;
import com.shipping.freightops.service.TrackingEventService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import jakarta.validation.Valid;
import java.io.FileNotFoundException;
import java.net.URI;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;

/**
Expand All @@ -32,10 +35,18 @@ public class FreightOrderController {

private final FreightOrderService service;
private final InvoiceService invoiceService;
private final FreightOrderRepository freightOrderRepository;
private final TrackingEventService trackingEventService;

public FreightOrderController(FreightOrderService service, InvoiceService invoiceService) {
public FreightOrderController(
FreightOrderService service,
InvoiceService invoiceService,
FreightOrderRepository freightOrderRepository,
TrackingEventService trackingEventService) {
this.service = service;
this.invoiceService = invoiceService;
this.freightOrderRepository = freightOrderRepository;
this.trackingEventService = trackingEventService;
}

/** Create a new freight order. */
Expand Down Expand Up @@ -108,4 +119,32 @@ public ResponseEntity<FreightOrderResponse> updateDiscount(
FreightOrder order = service.updateDiscount(id, request);
return ResponseEntity.ok(FreightOrderResponse.fromEntity(order));
}

@PostMapping("/{id}/events")
public ResponseEntity<TrackingEvent> createEvent(
@Valid @RequestBody TrackingEventRequest eventRequest, @PathVariable Long id, Errors errors) {
if (errors.hasErrors()) {
throw new IllegalArgumentException("invalid data");
}
TrackingEvent event = new TrackingEvent();
FreightOrder order =
freightOrderRepository
.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Order not found"));
event.setFreightOrder(order);
event.setDescription(eventRequest.getDescription());
event.setEventTime(LocalDateTime.now());
event.setEventType(eventRequest.getEventType());
event.setLocation(eventRequest.getLocation());
event.setDescription(eventRequest.getDescription());
event.setPerformedBy(eventRequest.getPerformedBy());
TrackingEvent savedEvent = trackingEventService.createEvent(event);
return ResponseEntity.ok().body(savedEvent);
}

@GetMapping("/{id}/events")
public ResponseEntity<List<TrackingEvent>> getAllEvents(@PathVariable Long id) {
List<TrackingEvent> events = trackingEventService.getAllEventsByOrderId(id);
return ResponseEntity.ok().body(events);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.shipping.freightops.dto;

import com.shipping.freightops.entity.FreightOrder;
import com.shipping.freightops.entity.TrackingEvent;
import com.shipping.freightops.enums.ContainerSize;
import com.shipping.freightops.enums.ContainerType;
import com.shipping.freightops.enums.OrderStatus;
import com.shipping.freightops.enums.VoyageStatus;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class OrderTrackingResponse {
private Long orderId;
Expand All @@ -20,6 +23,7 @@ public class OrderTrackingResponse {
private LocalDateTime departureTime;
private LocalDateTime estimatedArrival;
private VoyageStatus voyageStatus;
private List<TrackingEvent> events = new ArrayList<>();

public static OrderTrackingResponse fromEntity(FreightOrder order) {
OrderTrackingResponse dto = new OrderTrackingResponse();
Expand All @@ -28,6 +32,7 @@ public static OrderTrackingResponse fromEntity(FreightOrder order) {
dto.ContainerCode = order.getContainer().getContainerCode();
dto.containerSize = order.getContainer().getSize();
dto.containerType = order.getContainer().getType();
dto.events = order.getEvents();
if (order.getVoyage() != null) {
dto.voyageNumber = order.getVoyage().getVoyageNumber();
dto.vesselName = order.getVoyage().getVessel().getName();
Expand All @@ -40,6 +45,14 @@ public static OrderTrackingResponse fromEntity(FreightOrder order) {
return dto;
}

public void setEvents(List<TrackingEvent> events) {
this.events = events;
}

public List<TrackingEvent> getEvents() {
return events;
}

public String getVoyageNumber() {
return voyageNumber;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.shipping.freightops.dto;

import com.shipping.freightops.enums.EventType;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

public class TrackingEventRequest {
@NotNull private EventType eventType;

@NotBlank(message = "description is required")
private String description;

private String location;
private String performedBy;

public TrackingEventRequest() {}

public TrackingEventRequest(
EventType eventType, String description, String location, String performedBy) {
this.eventType = eventType;
this.description = description;
this.location = location;
this.performedBy = performedBy;
}

public EventType getEventType() {
return eventType;
}

public void setEventType(EventType eventType) {
this.eventType = eventType;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public String getLocation() {
return location;
}

public void setLocation(String location) {
this.location = location;
}

public String getPerformedBy() {
return performedBy;
}

public void setPerformedBy(String performedBy) {
this.performedBy = performedBy;
}
}
40 changes: 23 additions & 17 deletions src/main/java/com/shipping/freightops/entity/FreightOrder.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package com.shipping.freightops.entity;

import com.shipping.freightops.enums.OrderStatus;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/** A freight booking made by the internal ops team, assigning a container to a voyage. */
@Entity
Expand Down Expand Up @@ -43,13 +38,8 @@ public class FreightOrder extends BaseEntity {
@Column(nullable = false)
private String orderedBy;

public String getOrderedBy() {
return orderedBy;
}

public void setOrderedBy(String orderedBy) {
this.orderedBy = orderedBy;
}
@OneToMany(mappedBy = "freightOrder", cascade = CascadeType.ALL)
private List<TrackingEvent> events = new ArrayList<>();

@Column(length = 500)
private String notes;
Expand Down Expand Up @@ -78,6 +68,24 @@ public void setOrderedBy(String orderedBy) {
@Column(nullable = true, length = 500)
private String discountReason;

public FreightOrder() {}

public void setEvents(List<TrackingEvent> events) {
this.events = events;
}

public List<TrackingEvent> getEvents() {
return events;
}

public String getOrderedBy() {
return orderedBy;
}

public void setOrderedBy(String orderedBy) {
this.orderedBy = orderedBy;
}

public Customer getCustomer() {
return customer;
}
Expand All @@ -86,8 +94,6 @@ public void setCustomer(Customer customer) {
this.customer = customer;
}

public FreightOrder() {}

public Voyage getVoyage() {
return voyage;
}
Expand Down
90 changes: 90 additions & 0 deletions src/main/java/com/shipping/freightops/entity/TrackingEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.shipping.freightops.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.shipping.freightops.enums.EventType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.ManyToOne;
import jakarta.validation.constraints.NotBlank;
import java.time.LocalDateTime;

@Entity
public class TrackingEvent extends BaseEntity {
@ManyToOne(optional = false)
@JsonIgnore
private FreightOrder freightOrder;

private EventType eventType;

@Column(nullable = false)
@NotBlank(message = "description is required")
private String description;

private String location;
private String performedBy;
private LocalDateTime eventTime;

public TrackingEvent() {}

public TrackingEvent(
FreightOrder freightOrder,
EventType eventType,
String description,
String location,
String performedBy,
LocalDateTime eventTime) {
this.freightOrder = freightOrder;
this.description = description;
this.location = location;
this.performedBy = performedBy;
this.eventTime = eventTime;
}

public FreightOrder getFreightOrder() {
return freightOrder;
}

public void setFreightOrder(FreightOrder freightOrder) {
this.freightOrder = freightOrder;
}

public EventType getEventType() {
return eventType;
}

public void setEventType(EventType eventType) {
this.eventType = eventType;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public String getLocation() {
return location;
}

public void setLocation(String location) {
this.location = location;
}

public String getPerformedBy() {
return performedBy;
}

public void setPerformedBy(String performedBy) {
this.performedBy = performedBy;
}

public LocalDateTime getEventTime() {
return eventTime;
}

public void setEventTime(LocalDateTime eventTime) {
this.eventTime = eventTime;
}
}
11 changes: 11 additions & 0 deletions src/main/java/com/shipping/freightops/enums/EventType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.shipping.freightops.enums;

public enum EventType {
STATUS_CHANGE,
GATE_IN,
GATE_OUT,
LOADED,
DISCHARGED,
CUSTOMS_CLEARED,
NOTE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.shipping.freightops.repository;

import com.shipping.freightops.entity.TrackingEvent;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;

public interface TrackingEventRepository extends JpaRepository<TrackingEvent, Long> {
List<TrackingEvent> findAllByFreightOrder_IdOrderByCreatedAtAsc(Long id);
}
Loading
Loading