spree_price 3.1.6

Sign up to get free protection for your applications and to get access to all the features.
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