Amazon Locker Service: Java Implementation with Locker Locations, Access Codes, and Pickup Handling

The Amazon Locker Service Java implementation consists of several classes to model the functionality of an Amazon Locker service, offering customers a secure and convenient way to pick up and return their orders. Below is a one-line explanation of each class:

  1. Order Class:
    • Represents an order with an order ID and package size.
  2. LockerLocation Class:
    • Represents a physical location with lockers, providing details such as the location ID, address, maximum locker size, opening and closing times, and a list of lockers.
  3. AmazonLocker Class:
    • Models an individual locker within a specific location, tracking its ID, location, access code, package availability status, and delivery date. It handles package delivery, pickup, and closure.
  4. AmazonLockerService Class:
    • Manages locker locations, initializes them, and assigns lockers to orders based on size and location. It also provides a method for customers to pick up their packages, verifying access codes and handling expiration logic.
import java.util.*;

class Order {
    private int orderId;
    private LockerSize packageSize;

    public Order(int orderId, LockerSize packageSize) {
        this.orderId = orderId;
        this.packageSize = packageSize;
    }

    public int getOrderId() {
        return orderId;
    }

    public LockerSize getPackageSize() {
        return packageSize;
    }
}

class LockerLocation {
    private String locationId;
    private String address;
    private LockerSize maxSize;
    private int openingTime;
    private int closingTime;
    private boolean isOpen;
    private List<AmazonLocker> lockers;

    public LockerLocation(String locationId, String address, LockerSize maxSize, int openingTime, int closingTime, boolean isOpen) {
        this.locationId = locationId;
        this.address = address;
        this.maxSize = maxSize;
        this.openingTime = openingTime;
        this.closingTime = closingTime;
        this.isOpen = isOpen;
        this.lockers = new ArrayList<>();
        initializeLockers();
    }

    private void initializeLockers() {
        // Initialize lockers at this location
        for (int i = 1; i <= 10; i++) {
            lockers.add(new AmazonLocker("L" + locationId + "_Locker" + i, this));
        }
    }

    public String getLocationId() {
        return locationId;
    }

    public String getAddress() {
        return address;
    }

    public LockerSize getMaxSize() {
        return maxSize;
    }

    public int getOpeningTime() {
        return openingTime;
    }

    public int getClosingTime() {
        return closingTime;
    }

    public boolean isOpen() {
        return isOpen;
    }

    public List<AmazonLocker> getLockers() {
        return lockers;
    }
}

class AmazonLocker {
    private String lockerId;
    private LockerLocation location;
    private String accessCode;
    private boolean isPackageAvailable;
    private Date deliveryDate;

    public AmazonLocker(String lockerId, LockerLocation location) {
        this.lockerId = lockerId;
        this.location = location;
        this.isPackageAvailable = false;
    }

    public String getLockerId() {
        return lockerId;
    }

    public LockerLocation getLocation() {
        return location;
    }

    public boolean isPackageAvailable() {
        return isPackageAvailable;
    }

    public void deliverPackage(Order order) {
        if (order.getPackageSize().ordinal() <= location.getMaxSize().ordinal()) {
            this.isPackageAvailable = true;
            this.deliveryDate = new Date();
            generateAndSendAccessCode();
        } else {
            System.out.println("Package size exceeds locker size.");
        }
    }

    private void generateAndSendAccessCode() {
        // Generate and send a 6-digit access code to the customer
        Random rand = new Random();
        this.accessCode = String.format("%06d", rand.nextInt(1000000));
        System.out.println("Access code: " + accessCode);
    }

    public void pickupPackage(String enteredAccessCode) {
        if (isPackageAvailable && location.isOpen() && isWithinThreeDays() && enteredAccessCode.equals(accessCode)) {
            closeLocker();
        } else {
            System.out.println("Invalid pickup conditions or incorrect access code.");
        }
    }

    private boolean isWithinThreeDays() {
        // Check if the package is within the three-day pickup window
        Date currentDate = new Date();
        long differenceInMilliseconds = currentDate.getTime() - deliveryDate.getTime();
        long differenceInDays = differenceInMilliseconds / (24 * 60 * 60 * 1000);
        return differenceInDays <= 3;
    }

    private void closeLocker() {
        this.isPackageAvailable = false;
        System.out.println("Locker closed after successful pickup.");
    }
}

class AmazonLockerService {
    private List<LockerLocation> lockerLocations;

    public AmazonLockerService() {
        this.lockerLocations = new ArrayList<>();
        initializeLockerLocations();
    }

    private void initializeLockerLocations() {
        // Initialize locker locations
        lockerLocations.add(new LockerLocation("L1", "123 Main St", LockerSize.LARGE, 9, 18, true));
        // Add more locker locations as needed
    }

    public List<LockerLocation> getLockerLocations() {
        return lockerLocations;
    }

    public AmazonLocker assignLockerToLocation(Order order, LockerLocation location) {
        // Find an available locker of appropriate size at the specified location
        for (AmazonLocker locker : location.getLockers()) {
            if (!locker.isPackageAvailable() && order.getPackageSize().ordinal() <= location.getMaxSize().ordinal()) {
                locker.deliverPackage(order);
                return locker;
            }
        }
        return null; // No available locker found
    }

    public static void main(String[] args) {
        AmazonLockerService lockerService = new AmazonLockerService();

        // Example: Place an order and assign a locker
        Order order = new Order(1, LockerSize.MEDIUM);
        LockerLocation selectedLocation = lockerService.getLockerLocations().get(0); // Select the first location for simplicity
        AmazonLocker assignedLocker = lockerService.assignLockerToLocation(order, selectedLocation);

        // Example: Pickup the package
        if (assignedLocker != null) {
            // Simulating the customer entering the access code during pickup
            assignedLocker.pickupPackage("123456"); // Replace "123456" with the actual access code
        }
    }
}

Return package

The sequence diagram for the package return should have the following actors and objects that will interact with each other:

  • Actor: Customer
  • Object: Locker
  • System

Here are the steps in the return package interaction:

  1. The customer requests the system to return a package.
  2. If the package return request is approved:
    1. The system requests an available locker.
    2. The locker is returned to the system.
    3. The system sends an OTP code to the customer.
    4. The customer verifies their code.
    5. If verification is successful:
      1. The system assigns a locker to the customer.
      2. The customer places their package in the locker.
    6. Else:
      1. The customer receives an error message.
  3. Else, if the package return request is not approved:
    1. The customer is informed that the return request is not approved.
Customer System Locker sd return package requestReturn(package) requestLocker() return locker send OTP code verifyOTP(code) assign locker place package error return not approved alt [request approved] [request unapproved] alt [verification successful] [verification failed]

You may also like...