shoppe 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/shoppe/table-tear-off.png +0 -0
  3. data/app/assets/javascripts/shoppe/application.coffee +2 -2
  4. data/app/assets/stylesheets/shoppe/application.scss +80 -37
  5. data/app/assets/stylesheets/shoppe/elements.scss +1 -2
  6. data/app/controllers/shoppe/attachments_controller.rb +3 -3
  7. data/app/controllers/shoppe/countries_controller.rb +13 -13
  8. data/app/controllers/shoppe/delivery_service_prices_controller.rb +11 -11
  9. data/app/controllers/shoppe/delivery_services_controller.rb +13 -13
  10. data/app/controllers/shoppe/orders_controller.rb +20 -20
  11. data/app/controllers/shoppe/payments_controller.rb +8 -8
  12. data/app/controllers/shoppe/product_categories_controller.rb +13 -13
  13. data/app/controllers/shoppe/products_controller.rb +24 -13
  14. data/app/controllers/shoppe/sessions_controller.rb +7 -7
  15. data/app/controllers/shoppe/settings_controller.rb +6 -6
  16. data/app/controllers/shoppe/stock_level_adjustments_controller.rb +5 -5
  17. data/app/controllers/shoppe/tax_rates_controller.rb +13 -13
  18. data/app/controllers/shoppe/users_controller.rb +15 -15
  19. data/app/controllers/shoppe/variants_controller.rb +13 -13
  20. data/app/helpers/shoppe/application_helper.rb +12 -12
  21. data/app/models/shoppe/order/actions.rb +17 -3
  22. data/app/models/shoppe/order/billing.rb +18 -18
  23. data/app/models/shoppe/order/delivery.rb +30 -31
  24. data/app/models/shoppe/order_item.rb +33 -34
  25. data/app/models/shoppe/payment.rb +15 -15
  26. data/app/models/shoppe/product.rb +82 -21
  27. data/app/models/shoppe/product/variants.rb +10 -10
  28. data/app/models/shoppe/product_category.rb +7 -7
  29. data/app/models/shoppe/stock_level_adjustment.rb +6 -6
  30. data/app/validators/permalink_validator.rb +7 -0
  31. data/app/views/layouts/shoppe/application.html.haml +10 -20
  32. data/app/views/shoppe/countries/_form.html.haml +15 -11
  33. data/app/views/shoppe/countries/edit.html.haml +5 -4
  34. data/app/views/shoppe/countries/index.html.haml +9 -9
  35. data/app/views/shoppe/countries/new.html.haml +6 -4
  36. data/app/views/shoppe/delivery_service_prices/_form.html.haml +16 -16
  37. data/app/views/shoppe/delivery_service_prices/edit.html.haml +5 -4
  38. data/app/views/shoppe/delivery_service_prices/index.html.haml +8 -9
  39. data/app/views/shoppe/delivery_service_prices/new.html.haml +5 -4
  40. data/app/views/shoppe/delivery_services/_form.html.haml +15 -14
  41. data/app/views/shoppe/delivery_services/edit.html.haml +7 -5
  42. data/app/views/shoppe/delivery_services/index.html.haml +11 -12
  43. data/app/views/shoppe/delivery_services/new.html.haml +5 -4
  44. data/app/views/shoppe/orders/_form.html.haml +19 -19
  45. data/app/views/shoppe/orders/_order_details.html.haml +20 -15
  46. data/app/views/shoppe/orders/_order_items.html.haml +6 -6
  47. data/app/views/shoppe/orders/_order_items_form.html.haml +11 -11
  48. data/app/views/shoppe/orders/_payments_form.html.haml +4 -4
  49. data/app/views/shoppe/orders/_payments_table.html.haml +12 -12
  50. data/app/views/shoppe/orders/_search_form.html.haml +10 -10
  51. data/app/views/shoppe/orders/_status_bar.html.haml +17 -13
  52. data/app/views/shoppe/orders/despatch_note.html.haml +15 -15
  53. data/app/views/shoppe/orders/edit.html.haml +8 -8
  54. data/app/views/shoppe/orders/index.html.haml +12 -12
  55. data/app/views/shoppe/orders/new.html.haml +7 -7
  56. data/app/views/shoppe/orders/show.html.haml +9 -12
  57. data/app/views/shoppe/payments/refund.html.haml +6 -7
  58. data/app/views/shoppe/product_categories/_form.html.haml +9 -9
  59. data/app/views/shoppe/product_categories/edit.html.haml +4 -4
  60. data/app/views/shoppe/product_categories/index.html.haml +5 -5
  61. data/app/views/shoppe/product_categories/new.html.haml +4 -3
  62. data/app/views/shoppe/products/_form.html.haml +49 -50
  63. data/app/views/shoppe/products/_table.html.haml +10 -10
  64. data/app/views/shoppe/products/edit.html.haml +6 -6
  65. data/app/views/shoppe/products/import.html.haml +63 -0
  66. data/app/views/shoppe/products/index.html.haml +6 -4
  67. data/app/views/shoppe/products/new.html.haml +6 -4
  68. data/app/views/shoppe/sessions/new.html.haml +5 -5
  69. data/app/views/shoppe/sessions/reset.html.haml +6 -5
  70. data/app/views/shoppe/settings/edit.html.haml +5 -5
  71. data/app/views/shoppe/shared/error.html.haml +3 -3
  72. data/app/views/shoppe/stock_level_adjustments/index.html.haml +13 -12
  73. data/app/views/shoppe/tax_rates/form.html.haml +13 -13
  74. data/app/views/shoppe/tax_rates/index.html.haml +5 -5
  75. data/app/views/shoppe/users/_form.html.haml +10 -11
  76. data/app/views/shoppe/users/edit.html.haml +4 -4
  77. data/app/views/shoppe/users/index.html.haml +5 -5
  78. data/app/views/shoppe/users/new.html.haml +6 -4
  79. data/app/views/shoppe/variants/form.html.haml +27 -29
  80. data/app/views/shoppe/variants/index.html.haml +11 -11
  81. data/config/locales/en.yml +619 -14
  82. data/config/locales/es.yml +650 -0
  83. data/config/locales/pl.yml +650 -0
  84. data/config/locales/pt-BR.yml +643 -0
  85. data/config/routes.rb +16 -8
  86. data/db/migrate/20141026175622_add_indexes_to_shoppe_order_items.rb +6 -0
  87. data/db/migrate/20141026175943_add_indexes_to_shoppe_orders.rb +7 -0
  88. data/db/migrate/20141026180333_add_indexes_to_shoppe_payments.rb +6 -0
  89. data/db/migrate/20141026180835_add_indexes_to_shoppe_product_attributes.rb +7 -0
  90. data/db/migrate/20141026180952_add_indexes_to_shoppe_product_categories.rb +5 -0
  91. data/db/migrate/20141026181040_add_indexes_to_shoppe_products.rb +8 -0
  92. data/db/migrate/20141026181312_add_indexes_to_shoppe_settings.rb +5 -0
  93. data/db/migrate/20141026181354_add_indexes_to_shoppe_stock_level_adjustments.rb +6 -0
  94. data/db/migrate/20141026181559_add_indexes_to_shoppe_users.rb +5 -0
  95. data/db/migrate/20141026181716_add_indexes_to_shoppe_delivery_services.rb +9 -0
  96. data/db/schema.rb +36 -1
  97. data/lib/shoppe/engine.rb +6 -0
  98. data/lib/shoppe/navigation_manager.rb +1 -1
  99. data/lib/shoppe/version.rb +1 -1
  100. metadata +67 -5
