piggybak 0.6.34 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -14
  3. data/Gemfile.lock +18 -149
  4. data/README.md +6 -0
  5. data/app/assets/javascripts/piggybak/piggybak.js +18 -15
  6. data/app/assets/javascripts/piggybak/piggybak.states.js +7 -4
  7. data/app/assets/javascripts/rails_admin/custom/ui.js.erb +33 -28
  8. data/app/controllers/piggybak/orders_controller.rb +15 -3
  9. data/app/models/piggybak/address.rb +8 -11
  10. data/app/models/piggybak/country.rb +3 -4
  11. data/app/models/piggybak/line_item.rb +3 -3
  12. data/app/models/piggybak/order.rb +11 -6
  13. data/app/models/piggybak/order_note.rb +2 -3
  14. data/app/models/piggybak/payment.rb +4 -7
  15. data/app/models/piggybak/payment_method.rb +2 -4
  16. data/app/models/piggybak/payment_method_value.rb +2 -4
  17. data/app/models/piggybak/sellable.rb +4 -7
  18. data/app/models/piggybak/shipment.rb +2 -4
  19. data/app/models/piggybak/shipping_calculator/flat_rate.rb +1 -1
  20. data/app/models/piggybak/shipping_calculator/range.rb +1 -1
  21. data/app/models/piggybak/shipping_method +0 -0
  22. data/app/models/piggybak/shipping_method.rb +3 -6
  23. data/app/models/piggybak/shipping_method_value.rb +2 -3
  24. data/app/models/piggybak/state.rb +0 -1
  25. data/app/models/piggybak/tax_calculator/percent.rb +6 -10
  26. data/app/models/piggybak/tax_method.rb +5 -6
  27. data/app/models/piggybak/tax_method_value.rb +2 -3
  28. data/app/views/piggybak/orders/_user_details.html.erb +2 -2
  29. data/app/views/rails_admin/main/{_copy_from_billing.html.haml → _copy_from_billing.html.erb} +0 -0
  30. data/app/views/rails_admin/main/_location_select.html.haml +2 -4
  31. data/app/views/rails_admin/main/_polymorphic_nested.html.haml +1 -25
  32. data/config/routes.rb +17 -19
  33. data/db/migrate/20140325133841_upgrade_piggybak_tables.rb +19 -0
  34. data/lib/piggybak.rb +1 -477
  35. data/lib/piggybak/config.rb +2 -0
  36. data/lib/piggybak/engine.rb +481 -0
  37. data/lib/piggybak/version.rb +1 -1
  38. metadata +6 -46
  39. data/lib/currency.rb +0 -5
@@ -9,11 +9,11 @@ module Piggybak
9
9
 
10
10
  begin
11
11
  ActiveRecord::Base.transaction do
12
- @order = Piggybak::Order.new(params[:piggybak_order])
12
+ @order = Piggybak::Order.new(orders_params)
13
13
  @order.create_payment_shipment
14
14
 
15
15
  if Piggybak.config.logging
16
- clean_params = params[:piggybak_order].clone
16
+ clean_params = params[:order].clone
17
17
  clean_params[:line_items_attributes].each do |k, li_attr|
18
18
  if li_attr[:line_item_type] == "payment" && li_attr.has_key?(:payment_attributes)
19
19
  if li_attr[:payment_attributes].has_key?(:number)
@@ -144,12 +144,24 @@ module Piggybak
144
144
  end
145
145
 
146
146
  def geodata
147
- countries = ::Piggybak::Country.find(:all, :include => :states)
147
+ countries = ::Piggybak::Country.all.includes(:states)
148
148
  data = countries.inject({}) do |h, country|
149
149
  h["country_#{country.id}"] = country.states
150
150
  h
151
151
  end
152
152
  render :json => { :countries => data }
153
153
  end
154
+
155
+ private
156
+ def orders_params
157
+ nested_attributes = [shipment_attributes: [:shipping_method_id],
158
+ payment_attributes: [:number, :verification_value, :month, :year]].first.merge(Piggybak.config.additional_line_item_attributes)
159
+ line_item_attributes = [:sellable_id, :price, :unit_price, :description, :quantity, :line_item_type, nested_attributes]
160
+ params.require(:order).permit(:user_id, :email, :phone, :ip_address,
161
+ billing_address_attributes: [:firstname, :lastname, :address1, :location, :address2, :city, :state_id, :zip, :country_id],
162
+ shipping_address_attributes: [:firstname, :lastname, :address1, :location, :address2, :city, :state_id, :zip, :country_id, :copy_from_billing],
163
+ line_items_attributes: line_item_attributes)
164
+
165
+ end
154
166
  end
