zoho_hub 0.1.25 → 0.2.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +4 -0
  5. data/.ruby-version +1 -1
  6. data/.travis.yml +5 -2
  7. data/README.md +91 -7
  8. data/bin/console +5 -6
  9. data/bin/read +44 -0
  10. data/bin/setup +0 -2
  11. data/bin/zoho_hub +62 -0
  12. data/lib/zoho_hub.rb +20 -19
  13. data/lib/zoho_hub/auth.rb +37 -47
  14. data/lib/zoho_hub/base_record.rb +122 -0
  15. data/lib/zoho_hub/configuration.rb +3 -4
  16. data/lib/zoho_hub/connection.rb +10 -17
  17. data/lib/zoho_hub/{records → deprecated_and_only_for_reference_records}/account.rb +0 -0
  18. data/lib/zoho_hub/{records → deprecated_and_only_for_reference_records}/campaign.rb +0 -0
  19. data/lib/zoho_hub/{records → deprecated_and_only_for_reference_records}/contact.rb +2 -4
  20. data/lib/zoho_hub/deprecated_and_only_for_reference_records/funder.rb +9 -0
  21. data/lib/zoho_hub/{records → deprecated_and_only_for_reference_records}/potential.rb +1 -7
  22. data/lib/zoho_hub/deprecated_and_only_for_reference_records/product.rb +9 -0
  23. data/lib/zoho_hub/deprecated_and_only_for_reference_records/quote.rb +34 -0
  24. data/lib/zoho_hub/errors.rb +0 -3
  25. data/lib/zoho_hub/module_builder.rb +61 -0
  26. data/lib/zoho_hub/oauth_callback_server.rb +26 -0
  27. data/lib/zoho_hub/response.rb +1 -7
  28. data/lib/zoho_hub/settings/field.rb +33 -0
  29. data/lib/zoho_hub/settings/module.rb +49 -0
  30. data/lib/zoho_hub/string_utils.rb +34 -0
  31. data/lib/zoho_hub/version.rb +1 -1
  32. data/lib/zoho_hub/views/variables.erb +72 -0
  33. data/lib/zoho_hub/with_attributes.rb +74 -0
  34. data/lib/zoho_hub/with_connection.rb +36 -0
  35. data/zoho_hub.gemspec +21 -17
  36. metadata +103 -78
  37. data/lib/zoho_hub/records/attachment.rb +0 -104
  38. data/lib/zoho_hub/records/base_record.rb +0 -189
  39. data/lib/zoho_hub/records/product.rb +0 -35
  40. data/lib/zoho_hub/records/quote.rb +0 -42
  41. data/lib/zoho_hub/records/vendor.rb +0 -34
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zoho_hub/response'
4
+ require 'zoho_hub/with_connection'
5
+ require 'zoho_hub/with_attributes'
6
+ require 'zoho_hub/string_utils'
7
+
8
+ module ZohoHub
9
+ class BaseRecord
10
+ include WithConnection
11
+ include WithAttributes
12
+
13
+ # Default nnumber of records when fetching all.
14
+ DEFAULT_RECORDS_PER_PAGE = 200
15
+
16
+ # Default page number when fetching all.
17
+ DEFAULT_PAGE = 1
18
+
19
+ # Minimum number of records to fetch when fetching all.
20
+ MIN_RECORDS = 2
21
+
22
+ class << self
23
+ def request_path(name = nil)
24
+ @request_path = name if name
25
+ @request_path ||= StringUtils.pluralize(StringUtils.demodulize(to_s))
26
+ @request_path
27
+ end
28
+
29
+ def find(id)
30
+ body = get(File.join(request_path, id.to_s))
31
+ response = build_response(body)
32
+
33
+ if response.empty?
34
+ raise RecordNotFound, "Couldn't find #{request_path.singularize} with 'id'=#{id}"
35
+ end
36
+
37
+ new(response.data)
38
+ end
39
+
40
+ def where(params)
41
+ path = File.join(request_path, 'search')
42
+
43
+ response = get(path, params)
44
+ data = response[:data]
45
+
46
+ data.map { |info| new(info) }
47
+ end
48
+
49
+ def find_by(params)
50
+ records = where(params)
51
+ records.first
52
+ end
53
+
54
+ def create(params)
55
+ new(params).save
56
+ end
57
+
58
+ def all(options = {})
59
+ options[:page] ||= DEFAULT_PAGE
60
+ options[:per_page] ||= DEFAULT_RECORDS_PER_PAGE
61
+ options[:per_page] = MIN_RECORDS if options[:per_page] < MIN_RECORDS
62
+
63
+ body = get(request_path, options)
64
+ response = build_response(body)
65
+
66
+ data = response.nil? ? [] : response.data
67
+
68
+ data.map { |json| new(json) }
69
+ end
70
+
71
+ def exists?(id)
72
+ !find(id).nil?
73
+ rescue RecordNotFound
74
+ false
75
+ end
76
+
77
+ alias exist? exists?
78
+
79
+ def build_response(body)
80
+ response = Response.new(body)
81
+
82
+ raise InvalidTokenError, response.msg if response.invalid_token?
83
+ raise RecordInvalid, response.msg if response.invalid_data?
84
+
85
+ response
86
+ end
87
+ end
88
+
89
+ def save
90
+ body = if new_record? # create new record
91
+ post(self.class.request_path, data: [to_params])
92
+ else # update existing record
93
+ path = File.join(self.class.request_path, id)
94
+ put(path, data: [to_params])
95
+ end
96
+
97
+ response = build_response(body)
98
+
99
+ response.data.dig(:details, :id)
100
+ end
101
+
102
+ def new_record?
103
+ !id
104
+ end
105
+
106
+ def to_params
107
+ params = {}
108
+
109
+ attributes.each do |attr|
110
+ key = attr_to_zoho_key(attr)
111
+
112
+ params[key] = send(attr)
113
+ end
114
+
115
+ params
116
+ end
117
+
118
+ def build_response(body)
119
+ self.class.build_response(body)
120
+ end
121
+ end
122
+ end
@@ -2,17 +2,16 @@
2
2
 
