solidus_volume_pricing 0.2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +35 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +8 -4
  5. data/.rubocop_todo.yml +126 -0
  6. data/CHANGELOG.md +57 -0
  7. data/Gemfile +18 -4
  8. data/Guardfile +3 -1
  9. data/README.md +53 -48
  10. data/Rakefile +2 -0
  11. data/app/assets/javascripts/spree/backend/solidus_volume_pricing.js +1 -15
  12. data/app/controllers/spree/admin/volume_price_models_controller.rb +2 -1
  13. data/app/controllers/spree/admin/volume_prices_controller.rb +3 -1
  14. data/app/decorators/controllers/solidus_volume_pricing/spree/admin/variants_controller_decorator.rb +42 -0
  15. data/app/decorators/helpers/solidus_volume_pricing/spree/base_helper_decorator.rb +31 -0
  16. data/app/decorators/models/solidus_volume_pricing/spree/line_item_decorator.rb +18 -0
  17. data/app/decorators/models/solidus_volume_pricing/spree/user_decorator.rb +17 -0
  18. data/app/decorators/models/solidus_volume_pricing/spree/variant_decorator.rb +21 -0
  19. data/app/models/solidus_volume_pricing/price_display.rb +47 -0
  20. data/app/models/solidus_volume_pricing/pricer.rb +95 -0
  21. data/app/models/solidus_volume_pricing/pricing_options.rb +20 -0
  22. data/app/models/spree/volume_price.rb +43 -26
  23. data/app/models/spree/volume_price_model.rb +6 -4
  24. data/app/overrides/spree/admin/shared/_settings_sub_menu/add_volume_price_model_admin_menu_links.html.erb.deface +5 -0
  25. data/app/overrides/views_decorator.rb +2 -0
  26. data/app/views/spree/admin/shared/_vp_product_tab.html.erb +2 -2
  27. data/app/views/spree/admin/variants/_edit_fields.html.erb +5 -32
  28. data/app/views/spree/admin/variants/volume_prices.html.erb +9 -36
  29. data/app/views/spree/admin/volume_price_models/_form.html.erb +6 -2
  30. data/app/views/spree/admin/volume_price_models/_list.html.erb +8 -4
  31. data/app/views/spree/admin/volume_price_models/_select.html.erb +17 -0
  32. data/app/views/spree/admin/volume_price_models/edit.html.erb +7 -6
  33. data/app/views/spree/admin/volume_price_models/index.html.erb +7 -5
  34. data/app/views/spree/admin/volume_price_models/new.html.erb +5 -5
  35. data/app/views/spree/admin/volume_prices/_table.html.erb +26 -0
  36. data/app/views/spree/admin/volume_prices/_volume_price_fields.html.erb +6 -6
  37. data/app/views/spree/products/_volume_pricing.html.erb +8 -8
  38. data/bin/rails +3 -2
  39. data/config/locales/de.yml +17 -3
  40. data/config/locales/en.yml +21 -2
  41. data/config/locales/pt.yml +6 -2
  42. data/config/locales/ru.yml +6 -2
  43. data/config/locales/sv.yml +6 -2
  44. data/config/locales/tr.yml +6 -2
  45. data/config/routes.rb +3 -1
  46. data/db/migrate/20081119145604_create_volume_prices.rb +3 -1
  47. data/db/migrate/20110203174010_change_display_name_for_volume_prices.rb +3 -1
  48. data/db/migrate/20111206173307_prefix_volume_pricing_table_names.rb +3 -1
  49. data/db/migrate/20121115043422_add_discount_type_column.rb +3 -1
  50. data/db/migrate/20150513200904_add_role_to_volume_price.rb +3 -1
  51. data/db/migrate/20150603143015_create_spree_volume_price_models.rb +3 -1
  52. data/lib/generators/solidus_volume_pricing/install/install_generator.rb +3 -5
  53. data/lib/solidus_volume_pricing.rb +5 -1
  54. data/lib/solidus_volume_pricing/engine.rb +5 -22
  55. data/lib/solidus_volume_pricing/range_from_string.rb +36 -0
  56. data/lib/solidus_volume_pricing/version.rb +5 -3
  57. data/solidus_volume_pricing.gemspec +6 -14
  58. data/spec/controllers/spree/admin/variants_controller_spec.rb +18 -15
  59. data/spec/factories/volume_price_factory.rb +7 -5
  60. data/spec/features/manage_volume_price_models_feature_spec.rb +5 -3
  61. data/spec/features/manage_volume_prices_feature_spec.rb +6 -4
  62. data/spec/helpers/base_helper_spec.rb +3 -1
  63. data/spec/lib/solidus_volume_pricing/range_from_string_spec.rb +61 -0
  64. data/spec/models/solidus_volume_pricing/pricer_spec.rb +673 -0
  65. data/spec/models/solidus_volume_pricing/pricing_options_spec.rb +57 -0
  66. data/spec/models/spree/line_item_spec.rb +24 -21
  67. data/spec/models/spree/order_spec.rb +4 -2
  68. data/spec/models/spree/variant_spec.rb +3 -303
  69. data/spec/models/spree/volume_price_spec.rb +153 -49
  70. data/spec/spec_helper.rb +5 -38
  71. data/spec/support/shoulda.rb +11 -0
  72. metadata +37 -173
  73. data/.hound.yml +0 -40
  74. data/.travis.yml +0 -12
  75. data/CONTRIBUTING.md +0 -81
  76. data/app/controllers/spree/admin/variants_controller_decorator.rb +0 -32
  77. data/app/helpers/spree/base_helper_decorator.rb +0 -19
  78. data/app/models/spree/line_item_decorator.rb +0 -13
  79. data/app/models/spree/user_decorator.rb +0 -10
  80. data/app/models/spree/variant_decorator.rb +0 -104
  81. data/app/overrides/spree/admin/shared/sub_menu/_configuration/add_volume_price_model_admin_menu_links.html.erb.deface +0 -3
  82. data/app/views/spree/admin/volume_prices/_edit_fields.html.erb +0 -31
  83. data/spec/support/capybara.rb +0 -12
  84. data/spec/support/database_cleaner.rb +0 -21
  85. data/spec/support/factory_girl.rb +0 -7
  86. data/spec/support/spree.rb +0 -10