155
167
  end
@@ -5,20 +5,17 @@ module Piggybak
5
5
  has_one :order_shipping, :foreign_key => "shipping_address_id", :class_name => "Piggybak::Order"
6
6
  has_one :order_billing, :foreign_key => "billing_address_id", :class_name => "Piggybak::Order"
7
7
 
8
- validates_presence_of :firstname
9
- validates_presence_of :lastname
10
- validates_presence_of :address1
11
- validates_presence_of :city
12
- validates_presence_of :state_id
13
- validates_presence_of :country_id
14
- validates_presence_of :zip
8
+ validates :firstname, presence: true
9
+ validates :lastname, presence: true
10
+ validates :address1, presence: true
11
+ validates :city, presence: true
12
+ validates :state_id, presence: true
13
+ validates :country_id, presence: true
14
+ validates :zip, presence: true
15
15
 
16
16
  after_initialize :set_default_country
17
17
  after_save :document_address_changes
18
18
 
19
- attr_accessible :firstname, :lastname, :address1, :location,
20
- :address2, :city, :state_id, :zip, :country_id,
21
- :copy_from_billing
22
19
  attr_accessor :is_shipping
23
20
 
24
21
  def set_default_country
@@ -41,8 +38,8 @@ module Piggybak
41
38
  self.state ? self.state.name : self.state_id
42
39
  end
43
40
 
41
+ # TODO: Fix this. It isn't working.
44
42
  def document_address_changes
45
- # TODO: Fix this. It isn't working.
46
43
  if self.order_billing.present? && self.changed?
47
44
  self.order_billing.recorded_changes << self.formatted_changes
48
45
  end
@@ -1,10 +1,9 @@
1
1
  module Piggybak
2
2
  class Country < ActiveRecord::Base
3
- attr_accessible :name, :abbr, :active_shipping, :active_billing
4
3
  has_many :states
5
4
 
6
- scope :shipping, where(:active_shipping => true)
7
- scope :billing, where(:active_billing => true)
8
- default_scope :order => 'name ASC'
5
+ scope :shipping, -> { where(:active_shipping => true)}
6
+ scope :billing, -> { where(:active_billing => true)}
7
+ default_scope { order('name ASC') }
9
8
  end
10
9
  end
@@ -4,7 +4,9 @@ module Piggybak
4
4
  acts_as_changer
5
5
  belongs_to :sellable
6
6
 
7
- validates_presence_of :price, :description, :quantity
7
+ validates :price, presence: true
8
+ validates :description, presence: true
9
+ validates :quantity, presence: true
8
10
  validates_numericality_of :quantity, :only_integer => true, :greater_than_or_equal_to => 0
9
11
 
10
12
  default_scope :order => 'created_at ASC'
@@ -13,8 +15,6 @@ module Piggybak
13
15
  after_destroy :increase_inventory, :if => Proc.new { |line_item| line_item.line_item_type == 'sellable' && !line_item.sellable.unlimited_inventory }
14
16
  after_update :update_inventory, :if => Proc.new { |line_item| line_item.line_item_type == 'sellable' && !line_item.sellable.unlimited_inventory }
15
17
 
16
- attr_accessible :sellable_id, :price, :unit_price, :description, :quantity, :line_item_type
17
-
18
18
  after_initialize :initialize_line_item
19
19
  before_validation :preprocess
20
20
  before_destroy :destroy_associated_item
@@ -15,7 +15,14 @@ module Piggybak
15
15
  attr_accessor :recorded_changes, :recorded_changer,
16
16
  :was_new_record, :disable_order_notes
17
17
 
18
- validates_presence_of :status, :email, :phone, :total, :total_due, :created_at, :ip_address, :user_agent
18
+ validates :status, presence: true
19
+ validates :email, presence: true
20
+ validates :phone, presence: true
21
+ validates :total, presence: true
22
+ validates :total_due, presence: true
23
+ validates :created_at, presence: true
24
+ validates :ip_address, presence: true
25
+ validates :user_agent, presence: true
19
26
 
20
27
  after_initialize :initialize_defaults
21
28
  validate :number_payments
@@ -25,10 +32,6 @@ module Piggybak
25
32
 
26
33
  default_scope :order => 'created_at DESC'
27
34
 
28
- attr_accessible :user_id, :email, :phone, :billing_address_attributes,
29
- :shipping_address_attributes, :line_items_attributes,
30
- :order_notes_attributes, :details, :recorded_changer, :ip_address
31
-
32
35
  def deliver_order_confirmation
