spree_price 3.1.6

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 (68) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +83 -0
  3. data/app/assets/javascripts/spree/backend/price.js.coffee +13 -0
  4. data/app/assets/javascripts/spree/backend/price_book.js.coffee +104 -0
  5. data/app/assets/javascripts/spree/backend/spree_price.js +2 -0
  6. data/app/assets/javascripts/spree/frontend/spree_price.js +2 -0
  7. data/app/assets/stylesheets/spree/backend/spree_price.css +4 -0
  8. data/app/assets/stylesheets/spree/frontend/spree_price.css +4 -0
  9. data/app/controllers/spree/admin/currency_rates_controller.rb +11 -0
  10. data/app/controllers/spree/admin/price_books_controller.rb +41 -0
  11. data/app/controllers/spree/admin/price_types_controller.rb +6 -0
  12. data/app/controllers/spree/admin/prices_controller_decorator.rb +54 -0
  13. data/app/controllers/spree/admin/stores_controller_decorator.rb +16 -0
  14. data/app/helpers/spree/base_helper_decorator.rb +32 -0
  15. data/app/models/spree/currency_rate.rb +56 -0
  16. data/app/models/spree/line_item_decorator.rb +79 -0
  17. data/app/models/spree/line_item_price.rb +4 -0
  18. data/app/models/spree/order/currency_updater_decorator.rb +9 -0
  19. data/app/models/spree/order_decorator.rb +15 -0
  20. data/app/models/spree/order_price.rb +4 -0
  21. data/app/models/spree/order_updater_decorator.rb +30 -0
  22. data/app/models/spree/price_book.rb +88 -0
  23. data/app/models/spree/price_decorator.rb +39 -0
  24. data/app/models/spree/price_type.rb +15 -0
  25. data/app/models/spree/role_decorator.rb +15 -0
  26. data/app/models/spree/role_price_book.rb +5 -0
  27. data/app/models/spree/store_decorator.rb +4 -0
  28. data/app/models/spree/store_price_book.rb +7 -0
  29. data/app/models/spree/variant_decorator.rb +43 -0
  30. data/app/overrides/spree/admin/roles/_form/add_default_checkout_to_role.html.erb.deface +9 -0
  31. data/app/overrides/spree/admin/shared/sub_menu/_configuration/current_rates_link.html.erb.deface +6 -0
  32. data/app/overrides/spree/admin/shared/sub_menu/_product/add_price_books_tab.html.erb.deface +4 -0
  33. data/app/overrides/spree/admin/stores/_form/add_price_book_to_store.html.erb.deface +49 -0
  34. data/app/views/spree/admin/currency_rates/_form.html.erb +29 -0
  35. data/app/views/spree/admin/currency_rates/edit.html.erb +19 -0
  36. data/app/views/spree/admin/currency_rates/index.html.erb +50 -0
  37. data/app/views/spree/admin/currency_rates/new.html.erb +21 -0
  38. data/app/views/spree/admin/price_books/_add_price.html.erb +82 -0
  39. data/app/views/spree/admin/price_books/_form.html.erb +81 -0
  40. data/app/views/spree/admin/price_books/_price.html.erb +12 -0
  41. data/app/views/spree/admin/price_books/_price_book.html.erb +16 -0
  42. data/app/views/spree/admin/price_books/_price_list.html.erb +37 -0
  43. data/app/views/spree/admin/price_books/edit.html.erb +21 -0
  44. data/app/views/spree/admin/price_books/index.html.erb +65 -0
  45. data/app/views/spree/admin/price_books/new.html.erb +14 -0
  46. data/app/views/spree/admin/price_books/show.html.erb +39 -0
  47. data/app/views/spree/admin/price_types/_form.html.erb +25 -0
  48. data/app/views/spree/admin/price_types/edit.html.erb +18 -0
  49. data/app/views/spree/admin/price_types/index.html.erb +51 -0
  50. data/app/views/spree/admin/price_types/new.html.erb +14 -0
  51. data/app/views/spree/admin/prices/_variant_prices.html.erb +57 -0
  52. data/app/views/spree/admin/prices/index.html.erb +39 -0
  53. data/config/locales/en.yml +34 -0
  54. data/config/locales/validates_timeliness.en.yml +16 -0
  55. data/config/routes.rb +33 -0
  56. data/db/migrate/20180828044728_add_spree_price_book.rb +52 -0
  57. data/db/migrate/20180830053207_add_price_to_order_and_line_item.rb +19 -0
  58. data/db/migrate/20180830055224_add_default_for_role.rb +7 -0
  59. data/lib/generators/spree_price/install/install_generator.rb +31 -0
  60. data/lib/spree_price.rb +7 -0
  61. data/lib/spree_price/engine.rb +20 -0
  62. data/lib/spree_price/factories.rb +5 -0
  63. data/lib/spree_price/factories/currency_rate_factory.rb +15 -0
  64. data/lib/spree_price/factories/price_book_factory.rb +34 -0
  65. data/lib/spree_price/factories/price_type_factory.rb +21 -0
  66. data/lib/spree_price/version.rb +17 -0
  67. data/lib/tasks/price.rake +58 -0
  68. metadata +362 -0
