308. Design an Online Shopping Application
Asked in
Design an Online Shopping Application
Design and implement an in-memory online shopping application. Customers can search for products, add products to a shopping cart, place orders, update payment statuses, and fetch their 10 most recent orders.
Product inventory and actual payment processing are not required.

Constructor

OnlineShoppingApplication(List<String> productDetails)
  • productDetails contains the complete product catalogue.
  • Each string describes one product using "productId,productName,category,priceInCents".
  • Product names and categories never contain commas.
  • Product IDs are unique, and prices are non-negative integers.
For example, "P12,Running Shoes,Footwear,6500" represents a product with ID P12, name Running Shoes, category Footwear, and price 6500 cents.

Invalid Product Rows

Ignore a product row when:
  • It does not contain exactly four comma-separated values.
  • Its product ID, product name, or category is empty.
  • Its price is not a valid non-negative integer.
  • Its product ID was already used by an earlier valid row. Keep the first valid product and ignore later duplicates.
For example, "P15,Chair,Furniture", "P16,Table,Furniture,invalid", and "P17,,Furniture,5000" are invalid rows and must be ignored.

Method Signatures

Search Products

List<String> searchProducts(String keyword)
  • Return products whose names or categories contain keyword.
  • Matching is case-insensitive.
  • Return each product using "productId,productName,category,priceInCents".
  • Return matches in their original constructor order.
  • An empty keyword matches every valid product.
  • Return an empty list when no product matches.

Add Product to Cart

List<String> addToCart(String customerId, String productId, int quantity)
  • Add the specified product and quantity to the customer's active cart.
  • Create a cart automatically when the customer adds their first product.
  • If the product is already in the cart, increase its existing quantity.
  • Return the complete updated cart.
The first returned string describes the cart using "CART,customerId,totalInCents". Each remaining string describes one cart item using "ITEM,productId,productName,quantity,unitPriceInCents,itemTotalInCents".
Cart items must be returned in the order in which their products were first added. For an invalid operation, return exactly one applicable error string and follow below priority order as to when to display which error:
  • "ERROR,EMPTY_CUSTOMER_ID"
  • "ERROR,PRODUCT_NOT_FOUND"
  • "ERROR,INVALID_QUANTITY"

Place Order

List<String> placeOrder(String customerId, String orderId)
  • Create an order from all products currently present in the customer's cart.
  • The supplied orderId must be used for the order.
  • Order IDs must be unique across all customers.
  • Copy each product's name, price, and quantity into the order.
  • Set the payment status to PENDING.
  • Set the order status to PENDING_PAYMENT.
  • Clear the cart only after the order is successfully created.
The first returned string describes the order using "ORDER,orderId,customerId,totalInCents,paymentStatus,orderStatus". Each remaining string describes one purchased item using "ITEM,productId,productName,quantity,unitPriceInCents,itemTotalInCents".
Order items must follow their cart order. If the order cannot be created, leave the cart unchanged and return exactly one applicable error string and use below priority order to return error strings:
  • "ERROR,EMPTY_CUSTOMER_ID"
  • "ERROR,EMPTY_ORDER_ID"
  • "ERROR,DUPLICATE_ORDER_ID"
  • "ERROR,EMPTY_CART"

Update Payment Status

List<String> updatePaymentStatus(String orderId, String paymentStatus)
  • paymentStatus must be PENDING, SUCCESSFUL, or FAILED.
  • Set the order status to PENDING_PAYMENT for PENDING.
  • Set the order status to CONFIRMED for SUCCESSFUL.
  • Set the order status to PAYMENT_FAILED for FAILED.
  • A failed payment may subsequently be updated to SUCCESSFUL.
  • Once payment becomes SUCCESSFUL, it cannot be changed again.
  • Return the complete updated order in the order format defined above.
If the status cannot be updated, return exactly one applicable error string. Use below priority order to decide which error string to return:
  • "ERROR,ORDER_NOT_FOUND"
  • "ERROR,UNSUPPORTED_PAYMENT_STATUS"
  • "ERROR,PAYMENT_ALREADY_SUCCESSFUL"