33
36
  Piggybak::Notifier.order_notification(self).deliver
34
37
  self.update_column(:confirmation_sent,true)
@@ -52,6 +55,7 @@ module Piggybak
52
55
  end
53
56
 
54
57
  def number_payments
58
+
55
59
  new_payments = self.line_items.payments.select { |li| li.new_record? }
56
60
  if new_payments.size > 1
57
61
  self.errors.add(:base, "Only one payment may be created at a time.")
@@ -69,6 +73,7 @@ module Piggybak
69
73
  end
70
74
 
71
75
  def postprocess_order
76
+
72
77
  # Mark line items for destruction if quantity == 0
73
78
  self.line_items.each do |line_item|
74
79
  if line_item.quantity == 0
@@ -102,7 +107,7 @@ module Piggybak
102
107
  end
103
108
  end
104
109
  end
105
-
110
+
106
111
  # Recalculating total and total due, in case post process changed totals
107
112
  self.total_due = 0
108
113
  self.total = 0
@@ -1,11 +1,10 @@
1
1
  module Piggybak
2
2
  class OrderNote < ActiveRecord::Base
3
- attr_accessible :user_id, :order_id, :note, :created_at
4
- validates_presence_of :user_id, :order_id
3
+ validates :user_id, presence: true
4
+ validates :order_id, presence: true
5
5
 
6
6
  belongs_to :order
7
7
  belongs_to :user
8
- validates_presence_of :user_id
9
8
  default_scope :order => 'created_at ASC'
10
9
 
11
10
  def details
@@ -4,16 +4,13 @@ module Piggybak
4
4
  belongs_to :payment_method
5
5
  belongs_to :line_item
6
6
 
7
- validates_presence_of :status
8
- validates_presence_of :payment_method_id
9
- validates_presence_of :month
10
- validates_presence_of :year
7
+ validates :status, presence: true
8
+ validates :payment_method_id, presence: true
9
+ validates :month, presence: true
10
+ validates :year, presence: true
11
11
 
12
12
  attr_accessor :number
13
13
  attr_accessor :verification_value
14
-
15
- attr_accessible :number, :verification_value, :month, :year,
16
- :transaction_id, :masked_number, :payment_method_id
17
14
 
18
15
  def status_enum
19
16
  ["paid"]
@@ -5,11 +5,9 @@ module Piggybak
5
5
 
6
6
  accepts_nested_attributes_for :payment_method_values, :allow_destroy => true
7
7
 
8
- validates_presence_of :klass
9
- validates_presence_of :description
8
+ validates :klass, presence: true
9
+ validates :description, presence: true
10
10
 
11
- attr_accessible :active, :payment_method_values_attributes, :description,
12
- :klass
13
11
  def klass_enum
14
12
  Piggybak.config.payment_calculators
15
13
  end
@@ -1,11 +1,9 @@
1
1
  module Piggybak
2
2
  class PaymentMethodValue < ActiveRecord::Base
3
3
  belongs_to :payment_method
4
- validates_presence_of :key
5
- validates_presence_of :value
4
+ validates :key, presence: true
5
+ validates :value, presence: true
6
6
 
7
- attr_accessible :key, :value, :payment_method_id
8
-
9
7
  def admin_label
10
8
  "#{self.key} - #{self.value}"
11
9
  end
@@ -1,13 +1,10 @@
1
1
  class Piggybak::Sellable < ActiveRecord::Base
2
2
  belongs_to :item, :polymorphic => true, :inverse_of => :piggybak_sellable
3
- attr_accessible :sku, :description, :price, :quantity, :active, :unlimited_inventory, :item_id, :item_type
4
- attr_accessible :item # to allow direct assignment from code or console
5
3
 
6
- validates_presence_of :sku
7
- validates_uniqueness_of :sku
8
- validates_presence_of :description
9
- validates_presence_of :price
10
- validates_presence_of :item_type
4
+ validates :sku, presence: true, uniqueness: true
5
+ validates :description, presence: true
6
+ validates :price, presence: true
7
+ validates :item_type, presence: true
11
8
  validates_numericality_of :quantity, :only_integer => true, :greater_than_or_equal_to => 0
12
9
 
13
10
  has_many :line_items, :as => :reference, :inverse_of => :reference
@@ -4,10 +4,8 @@ module Piggybak
4
4
  belongs_to :shipping_method
5
5
  belongs_to :line_item
6
6
 