@@ -1,53 +1,53 @@
1
1
  module Shoppe
2
2
  class UsersController < Shoppe::ApplicationController
3
-
3
+
4
4
  before_filter { @active_nav = :users }
5
5
  before_filter { params[:id] && @user = Shoppe::User.find(params[:id]) }
6
6
  before_filter(:only => [:create, :update, :destroy]) do
7
7
  if Shoppe.settings.demo_mode?
8
- raise Shoppe::Error, "You cannot make changes to users in demo mode. Sorry about that."
8
+ raise Shoppe::Error, t('shoppe.users.demo_mode_error')
9
9
  end
10
10
  end
11
-
11
+
12
12
  def index
13
13
  @users = Shoppe::User.all
14
14
  end
15
-
15
+
16
16
  def new
17
17
  @user = Shoppe::User.new
18
18
  end
19
-
19
+
20
20
  def create
21
21
  @user = Shoppe::User.new(safe_params)
22
22
  if @user.save
23
- redirect_to :users, :flash => {:notice => "User has been created successfully"}
23
+ redirect_to :users, :flash => {:notice => t('shoppe.users.create_notice') }
24
24
  else
25
25
  render :action => "new"
26
26
  end
27
27
  end
28
-
28
+
29
29
  def edit
30
30
  end
31
-
31
+
32
32
  def update
