multi_currencies 1.0.0

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