3
3
  module ZohoHub
4
4
  class Configuration
5
- attr_accessor :client_id, :secret, :redirect_uri, :base_url, :access_type
5
+ attr_accessor :client_id, :secret, :redirect_uri, :api_domain
6
6
  attr_writer :debug
7
7
 
8
- DEFAULT_BASE_URL = 'https://accounts.zoho.eu'
8
+ DEFAULT_API_DOMAIN = 'https://accounts.zoho.eu'
9
9
 
10
10
  def initialize
11
11
  @client_id = ''
12
12
  @secret = ''
13
13
  @redirect_uri = ''
14
- @base_url = DEFAULT_BASE_URL
15
- @access_type = Auth::DEFAULT_ACCESS_TYPE
14
+ @api_domain = DEFAULT_API_DOMAIN
16
15
  end
17
16
 
18
17
  def debug?
@@ -22,43 +22,37 @@ module ZohoHub
22
22
  def initialize(access_token:, api_domain: DEFAULT_DOMAIN, expires_in: 3600, refresh_token: nil)
23
23
  @access_token = access_token
24
24
  @expires_in = expires_in
25
- @api_domain = api_domain || DEFAULT_DOMAIN
25
+ @api_domain = api_domain
26
26
  @refresh_token ||= refresh_token # do not overwrite if it's already set
27
27
  end
28
28
 
29
- def get(path, params = {}, &block)
29
+ def get(path, params = {})
30
30
  log "GET #{path} with #{params}"
31
31
 
32
- response = with_refresh do
33
- adapter(&block).get(path, params)
34
- end
32
+ response = with_refresh { adapter.get(path, params) }
35
33
  response.body
36
34
  end
37
35
 
38
- def post(path, params = {}, &block)
36
+ def post(path, params = {})
39
37
  log "POST #{path} with #{params}"
40
38
 
41
- response = with_refresh do
42
- adapter(&block).post(path, params)
43
- end
39
+ response = with_refresh { adapter.post(path, params) }
44
40
  response.body
45
41
  end
46
42
 
47
- def put(path, params = {}, &block)
43
+ def put(path, params = {})
48
44
  log "PUT #{path} with #{params}"
49
45
 
50
- response = with_refresh do
51
- adapter(&block).put(path, params)
52
- end
46
+ response = with_refresh { adapter.put(path, params) }
53
47
  response.body
54
48
  end
55
49
 
56
50
  def access_token?
57
- @access_token.present?
51
+ @access_token
58
52
  end
59
53
 
60
54
  def refresh_token?
61
- @refresh_token.present?
55
+ @refresh_token
62
56
  end
63
57
 
64
58
  def log(text)
@@ -79,7 +73,7 @@ module ZohoHub
79
73
  log "Refreshing outdated token... #{@access_token}"
80
74
  params = ZohoHub::Auth.refresh_token(@refresh_token)