7
- validates_presence_of :status
8
- validates_presence_of :shipping_method_id
9
-
10
- attr_accessible :shipping_method_id, :status
7
+ validates :status, presence: true
8
+ validates :shipping_method_id, presence: true
11
9
 
12
10
  def status_enum
13
11
  ["new", "processing", "shipped"]
@@ -11,7 +11,7 @@ module Piggybak
11
11
  end
12
12
 
13
13
  def self.rate(method, object)
14
- method.metadata.detect { |m| m.key == "rate" }.value.to_f.to_c
14
+ method.metadata.detect { |m| m.key == "rate" }.value.to_f
15
15
  end
16
16
  end
17
17
  end
@@ -14,7 +14,7 @@ module Piggybak
14
14
  end
15
15
 
16
16
  def self.rate(method, object)
17
- method.metadata.detect { |m| m.key == "cost" }.value.to_f.to_c
17
+ method.metadata.detect { |m| m.key == "cost" }.value.to_f
18
18
  end
19
19
  end
20
20
  end
File without changes
@@ -3,14 +3,11 @@ module Piggybak
3
3
  has_many :shipping_method_values, :dependent => :destroy
4
4
  alias :metadata :shipping_method_values
5
5
 
6
- validates_presence_of :description
7
- validates_presence_of :klass
6
+ validates :description, presence: true
7
+ validates :klass, presence: true
8
8
 
9
9
  accepts_nested_attributes_for :shipping_method_values, :allow_destroy => true
10
10
 
11
- attr_accessible :active, :shipping_method_values_attributes, :description,
12
- :klass
13
-
14
11
  validates_each :shipping_method_values do |record, attr, value|
15
12
  if record.klass.present?
16
13
  calculator = record.klass.constantize
@@ -45,7 +42,7 @@ module Piggybak
45
42
  arr << {
46
43
  :label => "#{method.description} $#{"%.2f" % rate}",
47
44
  :id => method.id,
48
- :rate => rate }
45
+ :rate => rate.to_f }
49
46
  end
50
47
  arr
51
48
  end
@@ -1,9 +1,8 @@
1
1
  module Piggybak
2
2
  class ShippingMethodValue < ActiveRecord::Base
3
3
  belongs_to :shipping_method
4
- validates_presence_of :key
5
- validates_presence_of :value
6
- attr_accessible :key, :value, :shipping_method_id
4
+ validates :key, presence: true
5
+ validates :value, presence: true
7
6
 
8
7
  def admin_label
9
8
  "#{self.key} - #{self.value}"
@@ -1,6 +1,5 @@
1
1
  module Piggybak
2
2
  class State < ActiveRecord::Base
3
- attr_accessible :name, :abbr, :country
4
3
  belongs_to :country
5
4
  end
6
5
  end
@@ -5,15 +5,11 @@ module Piggybak
5
5
  def self.available?(method, object)
6
6
  id = method.metadata.detect { |t| t.key == "state_id" }.value
7
7
 
8
- if object.is_a?(Cart)
9
- if object.extra_data[:state_id] != ""
10
- state = State.find(object.extra_data[:state_id])
11
- return state.id == id.to_i if state
12
- end
13
- else
14
- if object.billing_address && object.billing_address.state
15
- return object.billing_address.state.id == id.to_i
16
- end
8
+ if object.is_a?(Cart) && object.extra_data.has_key?(:state_id) && object.extra_data[:state_id] != ''
9
+ state = State.find(object.extra_data[:state_id])
10
+ return state.id == id.to_i if state
11
+ elsif object.is_a?(Order) && object.billing_address && object.billing_address.state
12
+ return object.billing_address.state.id == id.to_i
17
13
  end
18
14
  return false
19
15
  end
@@ -29,7 +25,7 @@ module Piggybak
29
25
  else
30
26
  taxable_total += object.extra_data[:reduce_tax_subtotal].to_f
31
27
  end
32
- (method.metadata.detect { |m| m.key == "rate" }.value.to_f * taxable_total).to_c
28
+ method.metadata.detect { |m| m.key == "rate" }.value.to_f * taxable_total
33
29
  end
34
30
  end
35
31
  end
@@ -3,12 +3,11 @@ module Piggybak
3
3
  has_many :tax_method_values, :dependent => :destroy
4
4
  alias :metadata :tax_method_values
5
5
 
6
- validates_presence_of :description
7
- validates_presence_of :klass
6
+ validates :description, presence: true
7
+ validates :klass, presence: true
8
8
 
9
9
  accepts_nested_attributes_for :tax_method_values, :allow_destroy => true