@@ -1,32 +0,0 @@
1
- Spree::Admin::VariantsController.class_eval do
2
-
3
- def edit
4
- @variant.volume_prices.build if @variant.volume_prices.empty?
5
- super
6
- end
7
-
8
- def volume_prices
9
- @product = @variant.product
10
- @variant.volume_prices.build if @variant.volume_prices.empty?
11
- end
12
-
13
- private
14
-
15
- # this loads the variant for the master variant volume price editing
16
- def load_resource_instance
17
- parent
18
-
19
- if new_actions.include?(params[:action].to_sym)
20
- build_resource
21
- elsif params[:id]
22
- Spree::Variant.find(params[:id])
23
- end
24
- end
25
-
26
- def location_after_save
27
- if @product.master.id == @variant.id && params[:variant].key?(:volume_prices_attributes)
28
- return volume_prices_admin_product_variant_url(@product, @variant)
29
- end
30
- super
31
- end
32
- end
@@ -1,19 +0,0 @@
1
- Spree::BaseHelper.class_eval do
2
- def display_volume_price(variant, quantity = 1, user = nil)
3
- Spree::Money.new(
4
- variant.volume_price(quantity, user),
5
- currency: Spree::Config[:currency]
6
- ).to_html
7
- end
8
-
9
- def display_volume_price_earning_percent(variant, quantity = 1, user = nil)
10
- variant.volume_price_earning_percent(quantity, user).round.to_s
11
- end
12
-
13
- def display_volume_price_earning_amount(variant, quantity = 1, user = nil)
14
- Spree::Money.new(
15
- variant.volume_price_earning_amount(quantity, user),
16
- currency: Spree::Config[:currency]
17
- ).to_html
18
- end
19
- end
@@ -1,13 +0,0 @@
1
- module Spree
2
- module LineItemPriceUpdater
3
- def set_pricing_attributes
4
- super
5
-
6
- if quantity_changed?
7
- self.price = variant.volume_price(quantity, order.user)
8
- end
9
- end
10
- end
11
- end
12
-
13
- Spree::LineItem.prepend(Spree::LineItemPriceUpdater)
@@ -1,10 +0,0 @@
1
- Spree.user_class.class_eval do
2
-
3
- def resolve_role
4
- if self.has_spree_role? Spree::Config.volume_pricing_role.to_sym
5
- return Spree::Role.find_by name: Spree::Config.volume_pricing_role
6
- else
7
- return Spree::Role.find_by name: 'user'
8
- end
9
- end
10
- end
@@ -1,104 +0,0 @@
1
- Spree::Variant.class_eval do
2
- has_and_belongs_to_many :volume_price_models
3
- has_many :volume_prices, -> { order(position: :asc) }, dependent: :destroy
4
- has_many :model_volume_prices, -> { order(position: :asc) }, class_name: 'Spree::VolumePrice', through: :volume_price_models, source: :volume_prices
5
- accepts_nested_attributes_for :volume_prices, allow_destroy: true,
6
- reject_if: proc { |volume_price|
7
- volume_price[:amount].blank? && volume_price[:range].blank?
8
- }
9
-
10
- def join_volume_prices(user = nil)
11
- table = Spree::VolumePrice.arel_table
12
-
13
- if user
14
- Spree::VolumePrice.where(
15
- (table[:variant_id].eq(id)
16
- .or(table[:volume_price_model_id].in(volume_price_models.ids)))
17
- .and(table[:role_id].eq(user.resolve_role))
18
- )
19
- .order(position: :asc)
20
- else
21
- Spree::VolumePrice.where(
22
- (table[:variant_id]
23
- .eq(id)
24
- .or(table[:volume_price_model_id].in(volume_price_models.ids)))
25
- .and(table[:role_id].eq(nil))
26
- ).order(position: :asc)
27
- end
28
- end
29
-
30
- # calculates the price based on quantity
31
- def volume_price(quantity, user = nil)
32
- compute_volume_price_quantities :volume_price, price, quantity, user
33
- end
34
-
35
- # return percent of earning
36
- def volume_price_earning_percent(quantity, user = nil)
37
- compute_volume_price_quantities :volume_price_earning_percent, 0, quantity, user
38
- end
39
-
40
- # return amount of earning
41
- def volume_price_earning_amount(quantity, user = nil)
42
- compute_volume_price_quantities :volume_price_earning_amount, 0, quantity, user
43
- end
44
-
45
- protected
46
-
47
- def use_master_variant_volume_pricing?
48
- Spree::Config.use_master_variant_volume_pricing && !(product.master.join_volume_prices.count == 0)
49
- end
50
-
51
- def compute_volume_price_quantities(type, default_price, quantity, user)
52
- volume_prices = join_volume_prices user
53
- if volume_prices.count == 0
54
- if use_master_variant_volume_pricing?
55
- product.master.send(type, quantity, user)
56
- else
57
- return default_price
58
- end
59
- else
60
- volume_prices.each do |volume_price|
61
- if volume_price.include?(quantity)
62
- return send "compute_#{type}".to_sym, volume_price
63
- end
64
- end
65
-
66
- # No price ranges matched.
67
- default_price
68
- end
69
- end
70
-
71
- def compute_volume_price(volume_price)
72
- case volume_price.discount_type
73
- when 'price'
74
- return volume_price.amount
75
- when 'dollar'
76
- return price - volume_price.amount
77
- when 'percent'
78
- return price * (1 - volume_price.amount)
79
- end
80
- end
81
-
82
- def compute_volume_price_earning_percent(volume_price)
83
- case volume_price.discount_type
84
- when 'price'
85
- diff = price - volume_price.amount
86
- return (diff * 100 / price).round
87
- when 'dollar'
88
- return (volume_price.amount * 100 / price).round
89
- when 'percent'
90
- return (volume_price.amount * 100).round
91
- end
92
- end
93
-
94
- def compute_volume_price_earning_amount(volume_price)
95
- case volume_price.discount_type
96
- when 'price'
97
- return price - volume_price.amount
98
- when 'dollar'
99
- return volume_price.amount
100
- when 'percent'
101
- return price - (price * (1 - volume_price.amount))
102
- end
103
- end
104
- end
@@ -1,3 +0,0 @@
1
- <!-- insert_bottom "[data-hook='admin_configurations_sidebar_menu'], #admin_configurations_sidebar_menu[data-hook]" -->
2
-
3
- <%= configurations_sidebar_menu_item Spree.t('volume_price_models'), admin_volume_price_models_path if can? :admin, Spree::VolumePriceModel %>
@@ -1,31 +0,0 @@
1
- <% content_for :page_actions do %>
2
- <span id="new_add_volume_price" data-hook>
3
- <%= button_link_to Spree.t(:add_volume_price), 'javascript:;', {
4
- icon: 'add',
5
- :'data-target' => 'tbody#volume_prices',
6
- class: 'btn-success spree_add_fields',
7
- id: 'add_volume_price'
8
- } %>
9
- </span>
10
- <% end %>
11
-
12
- <h3><%= Spree.t(:volume_prices) %></h3>
13
- <table class="table">
14
- <thead>
15
- <tr>
16
- <th><%= Spree.t(:name) %></th>
17
- <th><%= Spree.t(:discount_type) %></th>
18
- <th><%= Spree.t(:range) %></th>
19
- <th><%= Spree.t(:amount) %></th>
20
- <th><%= Spree.t(:position) %></th>
21
- <th><%= Spree.t(:role) %></th>
22
- <th class="actions"></th>
23
- </tr>
24
- </thead>
25
- <tbody id="volume_prices">
26
- <%= f.fields_for :volume_prices do |vp_form| %>
27
- <%= render partial: 'spree/admin/volume_prices/volume_price_fields', locals: { f: vp_form } %>
28
- <% end %>
29
- </tbody>
30
- </table>
31
- <br/><br/>
@@ -1,12 +0,0 @@
1
- require 'capybara'
2
- require 'capybara/rspec'
3
- require 'capybara/rails'
4
- require 'capybara/poltergeist'
5
-
6
- RSpec.configure do
7
- Capybara.javascript_driver = :poltergeist
8
-
9
- Capybara.register_driver(:poltergeist) do |app|
10
- Capybara::Poltergeist::Driver.new app, js_errors: true, timeout: 60
11
- end
12
- end
@@ -1,21 +0,0 @@
1
- require 'database_cleaner'
2
-
3
- RSpec.configure do |config|
4
-
5
- config.before :suite do
6
- DatabaseCleaner.clean_with :truncation
7
- end
8
-
9
- config.prepend_before(:each) do
10
- if RSpec.current_example.metadata[:js]
11
- DatabaseCleaner.strategy = :truncation
12
- else
13
- DatabaseCleaner.strategy = :transaction
14
- end
15
- DatabaseCleaner.start
16
- end
17
-
18
- config.append_after(:each) do
19
- DatabaseCleaner.clean
20
- end
21
- end
@@ -1,7 +0,0 @@
1
- require 'factory_girl'
2
-
3
- FactoryGirl.find_definitions
4
-
5
- RSpec.configure do |config|
6
- config.include FactoryGirl::Syntax::Methods
7
- end
@@ -1,10 +0,0 @@
1
- require 'spree/testing_support/factories'
2
- require 'spree/testing_support/controller_requests'
3
- require 'spree/testing_support/authorization_helpers'
4
- require 'spree/testing_support/url_helpers'
5
- require 'spree/testing_support/capybara_ext'
6
-
7
- RSpec.configure do |config|
8
- config.include Spree::TestingSupport::ControllerRequests, type: :controller
9
- config.include Spree::TestingSupport::UrlHelpers
10
- end