@@ -0,0 +1,14 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:new_price_book) %>
3
+ <% end %>
4
+
5
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @price_book } %>
6
+
7
+ <div id="price_book_form_wrapper">
8
+ <%= form_for [:admin, @price_book] do |f| %>
9
+ <fieldset>
10
+ <%= render :partial => 'form', :locals => { :f => f } %>
11
+ <%= render :partial => 'spree/admin/shared/new_resource_links' %>
12
+ </fieldset>
13
+ <% end %>
14
+ </div>
@@ -0,0 +1,39 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:price_book) %>
3
+ <span><%= @price_book.name %></span>
4
+ <% end %>
5
+
6
+ <% content_for :page_actions do %>
7
+ <span id="edit_pb_link">
8
+ <%= button_link_to Spree.t(:back_to_price_books_list),
9
+ spree.admin_price_books_path,
10
+ :icon => 'arrow-left'
11
+ %>
12
+ </span>
13
+ <span id="edit_pb_link">
14
+ <%= button_link_to Spree.t(:edit_price_book),
15
+ spree.edit_admin_price_book_url,
16
+ { :icon => 'edit', :id => 'edit_price_book_link' }
17
+ %>
18
+ </span>
19
+ <hr />
20
+ <span id="load_pb_link">
21
+ <%= button_link_to Spree.t(:load_missing_from_parent),
22
+ spree.load_from_parent_admin_price_book_url,
23
+ { :icon => 'cloud-download', :id => 'load_from_parent_price_book_link' } %>
24
+ </span>
25
+ <span id="force_load_pb_link">
26
+ <%= button_link_to Spree.t(:refresh_all_from_parent),
27
+ spree.load_from_parent_admin_price_book_url(force_update: true),
28
+ { :icon => 'refresh', :id => 'force_load_from_parent_price_book_link' } %>
29
+ </span>
30
+ <% end %>
31
+
32
+ <%= render 'price_book', price_book: @price_book %>
33
+ <br />
34
+
35
+ <h3><%= Spree.t(:prices) %></h3><hr />
36
+ <%= render 'price_list', prices: @prices %>
37
+
38
+ <h3><%= Spree.t(:add_or_update_variant_to_price_book) %></h3><hr />
39
+ <%= render 'add_price', price_book: @price_book %>
@@ -0,0 +1,25 @@
1
+ <div data-hook="admin_price_book_form_fields">
2
+ <div class="row">
3
+ <div class="col-md-6">
4
+ <%= f.field_container :name do %>
5
+ <%= f.label :name %> <span class="required">*</span><br />
6
+ <%= f.text_field :name, class: "form-control" %>
7
+ <%= f.error_message_on :name %>
8
+ <% end %>
9
+ </div>
10
+ <div class="col-md-6">
11
+ <%= f.field_container :code do %>
12
+ <%= f.label :code %> <span class="required">*</span><br />
13
+ <%= f.text_field :code, class: "form-control" %>
14
+ <%= f.error_message_on :code %>
15
+ <% end %>
16
+ </div>
17
+ <div class="col-md-6">
18
+ <%= f.field_container :default do %>
19
+ <%= f.label :default %> <span class="required">*</span><br />
20
+ <%= f.check_box :default, class: "form-control" %>
21
+ <%= f.error_message_on :default %>
22
+ <% end %>
23
+ </div>
24
+ </div>
25
+ </div>
@@ -0,0 +1,18 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:editing_price_type) %> <span class="green">"<%= @price_type.name %>"</span>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= button_link_to Spree.t(:back_to_price_types_list), spree.admin_price_types_path, :icon => 'icon-arrow-left' %>
7
+ <% end %>
8
+
9
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @price_type } %>
10
+
11
+ <div id="price_type_form_wrapper">
12
+ <%= form_for [:admin, @price_type] do |f| %>
13
+ <fieldset>
14
+ <%= render :partial => 'form', :locals => { :f => f } %>
15
+ <%= render :partial => 'spree/admin/shared/edit_resource_links' %>
16
+ </fieldset>
17
+ <% end %>
18
+ </div>
@@ -0,0 +1,51 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree::PriceType.model_name.human(:count => 2) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= link_to_with_icon('add',
7
+ Spree.t(:new_price_type),
8
+ new_admin_price_type_url,
9
+ { :class => 'btn btn-success', :id => 'new_price_type_link' }
10
+ )%>
11
+ <% end %>
12
+
13
+ <% if @price_types.any? %>
14
+ <table
15
+ class="table"
16
+ id="listing_price_types"
17
+ >
18
+ <colgroup>
19
+ <col style="width: 40%">
20
+ <col style="width: 20%">
21
+ <col style="width: 20%">
22
+ <col style="width: 20%">
23
+ </colgroup>
24
+ <thead>
25
+ <tr data-hook="option_header">
26
+ <th><%= Spree::PriceType.human_attribute_name(:name) %></th>
27
+ <th><%= Spree::PriceType.human_attribute_name(:code) %></th>
28
+ <th><%= Spree::PriceType.human_attribute_name(:default) %></th>
29
+ <th class="actions"></th>
30
+ </tr>
31
+ </thead>
32
+ <tbody>
33
+ <% @price_types.each do |price_type| %>
34
+ <tr class="spree_price_type">
35
+ <td class="align-center"><%= price_type.name %></td>
36
+ <td class="align-center"><%= price_type.code %></td>
37
+ <td class="align-center"><%= price_type.default? %></td>
38
+ <td class="actions">
39
+ <%= link_to_edit(price_type, :class => 'admin_edit_price_type', :no_text => true) %>
40
+ <%= link_to_delete(price_type, :no_text => true) %>
41
+ </td>
42
+ </tr>
43
+ <% end %>
44
+ </tbody>
45
+ </table>
46
+ <% else %>
47
+ <div class="col-md-12">
48
+ <%= Spree.t(:no_resource_found, resource: I18n.t(:other, scope: 'activerecord.models.spree/price_type')) %>,
49
+ <%= link_to Spree.t(:add_one), spree.new_admin_price_type_path %>!
50
+ </div>
51
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:new_price_type) %>
3
+ <% end %>
4
+
5
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @price_type } %>
6
+
7
+ <div id="price_type_form_wrapper">
8
+ <%= form_for [:admin, @price_type] do |f| %>
9
+ <fieldset>
10
+ <%= render :partial => 'form', :locals => { :f => f } %>
11
+ <%= render :partial => 'spree/admin/shared/new_resource_links' %>
12
+ </fieldset>
13
+ <% end %>
14
+ </div>
@@ -0,0 +1,57 @@
1
+ <div class="col-md-12">
2
+ <div class="panel panel-default">
3
+ <div class="panel-heading">
4
+ <h3 class="panel-title">
5
+ <span class="sku"><%= variant.sku %></span>
6
+
7
+ <span class="text-muted pull-right">
8
+ <% if variant.is_master? %>
9
+ <%= Spree.t(:master) %>
10
+ <% elsif variant.options_text.blank? %>
11
+ <%= Spree.t(:variant) %>
12
+ <% else %>
13
+ <%= variant.options_text %>
14
+ <% end %>
15
+ </span>
16
+ </h3>
17
+ </div>
18
+
19
+ <div class="panel-body no-padding-bottom">
20
+ <% supported_currencies.each do |currency| %>
21
+ <% code = currency.iso_code.upcase %>
22
+ <% price = variant.price_in_price_book(code, @store, [@role], @price_type) %>
23
+ <div class="form-group">
24
+ <div class="row">
25
+ <%= label_tag "vp[#{variant.id}][#{code}]", code, class: 'control-label col-md-2' %>
26
+ <div class="col-md-6">
27
+ <%= text_field_tag(
28
+ "vp[#{variant.id}][#{code}]",
29
+ (price && price.price ? price.display_amount.money : ''),
30
+ class: 'form-control')
31
+ %>
32
+ </div>
33
+ <div class="col-md-4">
34
+ <% if price %>
35
+ <%= link_to price.price_book.try(:name), admin_price_book_url(price.price_book) %>
36
+ <% else %>
37
+ <% default_price = variant.price_in(code, @store, [@role], @price_type) %>
38
+ <% if default_price %>
39
+ <blockquote>
40
+ <%= default_price.display_amount.to_html %>
41
+ <footer>
42
+ Ref:
43
+ <%= link_to(
44
+ default_price.price_book.try(:name),
45
+ admin_price_book_url(default_price.price_book))
46
+ %>
47
+ </footer>
48
+ </blockquote>
49
+ <% end %>
50
+ <% end %>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ <% end %>
55
+ </div>
56
+ </div>
57
+ </div>
@@ -0,0 +1,39 @@
1
+ <%= render 'spree/admin/shared/product_tabs', current: 'Prices' %>
2
+
3
+ <div class='row'>
4
+ <%= select_tag(:store, options_for_select(stores_options, selected: @store.try(:id)),
5
+ include_blank: false, multiple: false,
6
+ class: 'select2 col-md-4', id: 'select_variant_prices_store')
7
+ %>
8
+
9
+ <%= select_tag(:price_type,
10
+ options_for_select(price_types_options, selected: @price_type.try(:id)),
11
+ include_blank: false, multiple: false,
12
+ class: 'select2 col-md-4', id: 'select_variant_prices_price_type')
13
+ %>
14
+
15
+ <%= select_tag(:role,
16
+ options_for_select(roles_options, selected: @role.try(:id)),
17
+ include_blank: false, multiple: false,
18
+ class: 'select2 col-md-4', id: 'select_variant_prices_role')
19
+ %>
20
+ </div>
21
+
22
+ <div class='row'>
23
+ <%= form_tag variant_prices_admin_product_prices_url(@product) do %>
24
+ <%= render 'variant_prices', variant: @product.master %>
25
+ <% @product.variants.each do |variant| %>
26
+ <%= render 'variant_prices', variant: variant %>
27
+ <% end %>
28
+
29
+ <%= hidden_field_tag :store_id, @store.try(:id) %>
30
+ <%= hidden_field_tag :price_type_id, @price_type.try(:id) %>
31
+ <%= hidden_field_tag :role_id, @role.try(:id) %>
32
+
33
+ <div class="form-actions" data-hook="buttons">
34
+ <%= button Spree.t('actions.update'), 'update' %>
35
+ <span class="or"><%= Spree.t(:or) %></span>
36
+ <%= button_link_to Spree.t('actions.cancel'), admin_product_path(@product), icon: 'delete' %>
37
+ </div>
38
+ <% end %>
39
+ </div>
@@ -0,0 +1,34 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ activerecord:
6
+ attributes:
7
+ spree/currency_rate:
8
+ base_currency: Base Currency
9
+ currency: Currency
10
+ default: Default
11
+ exchange_rate: Exchange Rate
12
+ spree/price_book:
13
+ currency: Currency
14
+ default: Default
15
+ priority: Priority
16
+ price_adjustment_factor: Factor
17
+ errors:
18
+ models:
19
+ spree/price:
20
+ attributes:
21
+ currency:
22
+ match_price_book: Must match price book currency.
23
+ models:
24
+ spree/currency_rate:
25
+ one: Currency Rate
26
+ other: Currency Rates
27
+ spree/price_book:
28
+ one: Price Book
29
+ other: Price Books
30
+ spree:
31
+ notice_messages:
32
+ currency_rate_fetched: "Currency rate updated."
33
+ price_book_loaded_from_parent: "Price book loaded from parent."
34
+ variant_price_updated: "Variant prices updated."
@@ -0,0 +1,16 @@
1
+ en:
2
+ errors:
3
+ messages:
4
+ invalid_date: "is not a valid date"
5
+ invalid_time: "is not a valid time"
6
+ invalid_datetime: "is not a valid datetime"
7
+ is_at: "must be at %{restriction}"
8
+ before: "must be before %{restriction}"
9
+ on_or_before: "must be on or before %{restriction}"
10
+ after: "must be after %{restriction}"
11
+ on_or_after: "must be on or after %{restriction}"
12
+ validates_timeliness:
13
+ error_value_formats:
14
+ date: '%Y-%m-%d'
15
+ time: '%H:%M:%S'
16
+ datetime: '%Y-%m-%d %H:%M:%S'
@@ -0,0 +1,33 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ namespace :admin do
3
+ resources :currency_rates do
4
+ collection do
5
+ get :fetch
6
+ end
7
+ end
8
+
9
+ resources :price_books do
10
+ member do
11
+ patch :update_price
12
+ patch :add_price
13
+ get :load_from_parent
14
+ end
15
+ end
16
+
17
+ resources :price_types
18
+
19
+ resources :stores do
20
+ member do
21
+ post :update_price_book_positions
22
+ end
23
+ end
24
+
25
+ resources :products do
26
+ resources :prices do
27
+ collection do
28
+ post :variant_prices
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,52 @@
1
+ class AddSpreePriceBook < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_price_books do |t|
4
+ t.datetime :active_from
5
+ t.datetime :active_to
6
+ t.string :currency, index: true
7
+ t.string :name
8
+ t.float :price_adjustment_factor
9
+ t.integer :lft, index: true
10
+ t.integer :rgt, index: true
11
+ t.integer :depth, index: true
12
+ t.references :parent, index: true, references: :spree_price_books
13
+ t.belongs_to :price_type, index: true
14
+
15
+ t.timestamps
16
+ end
17
+
18
+ add_reference :spree_prices, :price_book, index: true
19
+ add_index :spree_prices, [:variant_id, :price_book_id]
20
+
21
+ create_table :spree_store_price_books do |t|
22
+ t.belongs_to :price_book, index: true
23
+ t.belongs_to :store, index: true
24
+ t.integer :priority, default: 0, null: false, index: true
25
+
26
+ t.timestamps
27
+ end
28
+
29
+ create_table :spree_role_price_books do |t|
30
+ t.belongs_to :price_book, index: true
31
+ t.belongs_to :role, index: true
32
+
33
+ t.timestamps
34
+ end
35
+
36
+ create_table :spree_currency_rates do |t|
37
+ t.string :base_currency
38
+ t.string :currency
39
+ t.boolean :default, null: false, default: false, index: true
40
+ t.float :exchange_rate
41
+ t.timestamps
42
+ end
43
+
44
+ create_table :spree_price_types do |t|
45
+ t.string :name
46
+ t.string :code
47
+ t.integer :priority, default: 0, null: false, index: true
48
+
49
+ t.timestamps
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,19 @@
1
+ class AddPriceToOrderAndLineItem < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_order_prices do |t|
4
+ t.belongs_to :order, index: true
5
+ t.belongs_to :price_type, index: true
6
+ t.decimal :amount, :precision => 8, :scale => 2, :null => false
7
+
8
+ t.timestamps
9
+ end
10
+
11
+ create_table :spree_line_item_prices do |t|
12
+ t.belongs_to :line_item, index: true
13
+ t.belongs_to :price_type, index: true
14
+ t.decimal :amount, :precision => 8, :scale => 2, :null => false
15
+
16
+ t.timestamps
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ class AddDefaultForRole < ActiveRecord::Migration
2
+ def change
3
+ remove_column :spree_price_types, :priority, :number
4
+ add_column :spree_price_types, :default, :boolean, default: false, null: false
5
+ add_column :spree_roles, :default, :boolean, default: false, null: false
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ module SpreePrice
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ class_option :auto_run_migrations, type: :boolean, default: false
6
+
7
+ def add_javascripts
8
+ append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/spree_price\n"
9
+ append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/spree_price\n"
10
+ end
11
+
12
+ def add_stylesheets
13
+ inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/spree_price\n", before: /\*\//, verbose: true
14
+ inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/spree_price\n", before: /\*\//, verbose: true
15
+ end
16
+
17
+ def add_migrations
18
+ run 'bundle exec rake railties:install:migrations FROM=spree_price'
19
+ end
20
+
21
+ def run_migrations
22
+ run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]')
23
+ if run_migrations
24
+ run 'bundle exec rake db:migrate'
25
+ else
26
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end