33
33
  if @user.update(safe_params)
34
- redirect_to [:edit, @user], :flash => {:notice => "User has been updated successfully"}
34
+ redirect_to [:edit, @user], :flash => {:notice => t('shoppe.users.update_notice') }
35
35
  else
36
36
  render :action => "edit"
37
37
  end
38
38
  end
39
-
39
+
40
40
  def destroy
41
- raise Shoppe::Error, "You cannot remove yourself" if @user == current_user
41
+ raise Shoppe::Error, t('shoppe.users.self_remove_error') if @user == current_user
42
42
  @user.destroy
43
- redirect_to :users, :flash => {:notice => "User has been removed successfully"}
43
+ redirect_to :users, :flash => {:notice => t('shoppe.users.destroy_notice') }
44
44
  end
45
-
45
+
46
46
  private
47
-
47
+
48
48
  def safe_params
49
49
  params[:user].permit(:first_name, :last_name, :email_address, :password, :password_confirmation)
50
50
  end
51
-
51
+
52
52
  end
53
53
  end
@@ -1,50 +1,50 @@
1
1
  module Shoppe
2
2
  class VariantsController < ApplicationController
3
-
3
+
4
4
  before_filter { @active_nav = :products }
5
5
  before_filter { @product = Shoppe::Product.find(params[:product_id]) }
6
6
  before_filter { params[:id] && @variant = @product.variants.find(params[:id]) }
7
-
7
+
8
8
  def index
9
9
  @variants = @product.variants.ordered
10
10
  end
11
-
11
+
12
12
  def new
13
13
  @variant = @product.variants.build
14
14
  render :action => "form"
15
15
  end
16
-
16
+
17
17
  def create
18
18
  @variant = @product.variants.build(safe_params)
19
19
  if @variant.save
20
- redirect_to [@product, :variants], :notice => "Varient has been added successfully"
20
+ redirect_to [@product, :variants], :notice => t('shoppe.variants.create_notice')
21
21
  else
22
22
  render :action => "form"
23
23
  end
24
24
  end
25
-
25
+
26
26
  def edit
27
27
  render :action => "form"
28
28
  end
29
-
29
+
30
30
  def update
31
31
  if @variant.update(safe_params)
32
- redirect_to edit_product_variant_path(@product, @variant), :notice => "Varient has been updated successfully"
32
+ redirect_to edit_product_variant_path(@product, @variant), :notice => t('shoppe.variants.update_notice')
33
33
  else
34
34
  render :action => "form"
35
35
  end
36
36
  end
37
-
37
+
38
38
  def destroy
39
39
  @variant.destroy
40
- redirect_to [@product, :variants], :notice => "Varient has been removed successfully"
40
+ redirect_to [@product, :variants], :notice => t('shoppe.variants.destroy_notice')
41
41
  end
42
-
42
+
43
43
  private
44
-
44
+
45
45
  def safe_params
46
46
  params[:product].permit(:name, :permalink, :sku, :default_image_file, :price, :cost_price, :tax_rate_id, :weight, :stock_control, :active, :default)
47
47
  end
48
-
48
+
49
49
  end
50
50
  end
@@ -1,14 +1,14 @@
1
1
  module Shoppe
2
2
  module ApplicationHelper
3
-
3
+
4
4
  def navigation_manager_link(item)
5
5
  link_to item.description, item.url(self), item.link_options.merge(:class => item.active?(self) ? 'active' : 'inactive')
6
6
  end
7
-
7
+
8
8
  def status_tag(status)
9
- content_tag :span, status, :class => "status-tag #{status}"
9
+ content_tag :span, t("shoppe.orders.statuses.#{status}"), :class => "status-tag #{status}"
10
10
  end
11
-
11
+
12
12
  def attachment_preview(attachment, options = {})
