Class: Shoppe::Order
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Shoppe::Order
- Defined in:
- app/models/shoppe/order.rb
Constant Summary collapse
- STATUSES =
An array of all the available statuses for an order
['building', 'confirming', 'received', 'accepted', 'rejected', 'shipped']
Class Method Summary collapse
-
.ransackable_associations(auth_object = nil) ⇒ Object
Specify which associations can be searched.
-
.ransackable_attributes(auth_object = nil) ⇒ Object
Specify which attributes can be searched.
Instance Method Summary collapse
-
#accept!(user) ⇒ Object
This method will accept the this order.
-
#accepted? ⇒ Boolean
Has this order been accepted?.
-
#available_delivery_services ⇒ Object
An array of all the delivery services which are suitable for this order in it’s current state (based on its current weight).
-
#build_time ⇒ Object
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?.
-
#confirm! ⇒ Object
This method will confirm the order If there are any issues with the order an exception should be raised.
-
#confirming? ⇒ Boolean
Is this order in the user confirmation step?.
-
#courier_tracking_url ⇒ Object
The URL which can be used to track the delivery of this order.
-
#customer_name ⇒ Object
The name of the customer.
-
#delivery_cost_price ⇒ Object
The cost of delivering this order in its current state.
-
#delivery_price ⇒ Object
The price for delivering this order in its current state.
-
#delivery_service ⇒ Object
The recommended delivery service for this order.
-
#delivery_service_price ⇒ Object
Return the delivery price for this order in its current state.
-
#delivery_service_prices ⇒ Object
An array of all the delivery service prices which can be applied to this order.
-
#delivery_tax_amount ⇒ Object
The tax amount due for the delivery of this order in its current state.
-
#delivery_tax_rate ⇒ Object
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).
-
#has_items? ⇒ Boolean
Does this order have items?.
-
#number ⇒ Object
The order number.
-
#paid? ⇒ Boolean
Has this order been fully paid for?.
-
#pay!(reference, method) ⇒ Object
This method will mark an order as paid.
-
#proceed_to_confirm(params = {}) ⇒ Object
This method is called by the customer when they submit their details in the first step of the checkout process.
-
#profit ⇒ Object
Return the price for the order.
-
#received? ⇒ Boolean
Has the order been received?.
-
#reject!(user) ⇒ Object
This method will reject the order.
-
#rejected? ⇒ Boolean
Has this order been rejected?.
-
#remove_delivery_service_if_invalid ⇒ Object
Remove the associated delivery service if it’s invalid.
-
#ship!(user, consignment_number) ⇒ Object
This method will mark an order as shipped and store the given consignment number with the order for use later in tracking.
-
#shipped? ⇒ Boolean
Has this order been shipped?.
-
#tax ⇒ Object
The total amount of tax due on this order.
-
#total ⇒ Object
The total of the order including tax.
-
#total_before_tax ⇒ Object
The total price of the order before tax.
-
#total_cost ⇒ Object
The total cost of the order.
-
#total_in_pence ⇒ Object
The total of the order including tax in pence.
-
#total_items ⇒ Object
Return the number of items in the order?.
-
#total_weight ⇒ Object
The total weight of the order.
-
#valid_delivery_service? ⇒ Boolean
Is the currently assigned delivery service appropriate for this order?.
Class Method Details
.ransackable_associations(auth_object = nil) ⇒ Object
Specify which associations can be searched
338 339 340 |
# File 'app/models/shoppe/order.rb', line 338 def self.ransackable_associations(auth_object = nil) ['products'] end |
.ransackable_attributes(auth_object = nil) ⇒ Object
Specify which attributes can be searched
333 334 335 |
# File 'app/models/shoppe/order.rb', line 333 def self.ransackable_attributes(auth_object = nil) ["id", "postcode", "address1", "address2", "address3", "address4", "first_name", "last_name", "company", "email_address", "phone_number", "consignment_number", "status", "received_at"] + _ransackers.keys end |
Instance Method Details
#accept!(user) ⇒ Object
This method will accept the this order. It is called by a user (which is the only parameter).
298 299 300 301 302 303 304 305 306 |
# File 'app/models/shoppe/order.rb', line 298 def accept!(user) run_callbacks :acceptance do self.accepted_at = Time.now self.accepted_by = user.id self.status = 'accepted' self.save! Shoppe::OrderMailer.accepted(self).deliver end end |
#accepted? ⇒ Boolean
Has this order been accepted?
66 67 68 |
# File 'app/models/shoppe/order.rb', line 66 def accepted? !!self.accepted_at end |
#available_delivery_services ⇒ Object
An array of all the delivery services which are suitable for this order in it’s current state (based on its current weight)
161 162 163 164 165 |
# File 'app/models/shoppe/order.rb', line 161 def available_delivery_services @available_delivery_services ||= begin delivery_service_prices.map(&:delivery_service).uniq end end |
#build_time ⇒ Object
The length of time the customer spent building the order before submitting it to us. The time from first item in basket to received.
87 88 89 90 |
# File 'app/models/shoppe/order.rb', line 87 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?
51 52 53 |
# File 'app/models/shoppe/order.rb', line 51 def building? self.status == 'building' end |
#confirm! ⇒ Object
This method will confirm the order If there are any issues with the order an exception should be raised.
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'app/models/shoppe/order.rb', line 244 def confirm! # Ensure that we have the stock to fulfil this order at the current time. We may have had it when # it was placed int he basket and if we don't now, we should let the user know so they can # rethink. no_stock_of = self.order_items.select(&:validate_stock_levels) unless no_stock_of.empty? raise Shoppe::Errors::InsufficientStockToFulfil, :order => self, :out_of_stock_items => no_stock_of end # Ensure that before we confirm the order that the delivery service which has been selected # is appropritae for the contents of the order. unless self.valid_delivery_service? raise Shoppe::Errors::InappropriateDeliveryService, :order => self end # Store the delivery prices with the order 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_amount, self.delivery_tax_amount write_attribute :delivery_tax_rate, self.delivery_tax_rate 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 Shoppe::OrderMailer.received(self).deliver end # We're all good. true end |
#confirming? ⇒ Boolean
Is this order in the user confirmation step?
56 57 58 |
# File 'app/models/shoppe/order.rb', line 56 def confirming? self.status == 'confirming' end |
#courier_tracking_url ⇒ Object
The URL which can be used to track the delivery of this order
219 220 221 222 |
# File 'app/models/shoppe/order.rb', line 219 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.consignment_number) end |
#customer_name ⇒ Object
The name of the customer
93 94 95 |
# File 'app/models/shoppe/order.rb', line 93 def customer_name company.blank? ? "#{first_name} #{last_name}" : "#{company} (#{first_name} #{last_name})" end |
#delivery_cost_price ⇒ Object
The cost of delivering this order in its current state
183 184 185 |
# File 'app/models/shoppe/order.rb', line 183 def delivery_cost_price @delivery_cost_price ||= read_attribute(:delivery_cost_price) || delivery_service_price.try(:cost_price) || 0.0 end |
#delivery_price ⇒ Object
The price for delivering this order in its current state
178 179 180 |
# File 'app/models/shoppe/order.rb', line 178 def delivery_price @delivery_price ||= read_attribute(:delivery_price) || delivery_service_price.try(:price) || 0.0 end |
#delivery_service ⇒ Object
The recommended delivery service for this order
168 169 170 |
# File 'app/models/shoppe/order.rb', line 168 def delivery_service super || available_delivery_services.first end |
#delivery_service_price ⇒ Object
Return the delivery price for this order in its current state
173 174 175 |
# File 'app/models/shoppe/order.rb', line 173 def delivery_service_price @delivery_service_price ||= self.delivery_service && self.delivery_service.delivery_service_prices.for_weight(self.total_weight).first end |
#delivery_service_prices ⇒ Object
An array of all the delivery service prices which can be applied to this order.
153 154 155 156 157 |
# File 'app/models/shoppe/order.rb', line 153 def delivery_service_prices @delivery_service_prices ||= begin Shoppe::DeliveryServicePrice.joins(:delivery_service).where(:shoppe_delivery_services => {:active => true}).order("`default` desc, price asc").for_weight(total_weight) end end |
#delivery_tax_amount ⇒ Object
The tax amount due for the delivery of this order in its current state
188 189 190 191 192 193 194 |
# File 'app/models/shoppe/order.rb', line 188 def delivery_tax_amount @delivery_tax_amount ||= begin read_attribute(:delivery_tax_amount) || (delivery_service_price ? delivery_price / BigDecimal(100) * delivery_service_price.tax_rate : 0.0) || 0.0 end end |
#delivery_tax_rate ⇒ Object
The tax rate for the delivery of this order in its current state
197 198 199 200 201 202 203 |
# File 'app/models/shoppe/order.rb', line 197 def delivery_tax_rate @delivery_tax_rate ||= begin read_attribute(:delivery_tax_rate) || delivery_service_price.try(:tax_rate) || 0.0 end end |
#empty? ⇒ Boolean
Is this order empty? (i.e. doesn’t have any items associated with it)
98 99 100 |
# File 'app/models/shoppe/order.rb', line 98 def empty? order_items.empty? end |
#has_items? ⇒ Boolean
Does this order have items?
103 104 105 |
# File 'app/models/shoppe/order.rb', line 103 def has_items? total_items > 0 end |
#number ⇒ Object
The order number
81 82 83 |
# File 'app/models/shoppe/order.rb', line 81 def number id.to_s.rjust(6, '0') end |
#paid? ⇒ Boolean
Has this order been fully paid for?
225 226 227 |
# File 'app/models/shoppe/order.rb', line 225 def paid? !paid_at.blank? end |
#pay!(reference, method) ⇒ Object
This method will mark an order as paid.
287 288 289 290 291 292 293 294 |
# File 'app/models/shoppe/order.rb', line 287 def pay!(reference, method) run_callbacks :payment do self.paid_at = Time.now.utc self.payment_reference = reference self.payment_method = method self.save! end end |
#proceed_to_confirm(params = {}) ⇒ Object
This method is called by the customer when they submit their details in the first step of the checkout process. It will update the status to ‘confirmed’ as well as updating their details. Any issues with validation will cause false to be returned otherwise true. Any more serious issues will be raised as exceptions.
233 234 235 236 237 238 239 240 |
# File 'app/models/shoppe/order.rb', line 233 def proceed_to_confirm(params = {}) self.status = 'confirming' if self.update(params) true else false end end |
#profit ⇒ Object
Return the price for the order
119 120 121 |
# File 'app/models/shoppe/order.rb', line 119 def profit total_before_tax - total_cost end |
#received? ⇒ Boolean
Has the order been received?
76 77 78 |
# File 'app/models/shoppe/order.rb', line 76 def received? !!self.received_at? end |
#reject!(user) ⇒ Object
This method will reject the order. It is called by a user (which is the only parameter).
309 310 311 312 313 314 315 316 317 |
# File 'app/models/shoppe/order.rb', line 309 def reject!(user) run_callbacks :rejection do self.rejected_at = Time.now self.rejected_by = user.id self.status = 'rejected' self.save! Shoppe::OrderMailer.rejected(self).deliver end end |
#rejected? ⇒ Boolean
Has this order been rejected?
61 62 63 |
# File 'app/models/shoppe/order.rb', line 61 def rejected? !!self.rejected_at end |
#remove_delivery_service_if_invalid ⇒ Object
Remove the associated delivery service if it’s invalid
211 212 213 214 215 216 |
# File 'app/models/shoppe/order.rb', line 211 def remove_delivery_service_if_invalid unless self.valid_delivery_service? self.delivery_service = nil self.save end end |
#ship!(user, consignment_number) ⇒ Object
This method will mark an order as shipped and store the given consignment number with the order for use later in tracking.
321 322 323 324 325 326 327 328 329 330 |
# File 'app/models/shoppe/order.rb', line 321 def ship!(user, consignment_number) run_callbacks :ship do self.shipped_at = Time.now self.shipped_by = user.id self.status = 'shipped' self.consignment_number = consignment_number self.save! Shoppe::OrderMailer.shipped(self).deliver end end |
#shipped? ⇒ Boolean
Has this order been shipped?
71 72 73 |
# File 'app/models/shoppe/order.rb', line 71 def shipped? !!self.shipped_at? end |
#tax ⇒ Object
The total amount of tax due on this order
130 131 132 133 |
# File 'app/models/shoppe/order.rb', line 130 def tax self.delivery_tax_amount + order_items.inject(BigDecimal(0)) { |t, i| t + i.tax_amount } end |
#total ⇒ Object
The total of the order including tax
136 137 138 139 140 |
# File 'app/models/shoppe/order.rb', line 136 def total self.delivery_price + self.delivery_tax_amount + order_items.inject(BigDecimal(0)) { |t, i| t + i.total } end |
#total_before_tax ⇒ Object
The total price of the order before tax
124 125 126 127 |
# File 'app/models/shoppe/order.rb', line 124 def total_before_tax self.delivery_price + order_items.inject(BigDecimal(0)) { |t, i| t + i.sub_total } end |
#total_cost ⇒ Object
The total cost of the order
113 114 115 116 |
# File 'app/models/shoppe/order.rb', line 113 def total_cost self.delivery_cost_price + order_items.inject(BigDecimal(0)) { |t, i| t + i.total_cost } end |
#total_in_pence ⇒ Object
The total of the order including tax in pence
143 144 145 |
# File 'app/models/shoppe/order.rb', line 143 def total_in_pence (total * BigDecimal(100)).to_i end |
#total_items ⇒ Object
Return the number of items in the order?
108 109 110 |
# File 'app/models/shoppe/order.rb', line 108 def total_items @total_items ||= order_items.inject(0) { |t,i| t + i.quantity } end |
#total_weight ⇒ Object
The total weight of the order
148 149 150 |
# File 'app/models/shoppe/order.rb', line 148 def total_weight order_items.inject(BigDecimal(0)) { |t,i| t + i.weight} end |
#valid_delivery_service? ⇒ Boolean
Is the currently assigned delivery service appropriate for this order?
206 207 208 |
# File 'app/models/shoppe/order.rb', line 206 def valid_delivery_service? self.delivery_service && self.available_delivery_services.include?(self.delivery_service) end |