insales_api 0.0.13 → 0.1.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -0
  3. data/CHANGELOG.md +20 -0
  4. data/Gemfile +1 -1
  5. data/README.md +57 -0
  6. data/Rakefile +8 -1
  7. data/insales_api.gemspec +12 -12
  8. data/lib/insales/controller/autologin.rb +45 -0
  9. data/lib/insales/controller/base_helpers.rb +52 -0
  10. data/lib/insales/controller/installer_actions.rb +19 -0
  11. data/lib/insales/controller/session_actions.rb +39 -0
  12. data/lib/insales/controller.rb +10 -0
  13. data/lib/insales.rb +7 -0
  14. data/lib/insales_api/account.rb +1 -9
  15. data/lib/insales_api/active_resource_proxy.rb +31 -0
  16. data/lib/insales_api/app.rb +57 -38
  17. data/lib/insales_api/application_charge.rb +3 -0
  18. data/lib/insales_api/asset.rb +3 -1
  19. data/lib/insales_api/base.rb +41 -5
  20. data/lib/insales_api/category.rb +8 -2
  21. data/lib/insales_api/client.rb +3 -1
  22. data/lib/insales_api/client_group.rb +3 -0
  23. data/lib/insales_api/collect.rb +8 -2
  24. data/lib/insales_api/discount_code.rb +3 -0
  25. data/lib/insales_api/helpers/has_insales_object.rb +34 -0
  26. data/lib/insales_api/helpers/init_api.rb +98 -0
  27. data/lib/insales_api/image.rb +5 -0
  28. data/lib/insales_api/order.rb +13 -5
  29. data/lib/insales_api/order_line.rb +2 -2
  30. data/lib/insales_api/product.rb +3 -1
  31. data/lib/insales_api/product_field.rb +3 -0
  32. data/lib/insales_api/product_field_value.rb +22 -0
  33. data/lib/insales_api/property.rb +3 -0
  34. data/lib/insales_api/resource/countable.rb +9 -0
  35. data/lib/insales_api/resource/paginated.rb +26 -0
  36. data/lib/insales_api/resource/with_updated_since.rb +28 -0
  37. data/lib/insales_api/theme.rb +7 -1
  38. data/lib/insales_api/variant.rb +18 -6
  39. data/lib/insales_api/version.rb +7 -1
  40. data/lib/insales_api.rb +74 -17
  41. data/spec/lib/insales_api/active_resource_proxy_spec.rb +59 -0
  42. data/spec/lib/insales_api/app_spec.rb +67 -0
  43. data/spec/lib/insales_api_spec.rb +110 -0
  44. data/spec/spec_helper.rb +3 -4
  45. metadata +54 -20
  46. data/README +0 -32
  47. data/spec/lib/insales_app_spec.rb +0 -63
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21c7b7e853b3998b60bd9e067abc75be2837608d
4
- data.tar.gz: 1e3cdaf7a448b016227d6fc8f5b2f4a82ae48572
3
+ metadata.gz: 0874e0c3d9d031bd7c44623652e9f8d0118bbca1
4
+ data.tar.gz: d8f445c2fd2f722d03368b0cef92430f4bb338b4
5
5
  SHA512:
6
- metadata.gz: 7f62cd468de7f1da9773068404b6b715a420d68eb106b2b3a3f15a9cd18da7cc3bc6c47d3aa4bd45cd90c751c2243687958b076b0a32fcc5b99a5c25fc4c56de
7
- data.tar.gz: ac1324ae0d02fb0995752d05987f764e05cfda89afabc1c17e7ebe5ea60e6ad0f2fef0aa3338267cb2b4a3bfcb350deb537f264427091925b6347ee3eb94a9c8
6
+ metadata.gz: 106dfba38c2704be7e63243f6493d441d440a200dc9f6a39454e21ea40c765cf16d5859f8103f5305786445ced8a42014603dbd1a43c56dc67adf8bea23bdc82
7
+ data.tar.gz: de95a094d63c5e09583943e56296f3d66f2a91e37246538afb499e7aae6252a832044acb8eaf74fa16a9c97dd163752bf5862c050af4dad5bc37ec03e1b9d5ed
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.1.0
5
+ notifications:
6
+ email: false
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## 0.1.0
2
+
3
+ * Helpers
4
+ * ProductFieldValue
5
+ * Controller auth mixins
6
+ * Account inherits AR::Singleton (it breaks ::current & #update methods)
7
+ * Added wait_retry method
8
+ * Added Property resource
9
+ * Added ProductField resource
10
+ * Added ClientGroup resource
11
+
12
+ ## 0.0.14
13
+
14
+ * Added Image resource
15
+ * Fixed Variant.group_update
16
+ * Added DiscountCode resource
17
+ * Added Product.count method
18
+ * Added Order.paid? method
19
+ * Added ApplicationCharge resource
20
+
1
21
  ## 0.0.13
2
22
 
3
23
  * ActiveResource::Singleton backport.
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source 'http://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # InsalesApi gem
2
+
3
+ [![Build Status](https://secure.travis-ci.org/insales/insales_api.png?branch=master)](http://travis-ci.org/insales/insales_api)
4
+
5
+ Insales api client based on [ActiveResource](https://github.com/rails/activeresource).
6
+
7
+ Rails application example is [here](https://github.com/insales/insales_app).
8
+
9
+ ## Install
10
+
11
+ Add to Gemfile:
12
+
13
+ ```ruby
14
+ gem 'insales_api'
15
+ ```
16
+
17
+ ## Initialize
18
+
19
+ ```ruby
20
+ class MyApp < InsalesApi::App
21
+ self.api_key = 'api_key'
22
+ end
23
+
24
+ MyApp.configure_api('domain', 'password')
25
+ ```
26
+
27
+ ## Use
28
+
29
+ ```ruby
30
+ order = InsalesApi::Order.find 123
31
+
32
+ # singleton resources
33
+ account = InsalesApi::Account.find
34
+ ```
35
+
36
+ ### Handling Insales API request limit
37
+
38
+ There is a 500 requests per 5 minutes limit for Insales API. To handle this limitation gracefully, use `InsalesApi.wait_retry` method:
39
+ ```ruby
40
+ # prepare a handler for request limit case
41
+ notify_user = Proc.new do |wait_for, attempt, max_attempts, ex|
42
+ puts "API limit reached. Waiting for #{wait_for} seconds. Attempt #{attempt}/#{max_attempts}"
43
+ end
44
+
45
+ # perform 10 attempts to get products
46
+ InsalesApi.wait_retry(10, notify_user) do |x|
47
+ puts "Attempt ##{x}."
48
+ products = InsalesApi::Products.all
49
+ end
50
+ ```
51
+
52
+ If you don't need to cap the attempts number or you don't want to do any special processing, simply drop the arguments:
53
+ ```ruby
54
+ InsalesApi.wait_retry do
55
+ products = InsalesApi::Products.all # will try to get products until the limit resets
56
+ end
57
+ ```
data/Rakefile CHANGED
@@ -1 +1,8 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new do |t|
5
+ t.pattern = 'spec/**/*_spec.rb'
6
+ end
7
+
8
+ task default: :spec
data/insales_api.gemspec CHANGED
@@ -1,23 +1,23 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "insales_api/version"
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ require 'insales_api/version'
4
3
 
5
4
  Gem::Specification.new do |s|
6
- s.name = "insales_api"
7
- s.version = InsalesApi::VERSION
8
- s.authors = "InSales"
9
- s.email = "dg@insales.ru"
10
- s.homepage = "http://wiki.insales.ru/wiki/%D0%9A%D0%B0%D0%BA_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%D1%81%D1%8F_%D1%81_InSales"
5
+ s.name = 'insales_api'
6
+ s.version = InsalesApi::VERSION::STRING
7
+ s.authors = 'InSales'
8
+ s.email = 'dg@insales.ru'
9
+ s.homepage = 'https://github.com/insales/insales_api'
11
10
  s.summary = %q{Gem for accessing the InSales REST web services}
12
11
  s.description = %q{Gem for accessing the InSales REST web services}
13
12
 
14
- s.rubyforge_project = "insales_api"
13
+ s.rubyforge_project = 'insales_api'
15
14
 
16
15
  s.files = `git ls-files`.split("\n")
17
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
18
 
20
- s.add_dependency("activesupport", [">= 3.0.0"])
21
- s.add_dependency("activeresource", [">= 3.0.0"])
22
- s.add_development_dependency "rspec"
19
+ s.add_dependency('activesupport', ['>= 3.0.0'])
20
+ s.add_dependency('activeresource', ['>= 3.0.0'])
21
+ s.add_development_dependency 'rspec', '~> 2.13.0'
22
+ s.add_development_dependency 'rake', '~> 10.3'
23
23
  end
@@ -0,0 +1,45 @@
1
+ module Insales::Controller
2
+ module Autologin
3
+ protected
4
+ def insales_authenticate!
5
+ params[:domain] ||= params[:shop]
6
+ insales_logout if params[:domain].present? && params[:domain] != session[:domain]
7
+ return if insales_authenticate_from_session
8
+ store_location
9
+ account = find_account_by_request
10
+ return insales_autologin_start(account) if account
11
+ redirect_to insales_login_path
12
+ end
13
+
14
+ def insales_authenticate_from_session
15
+ data = session[:insales_session]
16
+ return unless data && data[:account_id] && data[:insales_id]
17
+ @account = account_class.where(account_id: data[:account_id]).
18
+ find_by_insales_id(data[:insales_id])
19
+ end
20
+
21
+ def insales_autologin_start(account)
22
+ app = insales_app_class.new(account.insales_domain, account.insales_password)
23
+ auth_url = app.authorization_url
24
+ session[:insales_token] = app.auth_token
25
+ session[:insales_token_data] = {
26
+ domain: account.insales_domain,
27
+ account_id: account.id,
28
+ insales_id: account.insales_id,
29
+ }
30
+ redirect_to auth_url
31
+ end
32
+
33
+ def insales_autologin_finish(token = params[:token])
34
+ if token && session[:insales_token] == token && session[:insales_token_data].is_a?(Hash)
35
+ session[:insales_session] = session[:insales_token_data]
36
+ end
37
+ session[:insales_token] = session[:insales_token_data] = nil
38
+ session[:account_id].present?
39
+ end
40
+
41
+ def insales_logout
42
+ session.delete(:insales_session)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,52 @@
1
+ module Insales::Controller
2
+ module BaseHelpers
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ class_attribute :insales_config
7
+ self.insales_config = {
8
+ account_class: '::Account',
9
+ insales_app_class: '::InsalesApi::App',
10
+ login_path: 'login_path',
11
+ success_login_path: 'account_path',
12
+ }
13
+
14
+ def account_class
15
+ @account_class ||= insales_config[:account_class].constantize
16
+ end
17
+
18
+ def insales_app_class
19
+ @insales_app_class ||= insales_config[:insales_app_class].constantize
20
+ end
21
+
22
+ def insales_login_path
23
+ send(insales_config[:login_path])
24
+ end
25
+
26
+ def insales_success_login_path
27
+ send(insales_config[:success_login_path])
28
+ end
29
+ end
30
+
31
+ protected
32
+ delegate :insales_app_class, :account_class,
33
+ :insales_login_path, :insales_success_login_path,
34
+ to: :class
35
+
36
+ def store_location(path = request.url)
37
+ session[:return_to] = path
38
+ end
39
+
40
+ def stored_location
41
+ session.delete(:return_to)
42
+ end
43
+
44
+ def find_account_by_request
45
+ if params[:insales_id]
46
+ account_class.find_by_insales_id(params[:insales_id])
47
+ elsif params[:domain]
48
+ account_class.find_by_insales_domain(params[:domain])
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,19 @@
1
+ module Insales::Controller
2
+ module InstallerActions
3
+ def install
4
+ if insales_app_class.install(params[:shop], params[:token], params[:insales_id])
5
+ head :ok
6
+ else
7
+ raise 'Instalation failed'
8
+ end
9
+ end
10
+
11
+ def uninstall
12
+ if insales_app_class.uninstall(params[:shop], params[:token])
13
+ head :ok
14
+ else
15
+ raise 'Uninstallation failed'
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,39 @@
1
+ module Insales::Controller
2
+ module SessionActions
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ skip_before_filter :insales_authenticate!, except: [:destroy]
7
+ end
8
+
9
+ def new
10
+ # render
11
+ end
12
+
13
+ def create
14
+ account = find_account_by_request
15
+ return render_not_found unless account
16
+ store_location(insales_success_login_path)
17
+ insales_autologin_start(account)
18
+ end
19
+
20
+ def autologin
21
+ if insales_autologin_finish
22
+ redirect_to stored_location || insales_success_login_path
23
+ else
24
+ redirect_to action: :new
25
+ end
26
+ end
27
+
28
+ def destroy
29
+ insales_logout
30
+ redirect_to action: :new
31
+ end
32
+
33
+ protected
34
+ def render_not_found
35
+ flash.now[:error] = t(:'.account_not_found').html_safe
36
+ render action: :new
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,10 @@
1
+ module Insales
2
+ module Controller
3
+ extend ActiveSupport::Autoload
4
+
5
+ autoload :BaseHelpers
6
+ autoload :Autologin
7
+ autoload :SessionActions
8
+ autoload :InstallerActions
9
+ end
10
+ end
data/lib/insales.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'insales_api'
2
+
3
+ module Insales
4
+ extend ActiveSupport::Autoload
5
+
6
+ autoload :Controller
7
+ end
@@ -1,13 +1,5 @@
1
1
  module InsalesApi
2
2
  class Account < Base
3
- def self.current
4
- find(:one, :from => '/admin/account.xml')
5
- end
6
-
7
- def update
8
- connection.put('/admin/account.xml', encode, self.class.headers).tap do |response|
9
- load_attributes_from_response(response)
10
- end
11
- end
3
+ include ActiveResource::Singleton
12
4
  end
13
5
  end
@@ -0,0 +1,31 @@
1
+ module InsalesApi
2
+ class ActiveResourceProxy
3
+ class << self
4
+ def need_proxy?(value)
5
+ return true if value.is_a?(Hash) || value.is_a?(Array)
6
+ klass = value.is_a?(Class) ? value : value.class
7
+ return true if klass < Base || klass <= ActiveResource::Collection
8
+ false
9
+ end
10
+ end
11
+
12
+ def initialize(configurer, subject)
13
+ @configurer = configurer
14
+ @subject = subject
15
+ end
16
+
17
+ def respond_to_missing?(method_name)
18
+ @subject.respond_to?(method_name) || super
19
+ end
20
+
21
+ def method_missing(method_id, *args, &block)
22
+ @configurer.init_api { proxy_for @subject.send(method_id, *args, &block) }
23
+ end
24
+
25
+ private
26
+ def proxy_for(value)
27
+ return value unless self.class.need_proxy?(value)
28
+ self.class.new(@configurer, value)
29
+ end
30
+ end
31
+ end
@@ -1,35 +1,72 @@
1
1
  module InsalesApi
2
2
  class App
3
- class_attribute :api_key, :api_host, :api_secret, :api_autologin_path
4
- attr_reader :authorized, :auth_token, :shop, :password
3
+ class_attribute :api_key, :api_secret, :api_autologin_url, :api_host, :api_autologin_path,
4
+ :base_resource_class
5
+ attr_reader :authorized, :domain, :password
6
+ self.base_resource_class = Base
5
7
 
6
- def initialize(shop, password)
8
+ class << self
9
+ def configure_api(domain, password)
10
+ base_resource_class.configure(api_key, domain, password)
11
+ end
12
+
13
+ delegate :dump_config, :restore_config, to: :base_resource_class
14
+
15
+ def prepare_domain(domain)
16
+ domain.to_s.strip.downcase
17
+ end
18
+
19
+ alias_method :prepare_shop, :prepare_domain
20
+ deprecate prepare_shop: :prepare_domain,
21
+ api_host: :api_autologin_url,
22
+ api_autologin_path: :api_autologin_url,
23
+ deprecator: Deprecator
24
+
25
+ def install(domain, token, insales_id)
26
+ true
27
+ end
28
+
29
+ def uninstall(domain, password)
30
+ true
31
+ end
32
+
33
+ def password_by_token(token)
34
+ InsalesApi::Password.create(api_secret, token)
35
+ end
36
+ end
37
+
38
+ def initialize(domain, password)
7
39
  @authorized = false
8
- @shop = self.class.prepare_shop shop
40
+ @domain = self.class.prepare_domain(domain)
9
41
  @password = password
10
42
  end
11
43
 
12
44
  def authorization_url
13
- store_auth_token
14
- "http://#{shop}/admin/applications/#{self.class.api_key}/login?" \
15
- "token=#{salt}&login=http://#{self.class.api_host}/#{self.class.api_autologin_path}"
45
+ host, port = domain, nil
46
+ match = /(.+):(\d+)/.match host
47
+ host, port = match[1..2] if match
48
+ URI::Generic.build(
49
+ scheme: 'http',
50
+ host: host,
51
+ port: port && port.to_i,
52
+ path: "/admin/applications/#{api_key}/login",
53
+ query: {
54
+ token: salt,
55
+ login: api_autologin_url || "http://#{api_host}/#{api_autologin_path}",
56
+ }.to_query,
57
+ ).to_s
16
58
  end
17
59
 
18
- def store_auth_token
60
+ def auth_token
19
61
  @auth_token ||= InsalesApi::Password.create(password, salt)
20
62
  end
21
63
 
22
64
  def salt
23
- @salt ||= Digest::MD5.hexdigest("Twulvyeik#{$$}#{Time.now.to_i}thithAwn")
65
+ @salt ||= SecureRandom.hex
24
66
  end
25
67
 
26
- def authorize token
27
- @authorized = false
28
- if self.auth_token and self.auth_token == token
29
- @authorized = true
30
- end
31
-
32
- @authorized
68
+ def authorize(token)
69
+ @authorized = auth_token == token
33
70
  end
34
71
 
35
72
  def authorized?
@@ -37,29 +74,11 @@ module InsalesApi
37
74
  end
38
75
 
39
76
  def configure_api
40
- self.class.configure_api shop, password
77
+ self.class.configure_api(domain, password)
41
78
  end
42
79
 
43
- class << self
44
- def configure_api shop, password
45
- InsalesApi::Base.configure api_key, shop, password
46
- end
47
-
48
- def prepare_shop shop
49
- shop.to_s.strip.downcase
50
- end
51
-
52
- def install shop, token, insales_id
53
- true
54
- end
55
-
56
- def uninstall shop, password
57
- true
58
- end
59
-
60
- def password_by_token token
61
- InsalesApi::Password.create(api_secret, token)
62
- end
63
- end
80
+ alias_method :store_auth_token, :auth_token
81
+ alias_method :shop, :domain
82
+ deprecate store_auth_token: :auth_token, shop: :domain, deprecator: Deprecator
64
83
  end
65
84
  end
@@ -0,0 +1,3 @@
1
+ module InsalesApi
2
+ class ApplicationCharge < Base; end
3
+ end
@@ -1,3 +1,5 @@
1
1
  module InsalesApi
2
- class Asset < Base; end
2
+ class Asset < Base
3
+ self.prefix = "#{prefix}themes/:theme_id/"
4
+ end
3
5
  end
@@ -1,12 +1,48 @@
1
+ require 'insales_api/resource/countable'
2
+ require 'insales_api/resource/paginated'
3
+ require 'insales_api/resource/with_updated_since'
4
+ require 'insales_api/active_resource_proxy'
5
+
1
6
  module InsalesApi
2
7
  class Base < ActiveResource::Base
8
+ extend Resource::Countable
9
+ extend Resource::Paginated
10
+
11
+ self.include_root_in_json = false
12
+ self.headers['User-Agent'] = %W(
13
+ InsalesApi/#{InsalesApi::VERSION}
14
+ ActiveResource/#{ActiveResource::VERSION::STRING}
15
+ Ruby/#{RUBY_VERSION}
16
+ ).join(' ')
3
17
  self.format = :xml
18
+ self.prefix = '/admin/'
19
+
20
+ class << self
21
+ def configure(api_key, domain, password)
22
+ self.user = api_key
23
+ self.site = "http://#{domain}"
24
+ self.password = password
25
+ self
26
+ end
27
+
28
+ def dump_config
29
+ {
30
+ user: self.user,
31
+ site: self.site,
32
+ password: self.password,
33
+ }
34
+ end
35
+
36
+ def restore_config(options)
37
+ self.user = options[:user]
38
+ self.site = options[:site]
39
+ self.password = options[:password]
40
+ true
41
+ end
4
42
 
5
- def self.configure(api_key, shop, password)
6
- self.user = api_key
7
- self.site = "http://#{shop}/admin/"
8
- self.password = password
9
- nil
43
+ def for_account(account)
44
+ ActiveResourceProxy.new(account, self)
45
+ end
10
46
  end
11
47
  end
12
48
  end
@@ -1,7 +1,13 @@
1
1
  module InsalesApi
2
2
  class Category < Base
3
- def self.set_products_category new_category_id, product_ids
4
- connection.put("/admin/categories/set_products_category.xml", {:id => new_category_id, :product_ids => Array(product_ids)}.to_xml(:root => :new_category), headers)
3
+ class << self
4
+ def set_products_category(new_category_id, product_ids)
5
+ data = {
6
+ id: new_category_id,
7
+ product_ids: Array(product_ids),
8
+ }
9
+ put(:set_products_category, {}, format.encode(data, root: :new_category))
10
+ end
5
11
  end
6
12
  end
7
13
  end
@@ -1,3 +1,5 @@
1
1
  module InsalesApi
2
- class Client < Base; end
2
+ class Client < Base
3
+ extend Resource::WithUpdatedSince
4
+ end
3
5
  end
@@ -0,0 +1,3 @@
1
+ module InsalesApi
2
+ class ClientGroup < Base; end
3
+ end
@@ -1,7 +1,13 @@
1
1
  module InsalesApi
2
2
  class Collect < Base
3
- def self.group_create product_ids, collection_ids
4
- connection.post("/admin/collects/group_create.xml", {:collection_ids => Array(collection_ids), :product_ids => Array(product_ids)}.to_xml(:root => :group_create), headers)
3
+ class << self
4
+ def group_create(product_ids, collection_ids)
5
+ data = {
6
+ collection_ids: Array(collection_ids),
7
+ product_ids: Array(product_ids),
8
+ }
9
+ post(:group_create, {}, format.encode(data, root: :group_create))
10
+ end
5
11
  end
6
12
  end
7
13
  end
@@ -0,0 +1,3 @@
1
+ module InsalesApi
2
+ class DiscountCode < Base; end
3
+ end
@@ -0,0 +1,34 @@
1
+ module InsalesApi::Helpers
2
+ module HasInsalesObject
3
+ def has_insales_object(type, options = {})
4
+ i_method_name = "insales_#{type}"
5
+ class_method_name = "insales_#{type}_class"
6
+ object_class = options[:class] || InsalesApi.const_get(type.to_s.camelcase)
7
+ helpers = Module.new do
8
+ extend ActiveSupport::Concern
9
+
10
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
11
+ included do # included do
12
+ class_attribute :#{class_method_name} # class_attribute :insales_order_class
13
+ self.#{class_method_name} = #{object_class} # self.insales_order_class = InsalesApi::Order
14
+ end # end
15
+ #
16
+ def #{i_method_name}(force = false) # def insales_order(force = false)
17
+ return @#{i_method_name} if @#{i_method_name} && !force # return @insales_order if @insales_order && !force
18
+ @#{i_method_name} = init_api do # @insales_order = init_api do
19
+ #{class_method_name}.find(insales_id) # insales_order_class.find(insales_id)
20
+ end # end
21
+ end # end
22
+ #
23
+ attr_writer :#{i_method_name} # attr_writer :insales_order
24
+ #
25
+ def reload(*) # def reload(*)
26
+ @#{i_method_name} = nil # @insales_order = nil
27
+ super # super
28
+ end # end
29
+ RUBY
30
+ end
31
+ include helpers
32
+ end
33
+ end
34
+ end