13
13
  if attachment
14
14
  String.new.tap do |s|
@@ -22,24 +22,24 @@ module Shoppe
22
22
  s << "<div class='desc'>"
23
23
  s << "<span class='filename'><a href='#{attachment_path(attachment)}'>#{attachment.file_name}</a></span>"
24
24
  s << "<span class='delete'>"
25
- s << link_to(t('shoppe.helpers.attachment_preview.delete', :default => 'Delete this file?'), attachment_path(attachment), :method => :delete, :data => {:confirm => t('shoppe.helpers.attachment_preview.delete_confirm', :default => "Are you sure you wish to remove this attachment?")})
25
+ s << link_to(t('helpers.attachment_preview.delete', :default => 'Delete this file?'), attachment_path(attachment), :method => :delete, :data => {:confirm => t('helpers.attachment_preview.delete_confirm', :default => "Are you sure you wish to remove this attachment?")})
26
26
  s << "</span>"
27
27
  s << "</div>"
28
28
  s << "</div>"
29
29
  end.html_safe
30
30
  elsif !options[:hide_if_blank]
31
- "<div class='attachmentPreview'><div class='imgContainer'><div class='img none'></div></div><div class='desc none'>No attachment</div></div>".html_safe
31
+ "<div class='attachmentPreview'><div class='imgContainer'><div class='img none'></div></div><div class='desc none'>#{t('helpers.attachment_preview.no_attachment')},</div></div>".html_safe
32
32
  end
33
33
  end
34
-
34
+
35
35
  def settings_label(field)
36
36
  "<label for='settings_#{field}'>#{t("shoppe.settings.labels.#{field}")}</label>".html_safe
37
37
  end
38
-
38
+
39
39
  def settings_field(field, options = {})
40
- default = t("shoppe.settings.defaults")[field.to_sym]
40
+ default = I18n.t("shoppe.settings.defaults")[field.to_sym]
41
41
  value = (params[:settings] && params[:settings][field]) || Shoppe.settings[field.to_s]
42
- type = t("shoppe.settings.types")[field.to_sym] || 'string'
42
+ type = I18n.t("shoppe.settings.types")[field.to_sym] || 'string'
43
43
  case type
44
44
  when 'boolean'
45
45
  String.new.tap do |s|
@@ -55,6 +55,6 @@ module Shoppe
55
55
  text_field_tag "settings[#{field}]", value, options.merge(:placeholder => default, :class => 'text')
56
56
  end
57
57
  end
58
-
58
+
59
59
  end
60
- end
60
+ end
@@ -1,6 +1,8 @@
1
1
  module Shoppe
2
2
  class Order < ActiveRecord::Base
3
3
 
4
+ extend ActiveModel::Callbacks
5
+
4
6
  # These additional callbacks allow for applications to hook into other
5
7
  # parts of the order lifecycle.
6
8
  define_model_callbacks :confirmation, :acceptance, :rejection
@@ -41,7 +43,7 @@ module Shoppe
41
43
  self.order_items.each(&:confirm!)
42
44
 
43
45
  # Send an email to the customer
44
- Shoppe::OrderMailer.received(self).deliver
46
+ deliver_received_order_email
45
47
  end
46
48
 
47
49
  # We're all good.
@@ -59,7 +61,7 @@ module Shoppe
59
61
  self.status = 'accepted'
60
62
  self.save!
61
63
  self.order_items.each(&:accept!)
62
- Shoppe::OrderMailer.accepted(self).deliver
64
+ deliver_accepted_order_email
63
65
  end
64
66
  end
65
67
  end
@@ -75,10 +77,22 @@ module Shoppe
75
77
  self.status = 'rejected'
76
78
  self.save!
77
79
  self.order_items.each(&:reject!)
78
- Shoppe::OrderMailer.rejected(self).deliver
80
+ deliver_rejected_order_email
79
81
  end
80
82
  end
81
83
  end
84
+
85
+ def deliver_accepted_order_email
86
+ Shoppe::OrderMailer.accepted(self).deliver
87
+ end
88
+
89
+ def deliver_rejected_order_email
90
+ Shoppe::OrderMailer.rejected(self).deliver
91
+ end
92
+
93
+ def deliver_received_order_email
94
+ Shoppe::OrderMailer.received(self).deliver
95
+ end
82
96
 
