Class: KktShoppe::Order
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- KktShoppe::Order
- Extended by:
- ActiveModel::Callbacks
- Defined in:
- app/models/kkt_shoppe/order.rb,
app/models/kkt_shoppe/order/states.rb,
app/models/kkt_shoppe/order/actions.rb,
app/models/kkt_shoppe/order/billing.rb,
app/models/kkt_shoppe/order/delivery.rb
Constant Summary collapse
- STATUSES =
An array of all the available statuses for an order
['building', 'confirming', 'received', 'accepted', 'rejected', 'shipped']
Instance Attribute Summary collapse
-
#billing_address_id ⇒ Object
Some methods for setting the billing & delivery addresses.
-
#delivery_address_id ⇒ Object
Some methods for setting the billing & delivery addresses.
-
#save_addresses ⇒ Object
Some methods for setting the billing & delivery addresses.
Class Method Summary collapse
- .ransackable_associations(auth_object = nil) ⇒ Object
- .ransackable_attributes(auth_object = nil) ⇒ Object
Instance Method Summary collapse
-
#accept!(user = nil) ⇒ Object
Mark order as accepted.
-
#accepted? ⇒ Boolean
Has this order been accepted?.
-
#accepter ⇒ KktShoppe::User
The KktShoppe::User who accepted the order.
-
#available_delivery_services ⇒ Array
An array of all the delivery services which are suitable for this order in it’s current state (based on its current weight).
-
#balance ⇒ BigDecimal
The total amount due on the order.
-
#billing_country ⇒ KktShoppe::Country
The country which this order should be billed to.
-
#billing_name ⇒ String
The name for billing purposes.
-
#build_time ⇒ Float
The length of time the customer spent building the order before submitting it to us.
-
#building? ⇒ Boolean
Is this order still being built by the user?.
-
#cache_delivery_pricing ⇒ Object
Cache delivery prices for the order.
-
#cache_delivery_pricing! ⇒ Object
Cache prices and save the order.
-
#confirm! ⇒ Boolean
This method should be executed by the application when the order should be completed by the customer.
-
#confirming? ⇒ Boolean
Is this order in the user confirmation step?.
-
#courier_tracking_url ⇒ String
The URL which can be used to track the delivery of this order.
-
#customer_name ⇒ String
The name of the customer in the format of “Company (First Last)” or if they don’t have company specified, just “First Last”.
- #deliver_accepted_order_email ⇒ Object
- #deliver_received_order_email ⇒ Object
- #deliver_rejected_order_email ⇒ Object
-
#delivery_cost_price ⇒ BigDecimal
The cost of delivering this order in its current state.
-
#delivery_country ⇒ KktShoppe::Country
The country where this order is being delivered to (if one has been provided).
-
#delivery_price ⇒ BigDecimal
The price for delivering this order in its current state.
-
#delivery_required? ⇒ Boolean
Is delivery required for this order?.
-
#delivery_service ⇒ KktShoppe::DeliveryService
The recommended delivery service for this order.
-
#delivery_service_price ⇒ BigDecimal
Return the delivery price for this order in its current state.
-
#delivery_service_prices ⇒ Array
An array of all the delivery service prices which can be applied to this order.
-
#delivery_tax_amount ⇒ BigDecimal
The tax amount due for the delivery of this order in its current state.
-
#delivery_tax_rate ⇒ BigDecimal
The tax rate for the delivery of this order in its current state.
-
#empty? ⇒ Boolean
Is this order empty? (i.e. doesn’t have any items associated with it).
-
#full_name ⇒ String
The full name of the customer created by concatinting the first & last name.
-
#has_items? ⇒ Boolean
Does this order have items?.
-
#invoiced? ⇒ Boolean
Is the order invoiced?.
-
#items_sub_total ⇒ BigDecimal
The total price of all items in the basket excluding delivery.
-
#number ⇒ String
The order number.
-
#paid_in_full? ⇒ Boolean
Has this order been paid in full?.
-
#payment_outstanding? ⇒ Boolean
Is there a payment still outstanding on this order?.
-
#proceed_to_confirm(params = {}) ⇒ Boolean
This method should be called by the base application when the user has completed their first round of entering details.
-
#profit ⇒ BigDecimal
Return the price for the order.
-
#received? ⇒ Boolean
Has the order been received?.
-
#reject!(user = nil) ⇒ Object
Mark order as rejected.
-
#rejected? ⇒ Boolean
Has this order been rejected?.
-
#rejecter ⇒ KktShoppe::User
The KktShoppe::User who rejected the order.
-
#remove_delivery_service_if_invalid ⇒ Object
Remove the associated delivery service if it’s invalid.
-
#ship!(consignment_number, user = nil) ⇒ Object
Mark this order as shipped.
-
#shipped? ⇒ Boolean
Has this order been shipped?.
-
#shipper ⇒ KktShoppe::User
The user who marked the order has shipped.
-
#tax ⇒ BigDecimal
The total amount of tax due on this order.
-
#total ⇒ BigDecimal
The total of the order including tax.
-
#total_before_tax ⇒ BigDecimal
The total price of the order before tax.
-
#total_cost ⇒ BigDecimal
The total cost of the order.
-
#total_items ⇒ Integer
Return the number of items in the order?.
-
#total_weight ⇒ BigDecimal
The total weight of the order.
-
#valid_delivery_service? ⇒ Boolean
Is the currently assigned delivery service appropriate for this order?.
Instance Attribute Details
#billing_address_id ⇒ Object
Some methods for setting the billing & delivery addresses
37 38 39 |
# File 'app/models/kkt_shoppe/order.rb', line 37 def billing_address_id @billing_address_id end |
#delivery_address_id ⇒ Object
Some methods for setting the billing & delivery addresses
37 38 39 |
# File 'app/models/kkt_shoppe/order.rb', line 37 def delivery_address_id @delivery_address_id end |
#save_addresses ⇒ Object
Some methods for setting the billing & delivery addresses
37 38 39 |
# File 'app/models/kkt_shoppe/order.rb', line 37 def save_addresses @save_addresses end |
Class Method Details
.ransackable_associations(auth_object = nil) ⇒ Object
95 96 97 |
# File 'app/models/kkt_shoppe/order.rb', line 95 def self.ransackable_associations(auth_object = nil) [] end |
.ransackable_attributes(auth_object = nil) ⇒ Object
91 92 93 |
# File 'app/models/kkt_shoppe/order.rb', line 91 def self.ransackable_attributes(auth_object = nil) ["id", "billing_postcode", "billing_address1", "billing_address2", "billing_address3", "billing_address4", "first_name", "last_name", "company", "email_address", "phone_number", "consignment_number", "status", "received_at"] + _ransackers.keys end |
Instance Method Details
#accept!(user = nil) ⇒ Object
Mark order as accepted
56 57 58 59 60 61 62 63 64 65 |
# File 'app/models/kkt_shoppe/order/actions.rb', line 56 def accept!(user = nil) run_callbacks :acceptance do self.accepted_at = Time.now self.accepter = user if user self.status = 'accepted' self.save! self.order_items.each(&:accept!) deliver_accepted_order_email end end |
#accepted? ⇒ Boolean
Has this order been accepted?
56 57 58 |
# File 'app/models/kkt_shoppe/order/states.rb', line 56 def accepted? !!self.accepted_at end |
#accepter ⇒ KktShoppe::User
The KktShoppe::User who accepted the order
10 |
# File 'app/models/kkt_shoppe/order/states.rb', line 10 belongs_to :accepter, :class_name => 'KktShoppe::User', :foreign_key => 'accepted_by' |
#available_delivery_services ⇒ Array
An array of all the delivery services which are suitable for this order in it’s current state (based on its current weight)
131 132 133 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 131 def available_delivery_services delivery_service_prices.map(&:delivery_service).uniq end |
#balance ⇒ BigDecimal
The total amount due on the order
79 80 81 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 79 def balance @balance ||= total - amount_paid end |
#billing_country ⇒ KktShoppe::Country
The country which this order should be billed to
7 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 7 belongs_to :billing_country, :class_name => 'KktShoppe::Country', :foreign_key => 'billing_country_id' |
#billing_name ⇒ String
The name for billing purposes
26 27 28 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 26 def billing_name company.blank? ? full_name : "#{full_name} (#{company})" end |
#build_time ⇒ Float
The length of time the customer spent building the order before submitting it to us. The time from first item in basket to received.
50 51 52 53 |
# File 'app/models/kkt_shoppe/order.rb', line 50 def build_time return nil if self.received_at.blank? self.created_at - self.received_at end |
#building? ⇒ Boolean
Is this order still being built by the user?
35 36 37 |
# File 'app/models/kkt_shoppe/order/states.rb', line 35 def building? self.status == 'building' end |
#cache_delivery_pricing ⇒ Object
Cache delivery prices for the order
85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 85 def cache_delivery_pricing if self.delivery_service write_attribute :delivery_service_id, self.delivery_service.id write_attribute :delivery_price, self.delivery_price write_attribute :delivery_cost_price, self.delivery_cost_price write_attribute :delivery_tax_rate, self.delivery_tax_rate else write_attribute :delivery_service_id, nil write_attribute :delivery_price, nil write_attribute :delivery_cost_price, nil write_attribute :delivery_tax_rate, nil write_attribute :delivery_tax_amount, nil end end |
#cache_delivery_pricing! ⇒ Object
Cache prices and save the order
101 102 103 104 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 101 def cache_delivery_pricing! cache_delivery_pricing save! end |
#confirm! ⇒ Boolean
This method should be executed by the application when the order should be completed by the customer. It will raise exceptions if anything goes wrong or return true if the order has been confirmed successfully
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'app/models/kkt_shoppe/order/actions.rb', line 30 def confirm! no_stock_of = self.order_items.select(&:validate_stock_levels) unless no_stock_of.empty? raise KktShoppe::Errors::InsufficientStockToFulfil, :order => self, :out_of_stock_items => no_stock_of end run_callbacks :confirmation do # If we have successfully charged the card (i.e. no exception) we can go ahead and mark this # order as 'received' which means it can be accepted by staff. self.status = 'received' self.received_at = Time.now self.save! self.order_items.each(&:confirm!) # Send an email to the customer deliver_received_order_email end # We're all good. true end |
#confirming? ⇒ Boolean
Is this order in the user confirmation step?
42 43 44 |
# File 'app/models/kkt_shoppe/order/states.rb', line 42 def confirming? self.status == 'confirming' end |
#courier_tracking_url ⇒ String
The URL which can be used to track the delivery of this order
211 212 213 214 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 211 def courier_tracking_url return nil if self.shipped_at.blank? || self.consignment_number.blank? @courier_tracking_url ||= self.delivery_service.tracking_url_for(self) end |
#customer_name ⇒ String
The name of the customer in the format of “Company (First Last)” or if they don’t have company specified, just “First Last”.
59 60 61 |
# File 'app/models/kkt_shoppe/order.rb', line 59 def customer_name company.blank? ? full_name : "#{company} (#{full_name})" end |
#deliver_accepted_order_email ⇒ Object
81 82 83 |
# File 'app/models/kkt_shoppe/order/actions.rb', line 81 def deliver_accepted_order_email KktShoppe::OrderMailer.accepted(self).deliver_now end |
#deliver_received_order_email ⇒ Object
89 90 91 |
# File 'app/models/kkt_shoppe/order/actions.rb', line 89 def deliver_received_order_email KktShoppe::OrderMailer.received(self).deliver_now end |
#deliver_rejected_order_email ⇒ Object
85 86 87 |
# File 'app/models/kkt_shoppe/order/actions.rb', line 85 def deliver_rejected_order_email KktShoppe::OrderMailer.rejected(self).deliver_now end |
#delivery_cost_price ⇒ BigDecimal
The cost of delivering this order in its current state
172 173 174 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 172 def delivery_cost_price read_attribute(:delivery_cost_price) || delivery_service_price.try(:cost_price) || BigDecimal(0) end |
#delivery_country ⇒ KktShoppe::Country
The country where this order is being delivered to (if one has been provided)
12 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 12 belongs_to :delivery_country, :class_name => 'KktShoppe::Country', :foreign_key => 'delivery_country_id' |
#delivery_price ⇒ BigDecimal
The price for delivering this order in its current state
165 166 167 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 165 def delivery_price read_attribute(:delivery_price) || delivery_service_price.try(:price) || BigDecimal(0) end |
#delivery_required? ⇒ Boolean
Is delivery required for this order?
123 124 125 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 123 def delivery_required? total_weight > BigDecimal(0) end |
#delivery_service ⇒ KktShoppe::DeliveryService
The recommended delivery service for this order
7 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 7 belongs_to :delivery_service, :class_name => 'KktShoppe::DeliveryService' |
#delivery_service_price ⇒ BigDecimal
Return the delivery price for this order in its current state
158 159 160 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 158 def delivery_service_price self.delivery_service && self.delivery_service.delivery_service_prices.for_weight(self.total_weight).first end |
#delivery_service_prices ⇒ Array
An array of all the delivery service prices which can be applied to this order.
138 139 140 141 142 143 144 145 146 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 138 def delivery_service_prices if delivery_required? prices = KktShoppe::DeliveryServicePrice.joins(:delivery_service).where(:kkt_shoppe_delivery_services => {:active => true}).order(:price).for_weight(total_weight) prices = prices.select { |p| p.countries.empty? || p.country?(self.delivery_country) } prices.sort{ |x,y| (y.delivery_service.default? ? 1 : 0) <=> (x.delivery_service.default? ? 1 : 0) } # Order by truthiness else [] end end |
#delivery_tax_amount ⇒ BigDecimal
The tax amount due for the delivery of this order in its current state
179 180 181 182 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 179 def delivery_tax_amount read_attribute(:delivery_tax_amount) || delivery_price / BigDecimal(100) * delivery_tax_rate end |
#delivery_tax_rate ⇒ BigDecimal
The tax rate for the delivery of this order in its current state
187 188 189 190 191 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 187 def delivery_tax_rate read_attribute(:delivery_tax_rate) || delivery_service_price.try(:tax_rate).try(:rate_for, self) || BigDecimal(0) end |
#empty? ⇒ Boolean
Is this order empty? (i.e. doesn’t have any items associated with it)
73 74 75 |
# File 'app/models/kkt_shoppe/order.rb', line 73 def empty? order_items.empty? end |
#full_name ⇒ String
The full name of the customer created by concatinting the first & last name
66 67 68 |
# File 'app/models/kkt_shoppe/order.rb', line 66 def full_name "#{first_name} #{last_name}" end |
#has_items? ⇒ Boolean
Does this order have items?
80 81 82 |
# File 'app/models/kkt_shoppe/order.rb', line 80 def has_items? total_items > 0 end |
#invoiced? ⇒ Boolean
Is the order invoiced?
100 101 102 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 100 def invoiced? !invoice_number.blank? end |
#items_sub_total ⇒ BigDecimal
The total price of all items in the basket excluding delivery
48 49 50 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 48 def items_sub_total order_items.inject(BigDecimal(0)) { |t, i| t + i.sub_total } end |
#number ⇒ String
The order number
42 43 44 |
# File 'app/models/kkt_shoppe/order.rb', line 42 def number id ? id.to_s.rjust(6, '0') : nil end |
#paid_in_full? ⇒ Boolean
Has this order been paid in full?
93 94 95 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 93 def paid_in_full? !payment_outstanding? end |
#payment_outstanding? ⇒ Boolean
Is there a payment still outstanding on this order?
86 87 88 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 86 def payment_outstanding? balance > BigDecimal(0) end |
#proceed_to_confirm(params = {}) ⇒ Boolean
This method should be called by the base application when the user has completed their first round of entering details. This will mark the order as “confirming” which means the customer now just must confirm.
16 17 18 19 20 21 22 23 |
# File 'app/models/kkt_shoppe/order/actions.rb', line 16 def proceed_to_confirm(params = {}) self.status = 'confirming' if self.update(params) true else false end end |
#profit ⇒ BigDecimal
Return the price for the order
41 42 43 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 41 def profit total_before_tax - total_cost end |
#received? ⇒ Boolean
Has the order been received?
63 64 65 |
# File 'app/models/kkt_shoppe/order/states.rb', line 63 def received? !!self.received_at? end |
#reject!(user = nil) ⇒ Object
Mark order as rejected
70 71 72 73 74 75 76 77 78 79 |
# File 'app/models/kkt_shoppe/order/actions.rb', line 70 def reject!(user = nil) run_callbacks :rejection do self.rejected_at = Time.now self.rejecter = user if user self.status = 'rejected' self.save! self.order_items.each(&:reject!) deliver_rejected_order_email end end |
#rejected? ⇒ Boolean
Has this order been rejected?
49 50 51 |
# File 'app/models/kkt_shoppe/order/states.rb', line 49 def rejected? !!self.rejected_at end |
#rejecter ⇒ KktShoppe::User
The KktShoppe::User who rejected the order
15 |
# File 'app/models/kkt_shoppe/order/states.rb', line 15 belongs_to :rejecter, :class_name => 'KktShoppe::User', :foreign_key => 'rejected_by' |
#remove_delivery_service_if_invalid ⇒ Object
Remove the associated delivery service if it’s invalid
201 202 203 204 205 206 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 201 def remove_delivery_service_if_invalid unless self.valid_delivery_service? self.delivery_service = nil self.save end end |
#ship!(consignment_number, user = nil) ⇒ Object
Mark this order as shipped
217 218 219 220 221 222 223 224 225 226 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 217 def ship!(consignment_number, user = nil) run_callbacks :ship do self.shipped_at = Time.now self.shipper = user if user self.status = 'shipped' self.consignment_number = consignment_number self.save! KktShoppe::OrderMailer.shipped(self).deliver_now end end |
#shipped? ⇒ Boolean
Has this order been shipped?
109 110 111 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 109 def shipped? !!self.shipped_at? end |
#shipper ⇒ KktShoppe::User
The user who marked the order has shipped
17 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 17 belongs_to :shipper, :class_name => 'KktShoppe::User', :foreign_key => 'shipped_by' |
#tax ⇒ BigDecimal
The total amount of tax due on this order
62 63 64 65 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 62 def tax self.delivery_tax_amount + order_items.inject(BigDecimal(0)) { |t, i| t + i.tax_amount } end |
#total ⇒ BigDecimal
The total of the order including tax
70 71 72 73 74 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 70 def total self.delivery_price + self.delivery_tax_amount + order_items.inject(BigDecimal(0)) { |t, i| t + i.total } end |
#total_before_tax ⇒ BigDecimal
The total price of the order before tax
55 56 57 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 55 def total_before_tax self.delivery_price + self.items_sub_total end |
#total_cost ⇒ BigDecimal
The total cost of the order
33 34 35 36 |
# File 'app/models/kkt_shoppe/order/billing.rb', line 33 def total_cost self.delivery_cost_price + order_items.inject(BigDecimal(0)) { |t, i| t + i.total_cost } end |
#total_items ⇒ Integer
Return the number of items in the order?
87 88 89 |
# File 'app/models/kkt_shoppe/order.rb', line 87 def total_items order_items.inject(0) { |t,i| t + i.quantity } end |
#total_weight ⇒ BigDecimal
The total weight of the order
116 117 118 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 116 def total_weight order_items.inject(BigDecimal(0)) { |t,i| t + i.total_weight} end |
#valid_delivery_service? ⇒ Boolean
Is the currently assigned delivery service appropriate for this order?
196 197 198 |
# File 'app/models/kkt_shoppe/order/delivery.rb', line 196 def valid_delivery_service? self.delivery_service ? self.available_delivery_services.include?(self.delivery_service) : !self.delivery_required? end |