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
341 342 343 |
# File 'app/models/shoppe/order.rb', line 341 def self.ransackable_associations(auth_object = nil) ['products'] end |
.ransackable_attributes(auth_object = nil) ⇒ Object
Specify which attributes can be searched
336 337 338 |
# File 'app/models/shoppe/order.rb', line 336 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).
299 300 301 302 303 304 305 306 307 308 |
# File 'app/models/shoppe/order.rb', line 299 def accept!(user) run_callbacks :acceptance do self.accepted_at = Time.now self.accepted_by = user.id self.status = 'accepted' self.save! self.order_items.each(&:accept!) Shoppe::OrderMailer.accepted(self).deliver end end |
#accepted? ⇒ Boolean
Has this order been accepted?
67 68 69 |
# File 'app/models/shoppe/order.rb', line 67 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)
162 163 164 165 166 |
# File 'app/models/shoppe/order.rb', line 162 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.
88 89 90 91 |
# File 'app/models/shoppe/order.rb', line 88 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?
52 53 54 |
# File 'app/models/shoppe/order.rb', line 52 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.
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 285 |
# File 'app/models/shoppe/order.rb', line 245 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?
57 58 59 |
# File 'app/models/shoppe/order.rb', line 57 def confirming? self.status == 'confirming' end |
#courier_tracking_url ⇒ Object
The URL which can be used to track the delivery of this order
220 221 222 223 |
# File 'app/models/shoppe/order.rb', line 220 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
94 95 96 |
# File 'app/models/shoppe/order.rb', line 94 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
184 185 186 |
# File 'app/models/shoppe/order.rb', line 184 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
179 180 181 |
# File 'app/models/shoppe/order.rb', line 179 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
169 170 171 |
# File 'app/models/shoppe/order.rb', line 169 def delivery_service super || available_delivery_services.first end |
#delivery_service_price ⇒ Object
Return the delivery price for this order in its current state
174 175 176 |
# File 'app/models/shoppe/order.rb', line 174 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.
154 155 156 157 158 |
# File 'app/models/shoppe/order.rb', line 154 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
189 190 191 192 193 194 195 |
# File 'app/models/shoppe/order.rb', line 189 def delivery_tax_amount @delivery_tax_amount ||= begin read_attribute(:delivery_tax_amount) || (delivery_service_price && delivery_service_price.tax_rate ? delivery_price / BigDecimal(100) * delivery_service_price.tax_rate.rate : 0.0) || 0.0 end end |
#delivery_tax_rate ⇒ Object
The tax rate for the delivery of this order in its current state
198 199 200 201 202 203 204 |
# File 'app/models/shoppe/order.rb', line 198 def delivery_tax_rate @delivery_tax_rate ||= begin read_attribute(:delivery_tax_rate) || delivery_service_price.try(:tax_rate).try(:rate) || 0.0 end end |
#empty? ⇒ Boolean
Is this order empty? (i.e. doesn’t have any items associated with it)
99 100 101 |
# File 'app/models/shoppe/order.rb', line 99 def empty? order_items.empty? end |
#has_items? ⇒ Boolean
Does this order have items?
104 105 106 |
# File 'app/models/shoppe/order.rb', line 104 def has_items? total_items > 0 end |
#number ⇒ Object
The order number
82 83 84 |
# File 'app/models/shoppe/order.rb', line 82 def number id.to_s.rjust(6, '0') end |
#paid? ⇒ Boolean
Has this order been fully paid for?
226 227 228 |
# File 'app/models/shoppe/order.rb', line 226 def paid? !paid_at.blank? end |
#pay!(reference, method) ⇒ Object
This method will mark an order as paid.
288 289 290 291 292 293 294 295 |
# File 'app/models/shoppe/order.rb', line 288 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.
234 235 236 237 238 239 240 241 |
# File 'app/models/shoppe/order.rb', line 234 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
120 121 122 |
# File 'app/models/shoppe/order.rb', line 120 def profit total_before_tax - total_cost end |
#received? ⇒ Boolean
Has the order been received?
77 78 79 |
# File 'app/models/shoppe/order.rb', line 77 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).
311 312 313 314 315 316 317 318 319 320 |
# File 'app/models/shoppe/order.rb', line 311 def reject!(user) run_callbacks :rejection do self.rejected_at = Time.now self.rejected_by = user.id self.status = 'rejected' self.save! self.order_items.each(&:reject!) Shoppe::OrderMailer.rejected(self).deliver end end |
#rejected? ⇒ Boolean
Has this order been rejected?
62 63 64 |
# File 'app/models/shoppe/order.rb', line 62 def rejected? !!self.rejected_at end |
#remove_delivery_service_if_invalid ⇒ Object
Remove the associated delivery service if it’s invalid
212 213 214 215 216 217 |
# File 'app/models/shoppe/order.rb', line 212 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.
324 325 326 327 328 329 330 331 332 333 |
# File 'app/models/shoppe/order.rb', line 324 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?
72 73 74 |
# File 'app/models/shoppe/order.rb', line 72 def shipped? !!self.shipped_at? end |
#tax ⇒ Object
The total amount of tax due on this order
131 132 133 134 |
# File 'app/models/shoppe/order.rb', line 131 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
137 138 139 140 141 |
# File 'app/models/shoppe/order.rb', line 137 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
125 126 127 128 |
# File 'app/models/shoppe/order.rb', line 125 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
114 115 116 117 |
# File 'app/models/shoppe/order.rb', line 114 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
144 145 146 |
# File 'app/models/shoppe/order.rb', line 144 def total_in_pence (total * BigDecimal(100)).to_i end |
#total_items ⇒ Object
Return the number of items in the order?
109 110 111 |
# File 'app/models/shoppe/order.rb', line 109 def total_items @total_items ||= order_items.inject(0) { |t,i| t + i.quantity } end |
#total_weight ⇒ Object
The total weight of the order
149 150 151 |
# File 'app/models/shoppe/order.rb', line 149 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?
207 208 209 |
# File 'app/models/shoppe/order.rb', line 207 def valid_delivery_service? self.delivery_service && self.available_delivery_services.include?(self.delivery_service) end |