83
97
  end
84
98
  end
@@ -1,14 +1,14 @@
1
1
  module Shoppe
2
2
  class Order < ActiveRecord::Base
3
-
3
+
4
4
  # The country which this order should be billed to
5
5
  #
6
6
  # @return [Shoppe::Country]
7
7
  belongs_to :billing_country, :class_name => 'Shoppe::Country', :foreign_key => 'billing_country_id'
8
-
8
+
9
9
  # Payments which have been stored for the order
10
10
  has_many :payments, :dependent => :destroy, :class_name => 'Shoppe::Payment'
11
-
11
+
12
12
  # Validations
13
13
  with_options :if => Proc.new { |o| !o.building? } do |order|
14
14
  order.validates :first_name, :presence => true
@@ -19,43 +19,43 @@ module Shoppe
19
19
  order.validates :billing_postcode, :presence => true
20
20
  order.validates :billing_country, :presence => true
21
21
  end
22
-
22
+
23
23
  # The name for billing purposes
24
24
  #
25
25
  # @return [String]
26
26
  def billing_name
27
27
  company.blank? ? full_name : "#{full_name} (#{company})"
28
28
  end
29
-
29
+
30
30
  # The total cost of the order
31
31
  #
32
32
  # @return [BigDecimal]
33
33
  def total_cost
34
- self.delivery_cost_price +
34
+ self.delivery_cost_price +
35
35
  order_items.inject(BigDecimal(0)) { |t, i| t + i.total_cost }
36
36
  end
37
-
37
+
38
38
  # Return the price for the order
39
39
  #
40
40
  # @return [BigDecimal]
41
41
  def profit
42
42
  total_before_tax - total_cost
43
43
  end
44
-
44
+
45
45
  # The total price of all items in the basket excluding delivery
46
46
  #
47
47
  # @return [BigDecimal]
48
48
  def items_sub_total
49
49
  order_items.inject(BigDecimal(0)) { |t, i| t + i.sub_total }
50
50
  end
51
-
51
+
52
52
  # The total price of the order before tax
53
53
  #
54
54
  # @return [BigDecimal]
55
55
  def total_before_tax
56
56
  self.delivery_price + self.items_sub_total
57
57
  end
58
-
58
+
59
59
  # The total amount of tax due on this order
60
60
  #
61
61
  # @return [BigDecimal]
@@ -63,43 +63,43 @@ module Shoppe
63
63
  self.delivery_tax_amount +
64
64
  order_items.inject(BigDecimal(0)) { |t, i| t + i.tax_amount }
65
65
  end
66
-
66
+
67
67
  # The total of the order including tax
68
68
  #
69
69
  # @return [BigDecimal]
70
70
  def total
71
- self.delivery_price +
72
- self.delivery_tax_amount +
71
+ self.delivery_price +
72
+ self.delivery_tax_amount +
73
73
  order_items.inject(BigDecimal(0)) { |t, i| t + i.total }
74
74
  end
75
-
75
+
76
76
  # The total amount due on the order
77
77
  #
78
78
  # @return [BigDecimal]
79
79
  def balance
80
80
  @balance ||= total - amount_paid
81
81
  end
82
-
82
+
83
83
  # Is there a payment still outstanding on this order?
84
84
  #
85
85
  # @return [Boolean]
86
86
  def payment_outstanding?
87
87
  balance > BigDecimal(0)
88
88
  end
89
-
89
+
90
90
  # Has this order been paid in full?
91
91
  #
92
92
  # @return [Boolean]
93
93
  def paid_in_full?
94
94
  !payment_outstanding?
95
95
  end
96
-
96
+
97
97
  # Is the order invoiced?
98
98
  #
99
99
  # @return [Boolean]
100
100
  def invoiced?
101
101
  !invoice_number.blank?
102
102
  end
103
-
103
+
104
104
  end
105
105
  end
@@ -1,24 +1,24 @@
1
1
  module Shoppe
2
2
  class Order < ActiveRecord::Base
3
-
3
+
4
4
  # The associated delivery service
5
5
  #
6
6
  # @return [Shoppe::DeliveryService]
7
7
  belongs_to :delivery_service, :class_name => 'Shoppe::DeliveryService'
