Kotlin Shop (eCommerce Pet Project)
This is just a pet project of mine to play with Kotlin stdlib
For this, I’m simulating an eCommerce platform as close as I can, model-wise.
I took inspiration based on my understanding of how Amazon handles Physical, Digital and Subscription Orders
fun main() {
val cart = ShoppingCart()
.add(Product("PS4 Slim 1TB", ProductType.PHYSICAL, 1899.00), 1)
.add(Product("PDP Chair", ProductType.PHYSICAL, 399.00), 2)
.add(Product("Cracking the Code Interview", ProductType.PHYSICAL_TAX_FREE, 219.57), 2)
.add(Product("The Hitchhiker's Guide to the Galaxy", ProductType.PHYSICAL_TAX_FREE, 120.00), 1)
.add(Product("Stairway to Heaven", ProductType.DIGITAL, 5.00), 1)
.add(Product("Nier:Automata", ProductType.DIGITAL, 129.90), 4)
.add(Product("Netflix Familiar Plan", ProductType.SUBSCRIPTION, 29.90), 1)
.add(Product("Spotify Premium", ProductType.SUBSCRIPTION, 14.90), 1)
.add(Product("Amazon Prime", ProductType.SUBSCRIPTION, 12.90), 1)
val account = Account("john doe", "john.doe@gmail.com", "passwd")
val orders = cart.checkout(account)
// Pick one or Iterate through the orders
val physicalOrder = orders.first { it.type == OrderType.PHYSICAL } as PhysicalOrder
val digitalOrder = orders.first { it.type == OrderType.DIGITAL } as DigitalOrder
val subscriptionOrder = orders.first { it.type == OrderType.SUBSCRIPTION } as SubscriptionOrder
val address = Address.builder
.country("Brazil")
.city("Sao Paulo")
.state("SP")
.zipCode("01000-000")
.streetAddress("Av Paulista, 1000")
.build()
val myCreditCard = CreditCard(
nameOnCard = "John Doe",
number = "123.456.789-00",
securityCode = 123,
expiresAt = YearMonth.of(2027, 7),
billingAddress = address
)
val physicalOrderInvoice = physicalOrder
.withShippingAddress(address)
.withPaymentMethod(myCreditCard)
.place()
.pay()
.invoice()
val digitalOrderInvoice = digitalOrder
.withPaymentMethod(myCreditCard)
.place()
.pay()
.invoice()
val membershipOrderInvoice = subscriptionOrder
.withPaymentMethod(myCreditCard)
.place()
.pay()
.invoice()
}
These are pretty self explanatory, right ? :)
ProductType has an enum parameter, mapping to what kind of Order that product would be in
Represents a given amount of Product in the Shopping Cart
or in an Order
Represents an interface defining the implementations for Physical, Digital and Membership Orders,
each with its own set of rules for place()
, pay()
, fulfill()
and complete()
May only contain products which the ProductType
is ‘Physical’ or ‘PHYSICAL_TAX_FREE’
place()
:
Shipping and Handling
cost of extra $10 per package PENDING
status PHYSICAL_BOOK
category, they’re grouped together into another shipment with the label TAX_FREE
pay()
:
//TODO:
Process the Payment UNSHIPPED
fulfill()
:
//TODO:
Notifies the seller to fulfill/process the Order on its endSHIPPED
complete()
:
// TODO:
: Track the packages/shipment they’re all deliveredDELIVERED
May only contain products which the ProductType
is ‘Digital’
place()
:
Voucher
discount of $10 for the OrderPENDING
status pay()
:
//TODO:
Process the Payment UNSENT
fulfill()
:
//TODO:
Notifies the seller to fulfill/process the Order on its endSENT
complete()
:
// TODO:
: Track when the the Buyer clicks on the emailed link to redeem the itemREDEEMED
May only contain products which the ProductType
is ‘Subscription’
place()
:
PENDING
status Membership
Items in the Shopping Cart,pay()
:
//TODO:
Process the Payment PENDING_ACTIVATION
fulfill()
:
//TODO:
Activates the Subscription ServiceACTIVATED
To better simulate the user experience in an e-commerce platform,
and also to wrap all the complexity of creating an Order, this Shopping Cart entity was created
add(product: Product, n: Int)
:
product
to the shopping CartupdateQuantity(product: Product, n: Int)
:
product
wih the specified n
amount.(n == 0)
, the product is deleted from the cartdelete(product: Product)
Deletes the product from the cart regardless of the quantity
subtotal()
Computes the sum of (unittest price of each product in the Cart * quantity)
checkout(account: Account)
:
Physical
(regardless if their product category will be tax-free on Shipment or not)PhysicalOrder
Digital
are grouped together to create a DigitalOrder
Membership
will create a different Membership Order