Fetch Recent Orders

List<String> getRecentOrders(String customerId)
  • Return at most the 10 most recently placed orders of the customer.
  • If the customer has fewer than 10 orders, return all their orders.
  • Return the most recent order first.
  • Represent each order using "ORDER,orderId,customerId,totalInCents,paymentStatus,orderStatus".
  • The returned summaries must reflect the latest payment and order statuses.
  • Return an empty list if customerId is empty, the customer does not exist, or the customer has not placed any orders.

Constraints

  • 1 ≤ productDetails.size() ≤ 10,000
  • Every valid product row contains exactly four comma-separated values.
  • 1 ≤ productId.length(), productName.length(), category.length() ≤ 100
  • customerId, orderId, Product names and categories never contain commas.
  • Valid product IDs are unique and never contain commas.
  • 0 ≤ priceInCents ≤ 1,000,000,000
  • 0 ≤ keyword.length() ≤ 100
  • 0 ≤ customerId.length(), orderId.length() ≤ 100
  • 1 ≤ quantity ≤ 1,000,000 for valid quantities.
  • Every cart and order total fits in a signed 64-bit integer.
  • All information is stored in memory.
  • No parameter passed to the constructor or any method will be null.
  • The constructor and methods must never throw exceptions.

Examples

Example 1: Invalid Products, Search, and Cart

new OnlineShoppingApplication(productDetails = List.of("P10,Smart Watch,Wearables,12500", "BROKEN,Only Two Fields", "P20,Noise Cancelling Earbuds,Audio,7500", "P10,Duplicate Watch,Wearables,9999", "P30,Coffee Mug,Kitchen,invalid", "P40,Coffee Mug,Kitchen,1200"))
The malformed row, duplicate P10, and invalid P30 row are ignored. Products P10, P20, and P40 are stored.
searchProducts(keyword = "audio")
Output: ["P20,Noise Cancelling Earbuds,Audio,7500"]
addToCart(customerId = "C7", productId = "P20", quantity = 2)
Output: ["CART,C7,15000", "ITEM,P20,Noise Cancelling Earbuds,2,7500,15000"]
addToCart(customerId = "C7", productId = "P40", quantity = 1)
Output: ["CART,C7,16200", "ITEM,P20,Noise Cancelling Earbuds,2,7500,15000", "ITEM,P40,Coffee Mug,1,1200,1200"]

Example 2: Orders and Payment Status

Continuing with the cart from Example 1:
placeOrder(customerId = "C7", orderId = "O700")
Output: ["ORDER,O700,C7,16200,PENDING,PENDING_PAYMENT", "ITEM,P20,Noise Cancelling Earbuds,2,7500,15000", "ITEM,P40,Coffee Mug,1,1200,1200"]
updatePaymentStatus(orderId = "O700", paymentStatus = "SUCCESSFUL")
Output: ["ORDER,O700,C7,16200,SUCCESSFUL,CONFIRMED", "ITEM,P20,Noise Cancelling Earbuds,2,7500,15000", "ITEM,P40,Coffee Mug,1,1200,1200"]
addToCart(customerId = "C7", productId = "P10", quantity = 1)
Output: ["CART,C7,12500", "ITEM,P10,Smart Watch,1,12500,12500"]
placeOrder(customerId = "C7", orderId = "O701")
Output: ["ORDER,O701,C7,12500,PENDING,PENDING_PAYMENT", "ITEM,P10,Smart Watch,1,12500,12500"]

Example 3: Fetching Recent Orders

getRecentOrders(customerId = "C7")
Output: ["ORDER,O701,C7,12500,PENDING,PENDING_PAYMENT", "ORDER,O700,C7,16200,SUCCESSFUL,CONFIRMED"]
Customer C7 has only two orders, so both are returned with the most recent order first.


Please use Laptop/Desktop or any other large screen to add/edit code.