Loading page…
A single-restaurant cart, an idempotent checkout with a price snapshot, an order state machine, partner assignment with a waiting queue, and stage-based refunds.
Build the core of the food-delivery round. The data classes, the payment fake and the state table are given; you write the cart, the two strategies and the service.
Cart(customer) with restaurant_id (starts None) and qty (item_id to quantity). add(restaurant_id, item_id, n=1) accumulates, and raises CartConflict (given) if the cart already holds items from another restaurant. clear() empties it.StageRefund().refund_for(order, by_restaurant): the restaurant cancelling always refunds the full total; the customer gets the full total while the order is placed, half (rounded) while accepted, nothing once ready.NearestIdlePartner().choose(restaurant, idle): the idle partner closest to the restaurant, ties by partner_id; None if nobody is idle.FoodService(restaurants, partners, payments, assigner, refunds, delivery_fee=40):
checkout(cart, idempotency_key): the same key twice returns the same order and charges once. The restaurant must be open and the cart non-empty, and every item still available, otherwise ValueError. The order's lines copy each item's price at checkout (OrderLine(name, unit_price, qty)); its total is the lines plus the delivery fee; the payment reference comes from payments.charge(customer, total, key). Ids are O0001, O0002... The cart is cleared.accept(order_id): moves the order to accepted and assigns a partner with the assigner; with no idle partner the order waits in a FIFO queue.ready(order_id), picked_up(order_id) (InvalidTransition if no partner has the order), delivered(order_id), which frees the partner and hands them the oldest waiting order that is not cancelled.cancel(order_id, by_restaurant=False): asks the refund policy for the amount (only while placed, accepted or ready), moves to cancelled, frees the partner, calls payments.refund(payment_ref, amount) when the amount is above 0, and returns it. A second cancel raises InvalidTransition and refunds nothing.ALLOWED and appends the new status to order.history; a bad move raises InvalidTransition.JavaScript and TypeScript: camelCase (restaurantId, idempotencyKey, pickedUp, refundFor, byRestaurant, deliveryFee), new FoodService(restaurants, partners, payments, assigner, refunds, deliveryFee = 40).
Write your code, then run 10 example tests and 4 hidden tests. Each run is limited to 8 seconds: an infinite loop gets stopped and the runtime restarts, your code stays.