8
-
8
+
9
9
  # The country where this order is being delivered to (if one has been provided)
10
10
  #
11
11
  # @return [Shoppe::Country]
12
12
  belongs_to :delivery_country, :class_name => 'Shoppe::Country', :foreign_key => 'delivery_country_id'
13
-
13
+
14
14
  # The user who marked the order has shipped
15
15
  #
16
16
  # @return [Shoppe::User]
17
17
  belongs_to :shipper, :class_name => 'Shoppe::User', :foreign_key => 'shipped_by'
18
-
18
+
19
19
  # Set up a callback for use when an order is shipped
20
20
  define_model_callbacks :ship
21
-
21
+
22
22
  # Validations
23
23
  with_options :if => :separate_delivery_address? do |order|
24
24
  order.validates :delivery_name, :presence => true
@@ -28,17 +28,17 @@ module Shoppe
28
28
  order.validates :delivery_postcode, :presence => true
29
29
  order.validates :delivery_country, :presence => true
30
30
  end
31
-
31
+
32
32
  validate do
33
33
  if self.delivery_required?
34
34
  if self.delivery_service.nil?
35
- errors.add :delivery_service_id, "must be specified"
35
+ errors.add :delivery_service_id, :must_be_specified
36
36
  elsif !self.valid_delivery_service?
37
- errors.add :delivery_service_id, "is not suitable for this order"
37
+ errors.add :delivery_service_id, :not_suitable
38
38
  end
39
39
  end
40
40
  end
41
-
41
+
42
42
  before_confirmation do
43
43
  # Ensure that before we confirm the order that the delivery service which has been selected
44
44
  # is appropritae for the contents of the order.
@@ -47,7 +47,7 @@ module Shoppe
47
47
  end
48
48
  cache_delivery_pricing
49
49
  end
50
-
50
+
51
51
  # If an order has been received and something changes the delivery service or the delivery price
52
52
  # is cleared, we will re-cache all the delivery pricing so that we have the latest.
53
53
  before_save do
@@ -59,7 +59,7 @@ module Shoppe
59
59
  cache_delivery_pricing
60
60
  end
61
61
  end
62
-
62
+
63
63
  # If there isn't a seperate address needed, clear all the fields back to nil
64
64
  before_validation do
65
65
  unless separate_delivery_address?
@@ -72,7 +72,7 @@ module Shoppe
72
72
  self.delivery_country = nil
73
73
  end
74
74
  end
75
-
75
+
76
76
  # Create some delivery_ methods which will mimic the billing methods if the order does
77
77
  # not need a seperate address.
78
78
  [:delivery_name, :delivery_address1, :delivery_address2, :delivery_address3, :delivery_address4, :delivery_postcode, :delivery_country].each do |f|
@@ -80,7 +80,7 @@ module Shoppe
80
80
  separate_delivery_address? ? super() : send(f.to_s.gsub('delivery_', 'billing_'))
81
81
  end
82
82
  end
83
-
83
+
84
84
  # Cache delivery prices for the order
85
85
  def cache_delivery_pricing
86
86
  if self.delivery_service
@@ -96,34 +96,34 @@ module Shoppe
96
96
  write_attribute :delivery_tax_amount, nil
97
97
  end
98
98
  end
99
-
99
+
100
100
  # Cache prices and save the order
101
101
  def cache_delivery_pricing!
102
102
  cache_delivery_pricing
103
103
  save!
104
104
  end
105
-
105
+
106
106
  # Has this order been shipped?
107
107
  #
108
108
  # @return [Boolean]
109
109
  def shipped?
110
110
  !!self.shipped_at?
111
111
  end
112
-
112
+
113
113
  # The total weight of the order
114
114
  #
115
115
  # @return [BigDecimal]
116
116
  def total_weight
117
117
  order_items.inject(BigDecimal(0)) { |t,i| t + i.total_weight}
118
118
  end
119
-
119
+
120
120
  # Is delivery required for this order?
121
121
  #
122
122
  # @return [Boolean]
123
123
  def delivery_required?
124
124
  total_weight > BigDecimal(0)
125
125
  end
126
-
126
+
127
127
  # An array of all the delivery services which are suitable for this order in it's
128
128
  # current state (based on its current weight)