10
- attr_accessible :active, :tax_method_values_attributes, :description,
11
- :klass
10
+
12
11
  validates_each :tax_method_values do |record, attr, value|
13
12
  if record.klass.present?
14
13
  calculator = record.klass.constantize
@@ -36,8 +35,8 @@ module Piggybak
36
35
  total_tax += calculator.rate(tax_method, object)
37
36
  end
38
37
  end
39
-
40
- total_tax
38
+
39
+ ((100*total_tax.to_f).to_i).to_f/(100.to_f)
41
40
  end
42
41
 
43
42
  def admin_label
@@ -1,9 +1,8 @@
1
1
  module Piggybak
2
2
  class TaxMethodValue < ActiveRecord::Base
3
3
  belongs_to :tax_method
4
- validates_presence_of :key
5
- validates_presence_of :value
6
- attr_accessible :key, :value, :tax_method_id
4
+ validates :key, presence: true
5
+ validates :value, presence: true
7
6
 
8
7
  def admin_label
9
8
  "#{self.key} - #{self.value}"
@@ -4,11 +4,11 @@
4
4
  <% if current_user -%>
5
5
  <%= f.label :email %>
6
6
  <%= f.text_field :email, { :readonly => true, :class => "readonly required" } %>
7
- <span>or <%= link_to 'LOGOUT', destroy_user_session_path, :method => :delete, :class => "last" %></span>
7
+ <span>or <%= link_to 'LOGOUT', main_app.destroy_user_session_path, :method => :delete, :class => "last" %></span>
8
8
  <% else -%>
9
9
  <%= f.label :email %>
10
10
  <%= f.text_field :email, :class => "required" %><br />
11
- <span>or <%= link_to 'LOG IN', new_user_session_path %></span>
11
+ <span>or <%= link_to 'LOG IN', main_app.new_user_session_path %></span>
12
12
  <% end -%>
13
13
  </div>
14
14
  <div class="item">
@@ -1,12 +1,10 @@
1
1
  :ruby
2
2
  type = form.object.is_shipping ? "shipping" : "billing"
3
3
 
4
- = form.collection_select "country_id", Piggybak::Country.send(type), :id, :name, { :selected => form.object.country_id.to_s }
5
-
6
4
  - if form.object.country.states.any?
7
- = form.collection_select "state_id", form.object.country.states, :id, :name, { :selected => form.object.state_id.to_s }
5
+ = select_tag "#{type}_state_id", options_from_collection_for_select(form.object.country.states, "id", "name") #.collect { |s| [s.name, s.id] } #, :id, :name, { :selected => form.object.state_id.to_s }
8
6
  - else
9
- = form.text_field "state_id"
7
+ = text_field "#{type}_state_id"
10
8
 
11
9
  :javascript
12
10
  var geodata_lookup = "#{piggybak.orders_geodata_url}";
@@ -1,29 +1,5 @@
1
1
  - if form.object.new_record?
2
- = form.select "line_item_type", Piggybak::LineItem.line_item_type_select, {}, :onchange => "toggle_line_item($(this));"
2
+ = form.select "line_item_type", Piggybak::LineItem.line_item_type_select, {}, :onchange => "piggybak_rails_admin.toggle_line_item($(this));"
3
3
  - else
4
4
  = form.hidden_field "line_item_type"
5
5
  = form.object.line_item_type
6
-
7
- %script
8
- var line_item_types=#{raw Piggybak.config.line_item_types.to_json};
9
- var toggle_line_item = function(el) {
10
- el.parent().parent().siblings('div').hide();
11
- if(line_item_types[el.val()].fields === undefined) {
12
- line_item_types[el.val()].fields = new Array();
13
- }
14
- $.each(line_item_types[el.val()].fields, function(a, b) {
15
- el.parent().parent().siblings('.' + b + '_field').show();
16
- if(line_item_types[el.val()].nested_attrs !== undefined) {
17
- el.parent().parent().siblings('.' + b + '_field').find('> .controls,> .control-label').hide();
18
- }
19
- });
20
- };
21
- $.each($('.line_item_type_field select,.line_item_type_field input'), function(i, el) {
22
- toggle_line_item($(el));
23
- });
24
- //Removing delete-ability of line_item_types that can't be destroyed
25
- $.each($('.line_item_type_field input'), function(i, el) {
26
- if(!line_item_types[$(el).val()].allow_destroy) {
27
- $(el).parentsUntil('fieldset').parent().parent().find('.remove_nested_fields').remove();
28
- }
29
- });