81
75
 
82
- @on_refresh_cb.call(params) if @on_refresh_cb.present?
76
+ @on_refresh_cb.call(params) if @on_refresh_cb
83
77
 
84
78
  @access_token = params[:access_token]
85
79
 
@@ -104,7 +98,6 @@ module ZohoHub
104
98
  Faraday.new(url: base_url) do |conn|
105
99
  conn.headers = authorization_header if access_token?
106
100
  conn.use FaradayMiddleware::ParseJson
107
- yield conn if block_given?
108
101
  conn.response :json, parser_options: { symbolize_names: true }
109
102
  conn.response :logger if ZohoHub.configuration.debug?
110
103
  conn.adapter Faraday.default_adapter
@@ -4,8 +4,8 @@ require 'zoho_hub/records/base_record'
4
4
 
5
5
  module ZohoHub
6
6
  class Contact < BaseRecord
7
- attributes :id, :email, :salutation, :first_name, :mobile, :role, :last_name, :vendor_id
8
- attributes :account_id, :owner_id, :campaign_id, :status, :campaign_detail, :phone
7
+ attributes :id, :email, :salutation, :first_name, :mobile, :role, :last_name
8
+ attributes :account_id, :owner_id, :campaign_id, :status, :campaign_detail
9
9
 
10
10
  attribute_translation(
11
11
  id: :id,
@@ -30,7 +30,6 @@ module ZohoHub
30
30
  @account_id ||= params.dig(:Account_Name, :id)
31
31
  @owner_id ||= params.dig(:Owner, :id)
32
32
  @campaign_id ||= params.dig(:Campaign_Lookup, :id)
33
- @vendor_id ||= params.dig(:Vendor_Name, :id)
34
33
  end
35
34
 
36
35
  def to_params
@@ -39,7 +38,6 @@ module ZohoHub
39
38
  params[:Account_Name] = { id: @account_id } if @account_id
40
39
  params[:Owner] = { id: @owner_id } if @owner_id
41
40
  params[:Campaign_Lookup] = { id: @campaign_id } if @campaign_id
42
- params[:Vendor_Name] = { id: @vendor_id } if @vendor_id
43
41
 
44
42
  params
45
43
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ZohoHub
4
+ class Vendor < BaseRecord
5
+ def initialize(params)
6
+ puts Rainbow(params).red.bright
7
+ end
8
+ end
9
+ end
@@ -9,9 +9,6 @@ module ZohoHub
9
9
  attributes :currency, :territory, :employee_count, :turnover, :industry, :region
10
10
  attributes :review_outcome, :first_created, :last_modified, :preferred_term, :project_notes
11
11
  attributes :campaign_id, :account_id, :contact_id, :campaign_detail, :reviewers_comment
12
- attributes :accounting_software, :banking_provider
13
- attributes :guarantee_types, :home_ownership_status
14
- attributes :accountant_id, :vat_registration
15
12
 
16
13
  DEFAULTS = {
17
14
  currency: 'GBP',
@@ -26,8 +23,7 @@ module ZohoHub
26
23
  code: :Project_Ref_No,
27
24
  description: :Project_description,
28
25
  employee_count: :Number_of_Employees,
29
- use_proceeds: :use_proceeds,
30
- vat_registration: :Pick_List_15
26
+ use_proceeds: :use_proceeds
31
27
  )
32
28
 
33
29
  def initialize(params)
@@ -41,7 +37,6 @@ module ZohoHub
41
37
  @account_id ||= params.dig(:Account_Name, :id)
42
38
  @contact_id ||= params.dig(:Contact_Name, :id)
43
39
  @campaign_id ||= params.dig(:Campaign_Source, :id)
44
- @accountant_id ||= params.dig(:Accountant_Name, :id)
45
40
  end
46
41
 
47
42
  def to_params
@@ -50,7 +45,6 @@ module ZohoHub
50
45
  params[:Campaign_Source] = { id: @campaign_id } if @campaign_id
51
46
  params[:Account_Name] = { id: @account_id } if @account_id
52
47
  params[:Contact_Name] = { id: @contact_id } if @contact_id
53
- params[:Accountant_Name] = { id: @accountant_id } if @accountant_id
54
48
 
55
49
  params
56
50
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ZohoHub
4
+ class Product < BaseRecord
5
+ def initialize(params)
6
+ puts Rainbow(params).red.bright
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zoho_hub/records/base_record'
4
+
5
+ module ZohoHub
6
+ class Quote < BaseRecord
7
+ attributes :id, :stage, :subject
8
+ attributes :potential_id
9
+
10
+ attribute_translation(
11
+ id: :id,
12
+ stage: :Quote_Stage
13
+ )
14
+
15
+ def initialize(params)
16
+ puts Rainbow(params).bright.red
17
+ attributes.each do |attr|
18
+ zoho_key = attr_to_zoho_key(attr)
19
+
20
+ send("#{attr}=", params[zoho_key] || params[attr])
21
+ end
22
+
23
+ @potential_id ||= params.dig(:Deal_Name, :id)
24
+ @lender_organisation_id ||= params.dig(:Account_Name, :id)
25
+ end
26
+
27
+ def to_params
28
+ params = super
29
+
30
+ params[:Deal_Name] = { id: @potential_id } if @potential_id
31
+ params[:Account_Name] = { id: @lender_organisation_id } if @lender_organisation_id
32
+ end
33
+ end
34
+ end
@@ -12,7 +12,4 @@ module ZohoHub
12
12
 
13
13
  class ZohoAPIError < StandardError
14
14
  end
15
-
16
- class AttachmentLinkTakenError < StandardError
17
- end
18
15
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zoho_hub/string_utils'
4
+
5
+ module ZohoHub
6
+ class ModuleBuilder
7
+ class << self
8
+ def build_from_cache
9
+ cached_module_definitions.map do |file|
10
+ json = MultiJson.load(File.read(file), symbolize_keys: true)
11
+
12
+ create_module(json)
13
+ end
14
+ end
15
+
16
+ def cached_module_definitions
17
+ Dir[File.join(ZohoHub.root, 'cache', 'modules', '**')]
18
+ end
19
+
20
+ def create_module(json)
21
+ fields = cached_module_fields(json[:api_name])
22
+
23
+ klass = Class.new(ZohoHub::BaseRecord) do
24
+ request_path json[:api_name]
25
+
26
+ translations = {}
27
+ fields.each do |field|
28
+ key = StringUtils.underscore(field[:api_name])
29
+
30
+ translations[key] = field[:api_name]
31
+ end
32
+
33
+ if translations.any?
34
+ attributes(*translations.keys)
35
+ attribute_translation(translations)
36
+ end
37
+
38
+ def initialize(params)
39
+ attributes.each do |attr|
40
+ zoho_key = attr_to_zoho_key(attr)
41
+
42
+ send("#{attr}=", params[zoho_key] || params[attr])
43
+ end
44
+ end
45
+ end
46
+
47
+ ZohoHub.const_set(StringUtils.camelize(json[:singular_label]), klass)
48
+ end
49
+
50
+ def cached_module_fields(module_name)
51
+ file = File.join(ZohoHub.root, 'cache', 'fields', "#{module_name}.json")
52
+
53
+ return [] unless File.exist?(file)
54
+
55
+ json_content = File.read(file)
56
+
57
+ MultiJson.load(json_content, symbolize_keys: true)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sinatra/base'
4
+
5
+ module ZohoHub
6
+ class OauthCallbackServer < Sinatra::Base
7
+ enable :logging
8
+
9
+ CALLBACK_PATH = 'oauth2callback'
10
+
11
+ before do
12
+ content_type :json
13
+ end
14
+
15
+ get "/#{CALLBACK_PATH}" do
16
+ grant_token = params[:code]
17
+
18
+ # This will trigger a post request to get both the token and the refresh token
19
+ @variables = ZohoHub::Auth.get_token(grant_token)
20
+
21
+ puts "Variables: #{@variables.inspect}"
22
+
23
+ erb :variables
24
+ end
25
+ end
26
+ end
@@ -7,9 +7,7 @@ module ZohoHub
7
7
  end
8
8
 
9
9
  def invalid_data?
10
- if data.is_a?(Array)
11
- return data.first[:code] == 'MANDATORY_NOT_FOUND'
12
- end
10
+ return false if data.is_a?(Array)
13
11
 
14
12
  data[:code] == 'INVALID_DATA'
15
13
  end
@@ -43,10 +41,6 @@ module ZohoHub
43
41
  def msg
44
42
  msg = data[:message]
45
43
 
46
- if data.dig(:code) == 'INVALID_DATA'
47
- msg << ", error in #{data.dig(:details, :api_name)}"
48
- end
49
-
50
44
  if data.dig(:details, :expected_data_type)
51
45
  expected = data.dig(:details, :expected_data_type)
52
46
  field = data.dig(:details, :api_name)