multi_currencies 1.0.0

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.
data/LICENSE ADDED
File without changes
data/README.md ADDED
@@ -0,0 +1,13 @@
1
+ MultiCurrencies
2
+ ===============
3
+
4
+ Introduction goes here.
5
+
6
+
7
+ Example
8
+ =======
9
+
10
+ Example goes here.
11
+
12
+
13
+ Copyright (c) 2010 [name of extension creator], released under the New BSD License
@@ -0,0 +1,6 @@
1
+ class Admin::CurrenciesController < Admin::BaseController
2
+ resource_controller
3
+ update.wants.html { redirect_to collection_url }
4
+ create.wants.html { redirect_to collection_url }
5
+ destroy.wants.html { redirect_to collection_url }
6
+ end
@@ -0,0 +1,10 @@
1
+ class Admin::CurrencyConvertersController < Admin::BaseController
2
+ resource_controller
3
+ update.wants.html { redirect_to collection_url }
4
+ create.wants.html { redirect_to collection_url }
5
+ destroy.wants.html { redirect_to collection_url }
6
+ private
7
+ def collection
8
+ @collection = CurrencyConverter.all.paginate :per_page => 15, :page => params[:page]
9
+ end
10
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::CurrenciesHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::CurrencyConvertersHelper
2
+ end
@@ -0,0 +1,43 @@
1
+ class Currency < ActiveRecord::Base
2
+ has_many :currency_converters
3
+ class << self
4
+ # Текущая валюта определенная по текущей локали
5
+ def current(_locale=I18n.locale)
6
+ find_by_locale(_locale.to_s)
7
+ end
8
+
9
+ # Конвертируем сумму к валюте текущей локале
10
+ # Если валюта или локаль не найдена то возвращается та же сумма
11
+ #
12
+ def conversion_to_current(price, options = { })
13
+ _locale = options[:locale] || I18n.locale
14
+ _date = options[:date] || Time.now
15
+ return price if current(_locale).nil? || current(_locale).basic?
16
+ current_currency = current(_locale).currency_converters.last(:conditions => ["date_req <= ?", _date])
17
+ return price if current_currency.blank?
18
+ (price / current_currency.value.to_f) * current_currency.nominal.to_i
19
+ end
20
+
21
+ # Конвертируем значение из валюты текущей локали к основной валюте
22
+ # в параметрах можно указать локаль из которой можно делать конвертацияю :locale
23
+ # и дату курса :date, курс берется последний найденный до указанной даты
24
+ #
25
+ def conversion_from_current(value, options={})
26
+ _locale = options[:locale] || I18n.locale
27
+ _date = options[:date] || Time.now
28
+ return value if current(_locale).nil? || current(_locale).basic?
29
+ current_currency = current(_locale).currency_converters.last(:conditions => ["date_req <= ?", _date])
30
+ return value if current_currency.blank?
31
+ return (value/current_currency.nominal.to_f)*current_currency.value
32
+ end
33
+
34
+ # Основная валюта
35
+ def basic
36
+ first(:conditions => { :basic => true })
37
+ end
38
+
39
+ def get(num_code, options ={ })
40
+ find_by_num_code(num_code) || create(options)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,9 @@
1
+ class CurrencyConverter < ActiveRecord::Base
2
+ belongs_to :currency
3
+ default_scope :order => "currency_converters.date_req ASC"
4
+ class << self
5
+ def add(currency, date, value, nominal)
6
+ create({ :nominal => nominal, :value => value, :date_req => date, :currency => currency})
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,40 @@
1
+ <table>
2
+ <tr>
3
+ <td><%= t("currency_name") %>: </td>
4
+ <td>
5
+ <%= error_message_on :currency, :name %>
6
+ <%= f.text_field :name %>
7
+ </td>
8
+ </tr>
9
+ <tr>
10
+ <td><%= t("currency_num_code") %>: </td>
11
+ <td>
12
+ <%= error_message_on :currency, :num_code %>
13
+ <%= f.text_field :num_code %>
14
+ </td>
15
+ </tr>
16
+ <tr>
17
+ <td><%= t("currency_char_code") %>: </td>
18
+ <td>
19
+ <%= error_message_on :currency, :char_code %>
20
+ <%= f.text_field :char_code %>
21
+ </td>
22
+ </tr>
23
+
24
+ <tr>
25
+ <td><%= t("currency_basic") %>: </td>
26
+ <td>
27
+ <%= error_message_on :currency, :basic %>
28
+ <%= f.check_box :basic %>
29
+ </td>
30
+ </tr>
31
+ <tr>
32
+ <td><%= t("currency_locale") %>: </td>
33
+ <td>
34
+ <%= error_message_on :currency, :locale %>
35
+ <%= f.select :locale, I18n.available_locales.map{|x| [x,x] } %>
36
+ </td>
37
+ </tr>
38
+
39
+ </table>
40
+
@@ -0,0 +1,8 @@
1
+ <h1><%= t("editing_currency") %></h1>
2
+ <% form_for(:currency, :url => object_url, :html => { :method => :put }) do |f| %>
3
+ <%= render :partial => "form", :locals => { :f => f } %>
4
+ <p class="form-buttons">
5
+ <%= button t("update") %>
6
+ <%= link_to t('cancel'), collection_url %>
7
+ </p>
8
+ <% end -%>
@@ -0,0 +1,40 @@
1
+ <div class='toolbar'>
2
+ <ul class='actions'>
3
+ <li>
4
+ <p><%= button_link_to t("add_currency"), new_object_url, :icon => 'add' %></p>
5
+ </li>
6
+ </ul>
7
+ <br class='clear' />
8
+ </div>
9
+ <h1><%= t("list_currency") %></h1>
10
+
11
+ <table class="index">
12
+ <thead>
13
+ <tr>
14
+ <th><%= t("currency_name")%></th>
15
+ <th><%= t("currency_code")%></th>
16
+ <th><%= t("currency_locale")%></th>
17
+ <th><%= t("currency_basic")%></th>
18
+ <th><%= t("action") %></th>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <% collection.each do |currency|%>
23
+ <tr id="<%= dom_id currency %>">
24
+ <td width="350px"><%= currency.name %></td>
25
+ <td>
26
+ <%= currency.num_code %> - <%= currency.char_code %>
27
+ </td>
28
+ <td> <%= currency.locale %></td>
29
+ <td> <%= currency.basic %></td>
30
+ <td>
31
+ <%= link_to_edit currency %> &nbsp;
32
+ <%= link_to_delete currency %> &nbsp;
33
+ </td>
34
+ </tr>
35
+ <% end %>
36
+ </tbody>
37
+ </table>
38
+
39
+ <%#= will_paginate(:prev => "&#171; #{t('previous')}", :next => "#{t('next')} &#187;") %>
40
+
@@ -0,0 +1,10 @@
1
+ <h1><%= t("new_currency") %></h1>
2
+ <% form_for(:currency, :url => collection_url) do |f| %>
3
+ <%= render :partial => "form", :locals => { :f => f } %>
4
+ <p class="form-buttons">
5
+ <%= button t("create") %>
6
+ <%= link_to t('cancel'), collection_url %>
7
+ </p>
8
+ <% end -%>
9
+
10
+
@@ -0,0 +1,35 @@
1
+ <table>
2
+ <tr>
3
+ <td><%= t("currency_converter_currency") %>: </td>
4
+ <td>
5
+ <%= error_message_on :currency_converter, :currency_id %>
6
+ <%= f.select :currency_id, Currency.all.map{|x| [x.name, x.id]} %>
7
+ </td>
8
+ </tr>
9
+
10
+ <tr>
11
+ <td><%= t("currency_converter_date_req") %>: </td>
12
+ <td>
13
+ <%= error_message_on :currency_converter, :date_req %>
14
+ <%= f.datetime_select :date_req %>
15
+ </td>
16
+ </tr>
17
+
18
+ <tr>
19
+ <td><%= t("currency_converter_nominal") %>: </td>
20
+ <td>
21
+ <%= error_message_on :currency_converter, :nominal %>
22
+ <%= f.text_field :nominal %>
23
+ </td>
24
+ </tr>
25
+
26
+ <tr>
27
+ <td><%= t("currency_converter_value") %>: </td>
28
+ <td>
29
+ <%= error_message_on :currency_converter, :value %>
30
+ <%= f.text_field :value %>
31
+ </td>
32
+ </tr>
33
+
34
+ </table>
35
+
@@ -0,0 +1,8 @@
1
+ <h1><%= t("editing_currency_converter") %></h1>
2
+ <% form_for(:currency_converter, :url => object_url, :html => { :method => :put }) do |f| %>
3
+ <%= render :partial => "form", :locals => { :f => f } %>
4
+ <p class="form-buttons">
5
+ <%= button t("update") %>
6
+ <%= link_to t('cancel'), collection_url %>
7
+ </p>
8
+ <% end -%>
@@ -0,0 +1,38 @@
1
+ <div class='toolbar'>
2
+ <ul class='actions'>
3
+ <li>
4
+ <p><%= button_link_to t("add_currency_converter"), new_object_url, :icon => 'add' %></p>
5
+ </li>
6
+ </ul>
7
+ <br class='clear' />
8
+ </div>
9
+ <h1><%= t("currency_converter") %></h1>
10
+
11
+ <table class="index">
12
+ <thead>
13
+ <tr>
14
+ <th><%= t("currency_converter_date_req") %></th>
15
+ <th><%= t("currency_converter_currency") %></th>
16
+ <th><%= t("currency_converter_nominal") %></th>
17
+ <th><%= t("currency_converter_value") %></th>
18
+ <th><%= t("action") %></th>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <% collection.each do |currency_converter|%>
23
+ <tr id="<%= dom_id currency_converter %>">
24
+ <td><%= currency_converter.date_req %></td>
25
+ <td width="350px"><%= currency_converter.currency.try(:name) %></td>
26
+ <td><%= currency_converter.nominal %></td>
27
+ <td><%= currency_converter.value %></td>
28
+ <td>
29
+ <%= link_to_edit currency_converter %> &nbsp;
30
+ <%= link_to_delete currency_converter %> &nbsp;
31
+ </td>
32
+ </tr>
33
+ <% end %>
34
+ </tbody>
35
+ </table>
36
+
37
+ <%= will_paginate(:prev => "&#171; #{t('previous')}", :next => "#{t('next')} &#187;") %>
38
+
@@ -0,0 +1,10 @@
1
+ <h1><%= t("new_currency_converter") %></h1>
2
+ <% form_for(:currency_converter, :url => collection_url) do |f| %>
3
+ <%= render :partial => "form", :locals => { :f => f } %>
4
+ <p class="form-buttons">
5
+ <%= button t("create") %>
6
+ <%= link_to t('cancel'), collection_url %>
7
+ </p>
8
+ <% end -%>
9
+
10
+
@@ -0,0 +1,74 @@
1
+ require 'spree_core'
2
+ require 'multi_currencies_hooks'
3
+
4
+ module MultiCurrencies
5
+ class Engine < Rails::Engine
6
+
7
+ config.autoload_paths += %W(#{config.root}/lib)
8
+
9
+ def self.activate
10
+ Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c|
11
+ Rails.env.production? ? require(c) : load(c)
12
+ end
13
+ Variant.class_eval do
14
+
15
+ def price
16
+ Currency.conversion_to_current(read_attribute(:price))
17
+ end
18
+
19
+ def price=(value)
20
+ conversion_value = Currency.conversion_from_current(value)
21
+ write_attribute(:price, conversion_value)
22
+ end
23
+
24
+ end
25
+
26
+
27
+
28
+ Order.class_eval do
29
+ def total
30
+ Currency.conversion_to_current(read_attribute(:total))
31
+ end
32
+
33
+ def total=(value)
34
+ conversion_value = Currency.conversion_from_current(value)
35
+ write_attribute(:total, conversion_value)
36
+ end
37
+
38
+ def item_total
39
+ Currency.conversion_to_current(read_attribute(:item_total))
40
+ end
41
+
42
+ def item_total=(value)
43
+ conversion_value = Currency.conversion_from_current(value)
44
+ write_attribute(:item_total, conversion_value)
45
+ end
46
+
47
+ def credit_total
48
+ Currency.conversion_to_current(read_attribute(:credit_total))
49
+ end
50
+
51
+ def credit_total=(value)
52
+ conversion_value = Currency.conversion_from_current(value)
53
+ write_attribute(:credit_total, conversion_value)
54
+ end
55
+
56
+
57
+ end
58
+
59
+ LineItem.class_eval do
60
+ def price
61
+ Currency.conversion_to_current(read_attribute(:price))
62
+ end
63
+
64
+ def price=(value)
65
+ conversion_value = Currency.conversion_from_current(value)
66
+ write_attribute(:price, conversion_value)
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ config.to_prepare &method(:activate).to_proc
73
+ end
74
+ end
@@ -0,0 +1,18 @@
1
+ class MultiCurrenciesHooks < Spree::ThemeSupport::HookListener
2
+ # custom hooks go here
3
+ insert_after :admin_configurations_menu do
4
+ %(
5
+ <% if current_user.has_role?(:admin) %>
6
+ <tr>
7
+ <td><%= link_to t("currency_settings"), admin_currencies_path %></td>
8
+ <td><%= t("currency_description") %></td>
9
+ </tr>
10
+ <tr>
11
+ <td><%= link_to t("currency_converters_settings"), admin_currency_converters_path %></td>
12
+ <td><%= t("currency_converters_description") %></td>
13
+ </tr>
14
+
15
+ <% end %>
16
+ )
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ namespace :multi_currencies do
2
+ desc "Copies all migrations and assets (NOTE: This will be obsolete with Rails 3.1)"
3
+ task :install do
4
+ Rake::Task['multi_currencies:install:migrations'].invoke
5
+ Rake::Task['multi_currencies:install:assets'].invoke
6
+ end
7
+
8
+ namespace :install do
9
+ desc "Copies all migrations (NOTE: This will be obsolete with Rails 3.1)"
10
+ task :migrations do
11
+ source = File.join(File.dirname(__FILE__), '..', '..', 'db')
12
+ destination = File.join(Rails.root, 'db')
13
+ puts "INFO: Mirroring assets from #{source} to #{destination}"
14
+ Spree::FileUtilz.mirror_files(source, destination)
15
+ end
16
+
17
+ desc "Copies all assets (NOTE: This will be obsolete with Rails 3.1)"
18
+ task :assets do
19
+ source = File.join(File.dirname(__FILE__), '..', '..', 'public')
20
+ destination = File.join(Rails.root, 'public')
21
+ puts "INFO: Mirroring assets from #{source} to #{destination}"
22
+ Spree::FileUtilz.mirror_files(source, destination)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,20 @@
1
+ # add custom rake tasks here
2
+ namespace :multi_currencies do
3
+ desc "Получение валют Сбербанк РФ"
4
+ task :currency_sb => :environment do
5
+ require 'open-uri'
6
+ doc = Nokogiri::XML.parse(open("http://www.cbr.ru/scripts/XML_daily.asp?date_req=#{Time.now.strftime('%d/%m/%Y')}"))
7
+ date = Date.strptime(doc.xpath("//ValCurs").attr("Date").to_s, '%d/%m/%Y')
8
+ doc.xpath("//ValCurs/Valute").each do |valute|
9
+ char_code = valute.xpath("./CharCode").text.to_s
10
+ num_code = valute.xpath("./NumCode").text.to_s
11
+
12
+ name = valute.xpath("./Name").text.to_s
13
+ value = valute.xpath("./Value").text.gsub(',','.').to_f
14
+ nominal = valute.xpath("./Nominal").text
15
+ currency = Currency.get(num_code, { :num_code => num_code, :char_code => char_code, :name => name})
16
+ currency && CurrencyConverter.add(currency, date, value, nominal)
17
+ end
18
+ end
19
+
20
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: multi_currencies
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors: []
13
+
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-14 00:00:00 +03:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: spree_core
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 103
30
+ segments:
31
+ - 0
32
+ - 30
33
+ - 0
34
+ version: 0.30.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: nokogiri
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 113
46
+ segments:
47
+ - 1
48
+ - 4
49
+ - 3
50
+ - 1
51
+ version: 1.4.3.1
52
+ type: :runtime
53
+ version_requirements: *id002
54
+ description:
55
+ email:
56
+ executables: []
57
+
58
+ extensions: []
59
+
60
+ extra_rdoc_files: []
61
+
62
+ files:
63
+ - README.md
64
+ - LICENSE
65
+ - lib/multi_currencies_hooks.rb
66
+ - lib/multi_currencies.rb
67
+ - lib/tasks/multi_currencies.rake
68
+ - lib/tasks/install.rake
69
+ - app/helpers/admin/currencies_helper.rb
70
+ - app/helpers/admin/currency_converters_helper.rb
71
+ - app/models/currency.rb
72
+ - app/models/currency_converter.rb
73
+ - app/views/admin/currencies/edit.html.erb
74
+ - app/views/admin/currencies/index.html.erb
75
+ - app/views/admin/currencies/_form.html.erb
76
+ - app/views/admin/currencies/new.html.erb
77
+ - app/views/admin/currency_converters/edit.html.erb
78
+ - app/views/admin/currency_converters/index.html.erb
79
+ - app/views/admin/currency_converters/_form.html.erb
80
+ - app/views/admin/currency_converters/new.html.erb
81
+ - app/controllers/admin/currency_converters_controller.rb
82
+ - app/controllers/admin/currencies_controller.rb
83
+ has_rdoc: true
84
+ homepage:
85
+ licenses: []
86
+
87
+ post_install_message:
88
+ rdoc_options: []
89
+
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ hash: 57
98
+ segments:
99
+ - 1
100
+ - 8
101
+ - 7
102
+ version: 1.8.7
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ requirements:
113
+ - none
114
+ rubyforge_project:
115
+ rubygems_version: 1.3.7
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Add gem summary here
119
+ test_files: []
120
+