129
129
  #
@@ -131,7 +131,7 @@ module Shoppe
131
131
  def available_delivery_services
132
132
  delivery_service_prices.map(&:delivery_service).uniq
133
133
  end
134
-
134
+
135
135
  # An array of all the delivery service prices which can be applied to this order.
136
136
  #
137
137
  # @return [Array] an array of Shoppe:DeliveryServicePrice objects
@@ -139,8 +139,7 @@ module Shoppe
139
139
  if delivery_required?
140
140
  prices = Shoppe::DeliveryServicePrice.joins(:delivery_service).where(:shoppe_delivery_services => {:active => true}).order(:price).for_weight(total_weight)
141
141
  prices = prices.select { |p| p.countries.empty? || p.country?(self.delivery_country) }
142
- prices = prices.group_by { |dsp| dsp.delivery_service.default? }
143
- (prices[true] || []) | (prices[false] || [])
142
+ prices.sort{ |x,y| (y.delivery_service.default? ? 1 : 0) <=> (x.delivery_service.default? ? 1 : 0) } # Order by truthiness
144
143
  else
145
144
  []
146
145
  end
@@ -152,28 +151,28 @@ module Shoppe
152
151
  def delivery_service
153
152
  super || available_delivery_services.first
154
153
  end
155
-
154
+
156
155
  # Return the delivery price for this order in its current state
157
156
  #
158
157
  # @return [BigDecimal]
159
158
  def delivery_service_price
160
159
  self.delivery_service && self.delivery_service.delivery_service_prices.for_weight(self.total_weight).first
161
160
  end
162
-
161
+
163
162
  # The price for delivering this order in its current state
164
163
  #
165
164
  # @return [BigDecimal]
166
165
  def delivery_price
167
166
  read_attribute(:delivery_price) || delivery_service_price.try(:price) || BigDecimal(0)
168
167
  end
169
-
168
+
170
169
  # The cost of delivering this order in its current state
171
170
  #
172
171
  # @return [BigDecimal]
173
172
  def delivery_cost_price
174
173
  read_attribute(:delivery_cost_price) || delivery_service_price.try(:cost_price) || BigDecimal(0)
175
174
  end
176
-
175
+
177
176
  # The tax amount due for the delivery of this order in its current state
178
177
  #
179
178
  # @return [BigDecimal]
@@ -181,7 +180,7 @@ module Shoppe
181
180
  read_attribute(:delivery_tax_amount) ||
182
181
  delivery_price / BigDecimal(100) * delivery_tax_rate
183
182
  end
184
-
183
+
185
184
  # The tax rate for the delivery of this order in its current state
186
185
  #
187
186
  # @return [BigDecimal]
@@ -190,14 +189,14 @@ module Shoppe
190
189
  delivery_service_price.try(:tax_rate).try(:rate_for, self) ||
191
190
  BigDecimal(0)
192
191
  end
193
-
192
+
194
193
  # Is the currently assigned delivery service appropriate for this order?
195
194
  #
196
195
  # @return [Boolean]
197
196
  def valid_delivery_service?
198
197
  self.delivery_service ? self.available_delivery_services.include?(self.delivery_service) : !self.delivery_required?
199
198
  end
200
-
199
+
201
200
  # Remove the associated delivery service if it's invalid
202
201
  def remove_delivery_service_if_invalid
203
202
  unless self.valid_delivery_service?
@@ -205,7 +204,7 @@ module Shoppe
205
204
  self.save
206
205
  end
207
206
  end
208
-
207
+
209
208
  # The URL which can be used to track the delivery of this order
210
209
  #
211
210
  # @return [String]
@@ -213,7 +212,7 @@ module Shoppe
213
212
  return nil if self.shipped_at.blank? || self.consignment_number.blank?
214
213
  @courier_tracking_url ||= self.delivery_service.tracking_url_for(self)
215
214
  end
216
-
215
+
217
216
  # Mark this order as shipped
218
217
  def ship!(consignment_number, user = nil)
219
218
  run_callbacks :ship do
@@ -225,6 +224,6 @@ module Shoppe
225
224
  Shoppe::OrderMailer.shipped(self).deliver
226
225
  end
227
226
  end
228
-
227
+
229
228
  end
230
229
  end