shipping_rules.ry
module shipping_rules
purpose: Shipping cost and delivery rules for the web shop, called from the host application.
tags: shipping, pricing, embedding
public type Destination is one of
purpose: Where the parcel goes, as the shop groups its markets.
Domestic
Europe
International
end
public type Parcel
purpose: What the host passes in when it asks for a quote.
has weight_grams: Integer where weight_grams is greater than 0
has destination: Destination
has order_total: Decimal where order_total is at least 0
can FromJson
end
public type Quote
purpose: What the host gets back for one parcel.
has cost: Decimal
has business_days: Integer
has free_shipping: Boolean
can ToJson
end
public let free_shipping_threshold: Decimal be 50.00
purpose: Domestic orders at or above this total ship free.
public function quote(parcel: Parcel) returns Quote
purpose: Price and delivery time for one parcel; the host calls this at every checkout.
example: quote(Parcel(weight_grams: 500, destination: Domestic, order_total: 60.00))
is Quote(cost: 0, business_days: 2, free_shipping: true)
example: quote(Parcel(weight_grams: 2500, destination: Europe, order_total: 20.00))
is Quote(cost: 14.50, business_days: 5, free_shipping: false)
let free be parcel.destination is Domestic
and parcel.order_total is at least free_shipping_threshold
let weight_cost be weight_steps(parcel.weight_grams).to_decimal() * 2.50
let cost be if free then 0 otherwise base_cost(parcel.destination) + weight_cost end
return Quote(cost: cost, business_days: delivery_days(parcel.destination), free_shipping: free)
end
public function weight_steps(weight_grams: Integer) returns Integer
purpose: How many started kilograms beyond the first the parcel weighs; each one adds a step.
example: weight_steps(500) is 0
example: weight_steps(1000) is 0
example: weight_steps(1001) is 1
example: weight_steps(2500) is 2
return (weight_grams - 1).quotient(1000)
end
function base_cost(destination: Destination) returns Decimal
match destination
when Domestic then return 4.90
when Europe then return 9.50
when International then return 19.90
end
end
function delivery_days(destination: Destination) returns Integer
match destination
when Domestic then return 2
when Europe then return 5
when International then return 10
end
end