├── lib ├── ZCRMSDK │ ├── version.rb │ ├── restclient.rb │ ├── request.rb │ ├── oauth_utility.rb │ ├── persistence.rb │ ├── org.rb │ ├── response.rb │ ├── utility.rb │ ├── oauth_client.rb │ └── operations.rb └── ZCRMSDK.rb ├── Gemfile ├── bin ├── setup └── console ├── Rakefile ├── spec ├── ZCRMSDK_spec.rb ├── spec_helper.rb └── record_spec.rb ├── LICENSE.txt ├── ZCRMSDK.gemspec ├── README.md └── Gemfile.lock /lib/ZCRMSDK/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module ZCRMSDK 4 | VERSION = '1.0.5' 5 | end 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | # Specify your gem's dependencies in ZCRMSDK.gemspec 6 | gemspec 7 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler/gem_tasks' 4 | require 'rspec/core/rake_task' 5 | 6 | RSpec::Core::RakeTask.new(:spec) 7 | 8 | task default: :spec 9 | -------------------------------------------------------------------------------- /spec/ZCRMSDK_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe ZCRMSDK do 4 | it 'has a version number' do 5 | expect(ZCRMSDK::VERSION).not_to be nil 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/ZCRMSDK.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'ZCRMSDK/oauth_utility' 4 | require 'ZCRMSDK/operations' 5 | require 'ZCRMSDK/handler' 6 | require 'ZCRMSDK/oauth_client' 7 | require 'ZCRMSDK/operations' 8 | require 'ZCRMSDK/org' 9 | require 'ZCRMSDK/persistence' 10 | require 'ZCRMSDK/request' 11 | require 'ZCRMSDK/response' 12 | require 'ZCRMSDK/utility' 13 | require 'ZCRMSDK/restclient' 14 | require 'ZCRMSDK/version' 15 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require 'bundler/setup' 5 | require 'ZCRMSDK' 6 | 7 | # You can add fixtures and/or initialization code here to make experimenting 8 | # with your gem easier. You can also use a different console, if you like. 9 | 10 | # (If you use this, don't forget to add pry to your Gemfile!) 11 | # require "pry" 12 | # Pry.start 13 | 14 | require 'irb' 15 | IRB.start(__FILE__) 16 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler/setup' 4 | require 'ZCRMSDK' 5 | 6 | RSpec.configure do |config| 7 | # Enable flags like --only-failures and --next-failure 8 | config.example_status_persistence_file_path = '.rspec_status' 9 | 10 | # Disable RSpec exposing methods globally on `Module` and `main` 11 | config.disable_monkey_patching! 12 | 13 | config.expect_with :rspec do |c| 14 | c.syntax = :expect 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 ZOHO CRM API TEAM 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /ZCRMSDK.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | lib = File.expand_path('lib', __dir__) 4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 5 | require 'ZCRMSDK/version' 6 | 7 | Gem::Specification.new do |spec| 8 | spec.name = 'ZCRMSDK' 9 | spec.version = ZCRMSDK::VERSION 10 | spec.authors = ['ZOHO CRM API TEAM'] 11 | spec.email = ['support@zohocrm.com'] 12 | spec.summary = 'API client for Zoho CRM ' 13 | spec.description = 'An API client for CRM customers, with which they can call ZOHO CRM APIs with ease' 14 | spec.homepage = 'https://www.zoho.com/crm/' 15 | spec.metadata["source_code_uri"] = "https://github.com/zoho/zcrm-ruby-sdk" 16 | spec.files = Dir['lib/**/*'] 17 | spec.bindir = 'exe' 18 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 19 | spec.require_paths = ['lib'] 20 | 21 | spec.add_development_dependency 'bundler', '~> 2.0' 22 | spec.add_runtime_dependency 'multipart-post', '~> 2.0' 23 | spec.add_runtime_dependency 'rest-client', '~> 2.0' 24 | spec.add_runtime_dependency 'json', '~> 2.0' 25 | spec.add_development_dependency 'rake', '~> 10.0' 26 | spec.add_development_dependency 'rspec', '~> 3.0' 27 | spec.add_development_dependency 'mysql2', '~> 0.5.2' 28 | end 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Archival Notice: 2 | 3 | This SDK is archived. You can continue to use it, but no new features or support requests will be accepted. For the new version, refer to 4 | 5 | ZOHO CRM v2 API SDK : 6 | - [GitHub Repository](https://github.com/zoho/zohocrm-ruby-sdk-2.0) 7 | - [Help Doc](https://www.zoho.com/crm/developer/docs/server-side-sdks/v3/ruby.html) 8 | 9 | ZOHO CRM v2.1 API SDK : 10 | - [GitHub Repository](https://github.com/zoho/zohocrm-ruby-sdk-2.1) 11 | 12 | # ZCRMSDK 13 | 14 | The Ruby library for integrating with the Zoho CRM API. 15 | 16 | 17 | ## Installation 18 | 19 | There are a couple of ways of installing ZCRMSDKK: 20 | 21 | Install 1: 22 | 23 | Start by adding this line to your application's Gemfile: 24 | 25 | gem 'ZCRMSDK' 26 | 27 | And follow it with executing this command: 28 | 29 | $ bundle 30 | 31 | Install 2: 32 | 33 | To fully install the CRM API wrapper yourself, just execute this command: 34 | 35 | $ gem install ZCRMSDK 36 | 37 | 38 | ## Documentation 39 | 40 | ### SDK documentation 41 | ### API Reference 42 | 43 | ## Usage 44 | 45 | ### Refer SDK documentation for Usage 46 | 47 | 48 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | ZCRMSDK (1.0.4) 5 | json (~> 2.0) 6 | multipart-post (~> 2.0) 7 | rest-client (~> 2.0) 8 | 9 | GEM 10 | remote: https://rubygems.org/ 11 | specs: 12 | diff-lcs (1.3) 13 | domain_name (0.5.20190701) 14 | unf (>= 0.0.5, < 1.0.0) 15 | http-accept (1.7.0) 16 | http-cookie (1.0.3) 17 | domain_name (~> 0.5) 18 | json (2.3.0) 19 | mime-types (3.3.1) 20 | mime-types-data (~> 3.2015) 21 | mime-types-data (3.2020.0425) 22 | multipart-post (2.1.1) 23 | mysql2 (0.5.3) 24 | netrc (0.11.0) 25 | rake (10.5.0) 26 | rest-client (2.1.0) 27 | http-accept (>= 1.7.0, < 2.0) 28 | http-cookie (>= 1.0.2, < 2.0) 29 | mime-types (>= 1.16, < 4.0) 30 | netrc (~> 0.8) 31 | rspec (3.9.0) 32 | rspec-core (~> 3.9.0) 33 | rspec-expectations (~> 3.9.0) 34 | rspec-mocks (~> 3.9.0) 35 | rspec-core (3.9.2) 36 | rspec-support (~> 3.9.3) 37 | rspec-expectations (3.9.2) 38 | diff-lcs (>= 1.2.0, < 2.0) 39 | rspec-support (~> 3.9.0) 40 | rspec-mocks (3.9.1) 41 | diff-lcs (>= 1.2.0, < 2.0) 42 | rspec-support (~> 3.9.0) 43 | rspec-support (3.9.3) 44 | unf (0.1.4) 45 | unf_ext 46 | unf_ext (0.0.7.7) 47 | 48 | PLATFORMS 49 | ruby 50 | 51 | DEPENDENCIES 52 | ZCRMSDK! 53 | bundler (~> 2.0) 54 | mysql2 (~> 0.5.2) 55 | rake (~> 10.0) 56 | rspec (~> 3.0) 57 | 58 | BUNDLED WITH 59 | 2.0.2 60 | -------------------------------------------------------------------------------- /lib/ZCRMSDK/restclient.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'utility' 4 | require_relative 'handler' 5 | require_relative 'operations' 6 | require_relative 'org' 7 | module ZCRMSDK 8 | module RestClient 9 | # THIS CLASS IS PRIMARILY USED TO PASS THE CREDENTIALS TO THE SDK AND CALL FEW APIS 10 | class ZCRMRestClient 11 | @@current_user_email = nil 12 | def initialize; end 13 | 14 | def self.get_instance 15 | ZCRMRestClient.new 16 | end 17 | 18 | def self.current_user_email 19 | unless @@current_user_email.nil? 20 | @@current_user_email.dup 21 | end 22 | end 23 | 24 | def self.current_user_email=(current_user_email) 25 | @@current_user_email = current_user_email 26 | end 27 | 28 | def self.init(config_details) 29 | if config_details.nil? 30 | raise Utility::ZCRMException.new('init', Utility::APIConstants::RESPONSECODE_BAD_REQUEST, 'configuration details must be given', 'CONFIG DETAILS IS NOT PROVIDED'), 'Configurations details has to be provided!' 31 | end 32 | 33 | Utility::ZCRMConfigUtil.init(true, config_details) 34 | end 35 | 36 | def get_all_modules 37 | Handler::MetaDataAPIHandler.get_instance.get_all_modules 38 | end 39 | 40 | def get_module(module_api_name) 41 | Handler::MetaDataAPIHandler.get_instance.get_module(module_api_name) 42 | end 43 | 44 | def get_organization_instance 45 | Org::ZCRMOrganization.get_instance 46 | end 47 | 48 | def get_module_instance(module_api_name) 49 | Operations::ZCRMModule.get_instance(module_api_name) 50 | end 51 | 52 | def get_record_instance(module_api_name = nil, entity_id = nil) 53 | Operations::ZCRMRecord.get_instance(module_api_name, entity_id) 54 | end 55 | 56 | def get_current_user 57 | Handler::OrganizationAPIHandler.get_instance.get_current_user 58 | end 59 | 60 | def get_organization_details 61 | Handler::OrganizationAPIHandler.get_instance.get_organization_details 62 | end 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /lib/ZCRMSDK/request.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'utility' 4 | require_relative 'response' 5 | module ZCRMSDK 6 | module Request 7 | # THIS CLASS IS USED TO AUTHENTICATE AND CONSTRUCT API REQUEST 8 | class APIRequest 9 | def initialize(api_handler_ins) 10 | construct_api_url 11 | @url += api_handler_ins.request_url_path 12 | @url = 'https://' + @url unless @url.start_with?('http') 13 | @request_body = api_handler_ins.request_body 14 | @request_headers = api_handler_ins.request_headers 15 | @request_params = api_handler_ins.request_params 16 | @request_method = api_handler_ins.request_method 17 | @request_api_key = api_handler_ins.request_api_key 18 | end 19 | 20 | def self.get_instance(api_handler_ins) 21 | APIRequest.new(api_handler_ins) 22 | end 23 | 24 | def construct_api_url 25 | hit_sandbox = ZCRMSDK::Utility::ZCRMConfigUtil.get_config_value(ZCRMSDK::Utility::APIConstants::SANDBOX) 26 | url = ZCRMSDK::Utility::ZCRMConfigUtil.get_api_base_url 27 | if hit_sandbox == 'true' 28 | url = url.sub('www.', 'sandbox.') 29 | end 30 | @url = url + '/crm/' + ZCRMSDK::Utility::ZCRMConfigUtil.get_api_version + '/' 31 | end 32 | 33 | def authenticate_request 34 | access_token = ZCRMSDK::Utility::ZCRMConfigUtil.get_instance.get_access_token 35 | if @request_headers.nil? 36 | @request_headers = { ZCRMSDK::Utility::APIConstants::AUTHORIZATION => ZCRMSDK::Utility::APIConstants::OAUTH_HEADER_PREFIX.dup + access_token } 37 | else 38 | @request_headers[ZCRMSDK::Utility::APIConstants::AUTHORIZATION] = ZCRMSDK::Utility::APIConstants::OAUTH_HEADER_PREFIX.dup + access_token 39 | end 40 | @request_headers['User-Agent'] = 'ZohoCRM Ruby SDK' 41 | end 42 | 43 | def get_api_response 44 | authenticate_request 45 | connector = ZCRMSDK::Utility::ZohoHTTPConnector.get_instance(@url, @request_params, @request_headers, @request_body.to_json, @request_method, @request_api_key, false) 46 | response = connector.trigger_request 47 | Response::APIResponse.get_instance(response, response.code.to_i, @url, @request_api_key) 48 | end 49 | 50 | def get_bulk_api_response 51 | authenticate_request 52 | connector = ZCRMSDK::Utility::ZohoHTTPConnector.get_instance(@url, @request_params, @request_headers, @request_body.to_json, @request_method, @request_api_key, true) 53 | response = connector.trigger_request 54 | Response::BulkAPIResponse.get_instance(response, response.code.to_i, @url, @request_api_key) 55 | end 56 | 57 | def upload_file(file_path) 58 | authenticate_request 59 | form_data = [['file', File.open(file_path)]] 60 | connector = ZCRMSDK::Utility::ZohoHTTPConnector.get_instance(@url, @request_params, @request_headers, @request_body, @request_method, @request_api_key, false, form_data) 61 | response = connector.trigger_request 62 | Response::APIResponse.get_instance(response, response.code.to_i, @url, @request_api_key) 63 | end 64 | 65 | def upload_link_as_attachment(link_url) 66 | authenticate_request 67 | form_data = [['attachmentUrl', link_url]] 68 | connector = ZCRMSDK::Utility::ZohoHTTPConnector.get_instance(@url, @request_params, @request_headers, @request_body, @request_method, @request_api_key, false, form_data) 69 | response = connector.trigger_request 70 | Response::APIResponse.get_instance(response, response.code.to_i, @url, @request_api_key) 71 | end 72 | 73 | def download_file 74 | authenticate_request 75 | connector = ZCRMSDK::Utility::ZohoHTTPConnector.get_instance(@url, @request_params, @request_headers, @request_body, @request_method, @request_api_key, false) 76 | response = connector.trigger_request 77 | file_response = Response::FileAPIResponse.get_instance(response, response.code.to_i, @url) 78 | file_response.set_file_content 79 | file_response 80 | end 81 | end 82 | end 83 | end 84 | -------------------------------------------------------------------------------- /lib/ZCRMSDK/oauth_utility.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'logger' 4 | require 'net/http' 5 | require_relative 'utility' 6 | module ZCRMSDK 7 | module OAuthUtility 8 | # THIS CLASS IS USED TO DECLARE CONSTANTS THAT ARE USED FREQUENTLY 9 | class ZohoOAuthConstants 10 | IAM_URL = 'accounts_url' 11 | SCOPES = 'scope' 12 | STATE = 'state' 13 | STATE_OBTAINING_GRANT_TOKEN = 'OBTAIN_GRANT_TOKEN' 14 | RESPONSE_TYPE = 'response_type' 15 | RESPONSE_TYPE_CODE = 'code' 16 | CLIENT_ID = 'client_id' 17 | CLIENT_SECRET = 'client_secret' 18 | REDIRECT_URL = 'redirect_uri' 19 | ACCESS_TYPE = 'access_type' 20 | ACCESS_TYPE_OFFLINE = 'offline' 21 | ACCESS_TYPE_ONLINE = 'online' 22 | PROMPT = 'prompt' 23 | PROMPT_CONSENT = 'consent' 24 | GRANT_TYPE = 'grant_type' 25 | GRANT_TYPE_AUTH_CODE = 'authorization_code' 26 | TOKEN_PERSISTENCE_PATH = 'token_persistence_path' 27 | DATABASE_PORT = 'db_port' 28 | DATABASE_USERNAME = 'db_username' 29 | DATABASE_PASSWORD = 'db_password' 30 | GRANT_TYPE_REFRESH = 'refresh_token' 31 | CODE = 'code' 32 | GRANT_TOKEN = 'grant_token' 33 | ACCESS_TOKEN = 'access_token' 34 | REFRESH_TOKEN = 'refresh_token' 35 | EXPIRES_IN = 'expires_in' 36 | EXPIRIY_TIME = 'expiry_time' 37 | EXPIRES_IN_SEC = 'expires_in_sec' 38 | PERSISTENCE_HANDLER_CLASS_PATH = 'persistence_handler_class_path' 39 | PERSISTENCE_HANDLER_CLASS = 'persistence_handler_class' 40 | TOKEN = 'token' 41 | DISPATCH_TO = 'dispatchTo' 42 | OAUTH_TOKENS_PARAM = 'oauth_tokens' 43 | SANDBOX = 'sandbox' 44 | OAUTH_HEADER_PREFIX = 'Zoho-oauthtoken ' 45 | AUTHORIZATION = 'Authorization' 46 | REQUEST_METHOD_GET = 'GET' 47 | REQUEST_METHOD_POST = 'POST' 48 | CURRENT_USER_EMAIL = 'current_user_email' 49 | RESPONSECODE_OK = 200 50 | EMAIL = 'Email' 51 | ERROR = 'error' 52 | INFO = 'info' 53 | WARNING = 'warning' 54 | end 55 | # THIS CLASS IS USED TO HANDLE CUSTOM OAUTH EXCEPTIONS 56 | class ZohoOAuthException < StandardError 57 | attr_accessor :url, :err_message, :error, :level 58 | def initialize(url, err_message, error, level) 59 | @err_message = err_message 60 | @error = error 61 | @level = level 62 | @url = url 63 | Utility::SDKLogger.add_log(err_message, level, self) 64 | end 65 | 66 | def self.get_instance(url, err_message, error, level) 67 | ZohoOAuthException.new(url, err_message, error, level) 68 | end 69 | end 70 | # THIS CLASS IS USED TO STORE OAuthParams 71 | class ZohoOAuthParams 72 | attr_accessor :client_id, :client_secret, :redirect_uri 73 | def initialize(client_id, client_secret, redirect_uri) 74 | @client_id = client_id 75 | @client_secret = client_secret 76 | @redirect_uri = redirect_uri 77 | end 78 | 79 | def self.get_instance(client_id, client_secret, redirect_uri) 80 | ZohoOAuthParams.new(client_id, client_secret, redirect_uri) 81 | end 82 | end 83 | # THIS CLASS IS USED TO FIRE OAUTH RELATED REQUESTS 84 | class ZohoOAuthHTTPConnector 85 | attr_accessor :url, :req_headers, :req_method, :req_params, :req_body 86 | def self.get_instance(url, params = nil, headers = nil, body = nil, method = nil) 87 | ZohoOAuthHTTPConnector.new(url, params, headers, body, method) 88 | end 89 | 90 | def initialize(url, params = nil, headers = nil, body = nil, method = nil) 91 | @url = url 92 | @req_headers = headers 93 | @req_method = method 94 | @req_params = params 95 | @req_body = body 96 | end 97 | 98 | def trigger_request 99 | query_string = @req_params.to_a.map { |x| "#{x[0]}=#{x[1]}" }.join('&') 100 | if !query_string.nil? && (query_string.strip != '') 101 | @url += '?' + query_string 102 | end 103 | url = URI(@url) 104 | http = Net::HTTP.new(url.host, url.port) 105 | http.use_ssl = true 106 | if @req_method == OAuthUtility::ZohoOAuthConstants::REQUEST_METHOD_GET 107 | req = Net::HTTP::Get.new(url.request_uri) 108 | elsif @req_method == OAuthUtility::ZohoOAuthConstants::REQUEST_METHOD_POST 109 | req = Net::HTTP::Post.new(url.request_uri) 110 | end 111 | unless @req_headers.nil? 112 | @req_headers.each do |key, value| 113 | req.add_field(key, value) 114 | end 115 | end 116 | response = http.request(req) 117 | response 118 | end 119 | 120 | def self.set_url(url) 121 | @url = url 122 | end 123 | 124 | def self.get_url 125 | @url 126 | end 127 | 128 | def add_http_header(key, value) 129 | @req_headers[key] = value 130 | end 131 | 132 | def get_http_headers 133 | req_headers 134 | end 135 | 136 | def set_http_request_method(method) 137 | @req_method = method 138 | end 139 | 140 | def get_http_request_method 141 | @req_method 142 | end 143 | 144 | def set_request_body(req_body) 145 | @req_body = req_body 146 | end 147 | 148 | def get_request_body 149 | @req_body 150 | end 151 | 152 | def add_http_request_params(key, value) 153 | @req_params[key] = value 154 | end 155 | 156 | def get_http_request_params 157 | @req_params 158 | end 159 | end 160 | end 161 | end 162 | -------------------------------------------------------------------------------- /lib/ZCRMSDK/persistence.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'oauth_utility' 4 | require_relative 'oauth_client' 5 | module ZCRMSDK 6 | module Persistence 7 | # THIS CLASS IS USED TO STORE, RETRIEVE, DELETE TOKENS IN DEFAULT DB 8 | class ZohoOAuthPersistenceHandler 9 | def initialize; end 10 | 11 | def self.get_instance 12 | ZohoOAuthPersistenceHandler.new 13 | end 14 | 15 | def save_oauth_tokens(oauth_tokens) 16 | delete_oauth_tokens(oauth_tokens.user_identifier) 17 | con = Mysql2::Client.new(host: $OAUTH_CONFIG_PROPERTIES['db_address'], username: $OAUTH_CONFIG_PROPERTIES['db_username'], password: $OAUTH_CONFIG_PROPERTIES['db_password'], database: 'zohooauth', port: $OAUTH_CONFIG_PROPERTIES['db_port']) 18 | con.query("insert into oauthtokens(useridentifier,accesstoken,refreshtoken,expirytime) values('#{oauth_tokens.user_identifier}','#{oauth_tokens.access_token}','#{oauth_tokens.refresh_token}',#{oauth_tokens.expiry_time})") 19 | con.close 20 | rescue Mysql2::Error => e 21 | Utility::SDKLogger.add_log(e.error, OAuthUtility::ZohoOAuthConstants::ERROR, e) 22 | ensure 23 | con.close 24 | end 25 | 26 | def get_oauth_tokens(user_identifier) 27 | con = Mysql2::Client.new(host: $OAUTH_CONFIG_PROPERTIES['db_address'], username: $OAUTH_CONFIG_PROPERTIES['db_username'], password: $OAUTH_CONFIG_PROPERTIES['db_password'], database: 'zohooauth', port: $OAUTH_CONFIG_PROPERTIES['db_port']) 28 | query = "select * from oauthtokens where useridentifier='#{user_identifier}'" 29 | rs = con.query(query) 30 | oauth_tokens = nil 31 | rs.each do |row| 32 | oauth_tokens = OAuthClient::ZohoOAuthTokens.get_instance(row['refreshtoken'], row['accesstoken'], row['expirytime'], user_identifier) 33 | con.close 34 | return oauth_tokens 35 | end 36 | raise OAuthUtility::ZohoOAuthException.get_instance('get_oauth_tokens', 'no such email id - ' + user_identifier + ' present in the DB', 'Exception occured while fetching accesstoken from Grant Token', OAuthUtility::ZohoOAuthConstants::ERROR) 37 | rescue Mysql2::Error => e 38 | Utility::SDKLogger.add_log(e.error, OAuthUtility::ZohoOAuthConstants::ERROR, e) 39 | ensure 40 | con.close 41 | end 42 | 43 | def delete_oauth_tokens(user_identifier) 44 | con = Mysql2::Client.new(host: $OAUTH_CONFIG_PROPERTIES['db_address'], username: $OAUTH_CONFIG_PROPERTIES['db_username'], password: $OAUTH_CONFIG_PROPERTIES['db_password'], database: 'zohooauth', port: $OAUTH_CONFIG_PROPERTIES['db_port']) 45 | delete_query = "delete from oauthtokens where useridentifier='#{user_identifier}'" 46 | con.query(delete_query) 47 | con.close 48 | rescue Mysql2::Error => e 49 | Utility::SDKLogger.add_log(e.error, OAuthUtility::ZohoOAuthConstants::ERROR, e) 50 | ensure 51 | con.close 52 | end 53 | end 54 | # THIS CLASS IS USED TO STORE, RETRIEVE, DELETE TOKENS IN FILE 55 | class ZohoOAuthFilePersistenceHandler 56 | def initialize; end 57 | 58 | def self.get_instance 59 | ZohoOAuthFilePersistenceHandler.new 60 | end 61 | 62 | def save_oauth_tokens(oauth_tokens) 63 | unless File.exist?($OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::TOKEN_PERSISTENCE_PATH].dup + '/zcrm_oauthtokens.txt') 64 | file_obj = File.new($OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::TOKEN_PERSISTENCE_PATH].dup + '/zcrm_oauthtokens.txt', 'w') 65 | file_obj.close 66 | end 67 | delete_oauth_tokens(oauth_tokens.user_identifier) 68 | arr = [] 69 | path = $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::TOKEN_PERSISTENCE_PATH].dup + '/zcrm_oauthtokens.txt' 70 | file_obj = File.open(path, 'r') 71 | serialized = file_obj.read 72 | file_obj.close 73 | arr = Marshal.load(serialized) unless serialized.nil? || serialized.empty? 74 | arr.push(oauth_tokens) 75 | tokens = Marshal.dump(arr) 76 | file_obj = File.open(path, "w:#{tokens.encoding.to_s}") 77 | file_obj.write(tokens) 78 | file_obj.close 79 | end 80 | 81 | def get_oauth_tokens(user_identifier) 82 | if !File.exist?($OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::TOKEN_PERSISTENCE_PATH].dup + '/zcrm_oauthtokens.txt') 83 | raise OAuthUtility::ZohoOAuthException.get_instance('get_oauth_tokens', 'file does not exist!generate the access token!', 'Error occured while getting access token', OAuthUtility::ZohoOAuthConstants::ERROR) 84 | end 85 | 86 | path = $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::TOKEN_PERSISTENCE_PATH].dup + '/zcrm_oauthtokens.txt' 87 | file_obj = File.open(path, 'r') 88 | serialized = file_obj.read 89 | file_obj.close 90 | if serialized.empty? || serialized.nil? 91 | raise OAuthUtility::ZohoOAuthException.get_instance('get_oauth_tokens', 'no tokens found!generate the access token!', 'Error occured while getting access token', OAuthUtility::ZohoOAuthConstants::ERROR) 92 | end 93 | 94 | deserialized = Marshal.load(serialized) 95 | deserialized.each do |token| 96 | return token if token.user_identifier == user_identifier 97 | end 98 | raise OAuthUtility::ZohoOAuthException.get_instance('get_oauth_tokens', 'no such' + user_identifier.to_s + 'present in the File', 'Exception occured while fetching accesstoken from Grant Token', OAuthUtility::ZohoOAuthConstants::ERROR) 99 | end 100 | 101 | def delete_oauth_tokens(user_identifier) 102 | path = $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::TOKEN_PERSISTENCE_PATH].dup + '/zcrm_oauthtokens.txt' 103 | file_obj = File.open(path, 'r') 104 | serialized = file_obj.read 105 | file_obj.close 106 | 107 | return if serialized.empty? || serialized.nil? 108 | 109 | found = false 110 | i = 0 111 | deserialized = Marshal.load(serialized) 112 | deserialized.each do |token| 113 | if token.user_identifier == user_identifier 114 | found = true 115 | break 116 | end 117 | i += 1 118 | end 119 | if found 120 | deserialized.delete_at(i) 121 | tokens = Marshal.dump(deserialized) 122 | file_obj = File.open(path, "w:#{tokens.encoding.to_s}") 123 | file_obj.write(tokens) 124 | file_obj.close 125 | end 126 | end 127 | end 128 | end 129 | end 130 | -------------------------------------------------------------------------------- /lib/ZCRMSDK/org.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'handler' 4 | require_relative 'utility' 5 | require_relative 'operations' 6 | module ZCRMSDK 7 | module Org 8 | # THIS CLASS IS USED TO STORE AND EXECUTE ORGANIZATION RELATED FUNCTIONALITIES 9 | class ZCRMOrganization 10 | attr_accessor :users_license_purchased, :photo_id, :privacy_settings, :zia_portal_id, :currency, :company_name, :org_id, :alias_aka, :primary_zuid, :zgid, :primary_email, :website, :mobile, :phone, :employee_count, :description, :time_zone, :iso_code, :currency_locale, :currency_symbol, :street, :state, :city, :country, :zip_code, :country_code, :fax, :mc_status, :is_gapps_enabled, :paid_expiry, :trial_type, :trial_expiry, :is_paid_account, :paid_type 11 | def initialize(org_name = nil, org_id = nil) 12 | @currency = nil 13 | @zia_portal_id = nil 14 | @privacy_settings = nil 15 | @photo_id = nil 16 | @company_name = org_name 17 | @org_id = org_id 18 | @alias_aka = nil 19 | @primary_zuid = nil 20 | @zgid = nil 21 | @primary_email = nil 22 | @website = nil 23 | @mobile = nil 24 | @phone = nil 25 | @employee_count = nil 26 | @description = nil 27 | @time_zone = nil 28 | @iso_code = nil 29 | @currency_locale = nil 30 | @currency_symbol = nil 31 | @street = nil 32 | @state = nil 33 | @city = nil 34 | @country = nil 35 | @zip_code = nil 36 | @country_code = nil 37 | @fax = nil 38 | @mc_status = nil 39 | @is_gapps_enabled = nil 40 | @paid_expiry = nil 41 | @trial_type = nil 42 | @trial_expiry = nil 43 | @is_paid_account = nil 44 | @paid_type = nil 45 | @users_license_purchased = nil 46 | end 47 | 48 | def self.get_instance(org_name = nil, org_id = nil) 49 | ZCRMOrganization.new(org_name, org_id) 50 | end 51 | 52 | def get_user(user_id) 53 | Handler::OrganizationAPIHandler.get_instance.get_user(user_id) 54 | end 55 | 56 | def get_current_user 57 | Handler::OrganizationAPIHandler.get_instance.get_current_user 58 | end 59 | 60 | def get_all_users(page=1,per_page=200) 61 | Handler::OrganizationAPIHandler.get_instance.get_all_users(page,per_page) 62 | end 63 | 64 | def get_all_active_users(page=1,per_page=200) 65 | Handler::OrganizationAPIHandler.get_instance.get_all_active_users(page,per_page) 66 | end 67 | 68 | def get_all_deactive_users(page=1,per_page=200) 69 | Handler::OrganizationAPIHandler.get_instance.get_all_deactive_users(page,per_page) 70 | end 71 | 72 | def get_all_confirmed_users(page=1,per_page=200) 73 | Handler::OrganizationAPIHandler.get_instance.get_all_confirmed_users(page,per_page) 74 | end 75 | 76 | def get_all_not_confirmed_users(page=1,per_page=200) 77 | Handler::OrganizationAPIHandler.get_instance.get_all_not_confirmed_users(page,per_page) 78 | end 79 | 80 | def get_all_deleted_users(page=1,per_page=200) 81 | Handler::OrganizationAPIHandler.get_instance.get_all_deleted_users(page,per_page) 82 | end 83 | 84 | def get_all_active_confirmed_users(page=1,per_page=200) 85 | Handler::OrganizationAPIHandler.get_instance.get_all_active_confirmed_users(page,per_page) 86 | end 87 | 88 | def get_all_admin_users(page=1,per_page=200) 89 | Handler::OrganizationAPIHandler.get_instance.get_all_admin_users(page,per_page) 90 | end 91 | 92 | def get_all_active_confirmed_admin_users(page=1,per_page=200) 93 | Handler::OrganizationAPIHandler.get_instance.get_all_active_confirmed_admin_users(page,per_page) 94 | end 95 | 96 | def get_all_profiles 97 | Handler::OrganizationAPIHandler.get_instance.get_all_profiles 98 | end 99 | 100 | def get_profile(profile_id) 101 | Handler::OrganizationAPIHandler.get_instance.get_profile(profile_id) 102 | end 103 | 104 | def get_all_roles 105 | Handler::OrganizationAPIHandler.get_instance.get_all_roles 106 | end 107 | 108 | def get_role(role_id) 109 | Handler::OrganizationAPIHandler.get_instance.get_role(role_id) 110 | end 111 | 112 | def create_user(user_instance) 113 | Handler::OrganizationAPIHandler.get_instance.create_user(user_instance) 114 | end 115 | 116 | def update_user(user_instance) 117 | Handler::OrganizationAPIHandler.get_instance.update_user(user_instance) 118 | end 119 | 120 | def delete_user(user_id) 121 | Handler::OrganizationAPIHandler.get_instance.delete_user(user_id) 122 | end 123 | 124 | def get_organization_taxes 125 | Handler::OrganizationAPIHandler.get_instance.get_organization_taxes 126 | end 127 | 128 | def get_organization_tax(org_tax_id) 129 | Handler::OrganizationAPIHandler.get_instance.get_organization_tax(org_tax_id) 130 | end 131 | 132 | def search_users_by_criteria(criteria, type = nil,page=1,per_page=200) 133 | Handler::OrganizationAPIHandler.get_instance.search_users_by_criteria(criteria, type,page,per_page) 134 | end 135 | 136 | def create_organization_taxes(orgtax_instances) 137 | Handler::OrganizationAPIHandler.get_instance.create_organization_taxes(orgtax_instances) 138 | end 139 | 140 | def update_organization_taxes(orgtax_instances) 141 | Handler::OrganizationAPIHandler.get_instance.update_organization_taxes(orgtax_instances) 142 | end 143 | 144 | def delete_organization_taxes(orgtax_ids) 145 | Handler::OrganizationAPIHandler.get_instance.delete_organization_taxes(orgtax_ids) 146 | end 147 | 148 | def delete_organization_tax(orgtax_id) 149 | Handler::OrganizationAPIHandler.get_instance.delete_organization_tax(orgtax_id) 150 | end 151 | def get_notes(sort_by=nil,sort_order=nil,page=1,per_page=200) 152 | Handler::OrganizationAPIHandler.get_instance.get_notes(sort_by,sort_order,page,per_page) 153 | end 154 | def create_notes(notes_instances) 155 | Handler::OrganizationAPIHandler.get_instance.create_notes(notes_instances) 156 | end 157 | def delete_notes(notes_ids) 158 | Handler::OrganizationAPIHandler.get_instance.delete_notes(notes_ids) 159 | end 160 | def get_variable_groups 161 | Handler::VariableGroupAPIHandler.get_instance.get_variable_groups 162 | end 163 | def get_variables 164 | Handler::VariableAPIHandler.get_instance.get_variables 165 | end 166 | def create_variables(variable_instances) 167 | Handler::VariableAPIHandler.get_instance.create_variables(variable_instances) 168 | end 169 | def update_variables(variable_instances) 170 | Handler::VariableAPIHandler.get_instance.update_variables(variable_instances) 171 | end 172 | end 173 | end 174 | end 175 | -------------------------------------------------------------------------------- /lib/ZCRMSDK/response.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'utility' 4 | require 'json' 5 | module ZCRMSDK 6 | module Response 7 | # THIS CLASS IS USED TO STORE DETAILS ABOUT THE API RESPONSE , PROCESS JSON AND HANDLE FAULTY RESPONSES 8 | class CommonAPIResponse 9 | attr_accessor :response_json, :response_headers, :response, :status_code, :api_key, :url, :data, :status, :code, :message, :details 10 | def initialize(response, status_code, url, api_key = nil) 11 | @response_json = nil 12 | @response_headers = nil 13 | @response = response 14 | @status_code = status_code 15 | @api_key = api_key 16 | @url = url 17 | @data = nil 18 | @status = nil 19 | @code = nil 20 | @message = nil 21 | @details = nil 22 | set_response_json 23 | process_response 24 | end 25 | 26 | def self.get_instance(response, status_code, url, api_key = nil) 27 | CommonAPIResponse.new(response, status_code, url, api_key) 28 | end 29 | 30 | def set_response_json 31 | if (@status_code != Utility::APIConstants::RESPONSECODE_NO_CONTENT) && (@status_code != Utility::APIConstants::RESPONSECODE_NOT_MODIFIED) 32 | @response_json = JSON.parse(@response.body) 33 | else 34 | @response_json = {} 35 | @response_headers = {} 36 | return 37 | end 38 | @response_headers = @response.to_hash 39 | end 40 | 41 | def process_response 42 | if Utility::APIConstants::FAULTY_RESPONSE_CODES.include?(@status_code) 43 | handle_faulty_responses 44 | elsif (@status_code == Utility::APIConstants::RESPONSECODE_ACCEPTED) || (@status_code == Utility::APIConstants::RESPONSECODE_OK) || (@status_code == Utility::APIConstants::RESPONSECODE_CREATED) 45 | process_response_data 46 | end 47 | end 48 | 49 | def handle_faulty_responses 50 | nil 51 | end 52 | 53 | def process_response_data 54 | nil 55 | end 56 | end 57 | # THIS CLASS IS USED TO HANDLE API RESPONSE 58 | class APIResponse < CommonAPIResponse 59 | def initialize(response, status_code, url, api_key) 60 | super 61 | end 62 | 63 | def self.get_instance(response, status_code, url, api_key) 64 | APIResponse.new(response, status_code, url, api_key) 65 | end 66 | 67 | def handle_faulty_responses 68 | if @status_code == Utility::APIConstants::RESPONSECODE_NO_CONTENT 69 | error_msg = Utility::APIConstants::NO_CONTENT 70 | exception = Utility::ZCRMException.get_instance(@url, @status_code, error_msg, Utility::APIConstants::NO_CONTENT, nil, error_msg) 71 | else 72 | response_json = @response_json 73 | exception = Utility::ZCRMException.get_instance(@url, @status_code, response_json[Utility::APIConstants::MESSAGE], response_json[Utility::APIConstants::CODE], response_json[Utility::APIConstants::DETAILS], response_json[Utility::APIConstants::MESSAGE]) 74 | end 75 | raise exception 76 | end 77 | 78 | def process_response_data 79 | resp_json = @response_json 80 | if resp_json.include?(api_key) 81 | resp_json = @response_json[api_key] 82 | resp_json = resp_json[0] if resp_json.instance_of?(Array) 83 | end 84 | if resp_json.include?(Utility::APIConstants::STATUS) && (resp_json[Utility::APIConstants::STATUS] == Utility::APIConstants::STATUS_ERROR) 85 | exception = Utility::ZCRMException.get_instance(@url, @status_code, resp_json[Utility::APIConstants::MESSAGE], resp_json[Utility::APIConstants::CODE], resp_json[Utility::APIConstants::DETAILS], resp_json[Utility::APIConstants::STATUS]) 86 | raise exception 87 | elsif resp_json.include?(Utility::APIConstants::STATUS) && (resp_json[Utility::APIConstants::STATUS] == Utility::APIConstants::STATUS_SUCCESS) 88 | @status = resp_json[Utility::APIConstants::STATUS] 89 | @code = resp_json[Utility::APIConstants::CODE] 90 | @message = resp_json[Utility::APIConstants::MESSAGE] 91 | @details = resp_json[Utility::APIConstants::DETAILS] 92 | end 93 | end 94 | end 95 | # THIS CLASS IS USED TO BULK API RESPONSE 96 | class BulkAPIResponse < CommonAPIResponse 97 | attr_accessor :bulk_entity_response, :info 98 | def initialize(response, status_code, url, api_key) 99 | @bulk_entity_response = [] 100 | super 101 | if @response_json.include?(Utility::APIConstants::INFO) 102 | @info = ResponseInfo.get_instance(@response_json[Utility::APIConstants::INFO]) 103 | end 104 | end 105 | 106 | def self.get_instance(response, status_code, url, api_key) 107 | BulkAPIResponse.new(response, status_code, url, api_key) 108 | end 109 | 110 | def handle_faulty_responses 111 | if @status_code == Utility::APIConstants::RESPONSECODE_NO_CONTENT 112 | error_msg = Utility::APIConstants::NO_CONTENT 113 | exception = Utility::ZCRMException.get_instance(@url, @status_code, error_msg, Utility::APIConstants::NO_CONTENT, nil, error_msg) 114 | else 115 | response_json = @response_json 116 | exception = Utility::ZCRMException.get_instance(@url, @status_code, response_json[Utility::APIConstants::MESSAGE], response_json[Utility::APIConstants::CODE], response_json[Utility::APIConstants::DETAILS], response_json[Utility::APIConstants::MESSAGE]) 117 | end 118 | raise exception 119 | end 120 | 121 | def process_response_data 122 | responses_json = @response_json 123 | if responses_json.include?(@api_key) 124 | records_data = @response_json[api_key] 125 | records_data.each do |record_data| 126 | if !record_data.nil? && record_data.key?(Utility::APIConstants::STATUS) 127 | @bulk_entity_response.push(EntityResponse.get_instance(record_data)) 128 | end 129 | end 130 | end 131 | end 132 | end 133 | # THIS CLASS IS USED TO HANDLE FILE API RESPONSE 134 | class FileAPIResponse 135 | attr_accessor :filename, :response_json, :response_headers, :response, :status_code, :url, :data, :status, :code, :message, :details 136 | def initialize(response, status_code, url) 137 | @response_json = nil 138 | @response_headers = nil 139 | @response = response 140 | @status_code = status_code 141 | @url = url 142 | @data = nil 143 | @status = nil 144 | @code = nil 145 | @message = nil 146 | @details = nil 147 | @filename = nil 148 | end 149 | 150 | def self.get_instance(response, status_code, url) 151 | FileAPIResponse.new(response, status_code, url) 152 | end 153 | 154 | def set_file_content 155 | if @status_code == Utility::APIConstants::RESPONSECODE_NO_CONTENT 156 | error_msg = Utility::APIConstants::NO_CONTENT 157 | exception = Utility::ZCRMException.get_instance(@url, @status_code, error_msg, Utility::APIConstants::NO_CONTENT, nil, error_msg) 158 | raise exception 159 | end 160 | if Utility::APIConstants::FAULTY_RESPONSE_CODES.include?(@status_code) 161 | content = JSON.parse(@response.body) 162 | exception = Utility::ZCRMException.get_instance(@url, @status_code, content[Utility::APIConstants::MESSAGE], content[Utility::APIConstants::CODE], content[Utility::APIConstants::DETAILS], content[Utility::APIConstants::MESSAGE]) 163 | raise exception 164 | elsif @status_code == Utility::APIConstants::RESPONSECODE_OK 165 | @response_headers = @response.to_hash 166 | @status = Utility::APIConstants::STATUS_SUCCESS 167 | @filename = @response_headers['content-disposition'][0] 168 | @filename = @filename[@filename.rindex("'") + 1..@filename.length] 169 | @response = @response.body 170 | end 171 | @response_headers = @response.to_hash if @response_headers.nil? 172 | end 173 | end 174 | # THIS CLASS IS USED TO HANDLE ENTITY API RESPONSE 175 | class EntityResponse 176 | attr_accessor :response_json, :code, :message, :status, :details, :data, :upsert_action, :upsert_duplicate_field 177 | def initialize(entity_response) 178 | @response_json = entity_response 179 | @code = entity_response[Utility::APIConstants::CODE] 180 | @message = entity_response[Utility::APIConstants::MESSAGE] 181 | @status = entity_response[Utility::APIConstants::STATUS] 182 | @details = nil 183 | @data = nil 184 | @upsert_action = nil 185 | @upsert_duplicate_field = nil 186 | if entity_response.key?(Utility::APIConstants::DETAILS) 187 | @details = entity_response[Utility::APIConstants::DETAILS] 188 | end 189 | if entity_response.key?(Utility::APIConstants::ACTION) 190 | @upsert_action = entity_response[Utility::APIConstants::ACTION] 191 | end 192 | if entity_response.key?(Utility::APIConstants::DUPLICATE_FIELD) 193 | @upsert_duplicate_field = entity_response[Utility::APIConstants::DUPLICATE_FIELD] 194 | end 195 | end 196 | 197 | def self.get_instance(entity_response) 198 | EntityResponse.new(entity_response) 199 | end 200 | end 201 | # THIS CLASS IS USED TO STORE RESPONSE INFO 202 | class ResponseInfo 203 | attr_reader :is_more_records, :page, :per_page, :count 204 | def initialize(response_info_json) 205 | @is_more_records = (response_info_json['more_records']) == true 206 | @page = (response_info_json['page']).to_i 207 | @per_page = (response_info_json['per_page']).to_i 208 | @count = (response_info_json['count']).to_i 209 | end 210 | 211 | def self.get_instance(response_info_json) 212 | ResponseInfo.new(response_info_json) 213 | end 214 | end 215 | end 216 | end 217 | -------------------------------------------------------------------------------- /lib/ZCRMSDK/utility.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'oauth_utility' 4 | require_relative 'oauth_client' 5 | require_relative 'restclient' 6 | require 'uri' 7 | require 'json' 8 | require 'logger' 9 | require 'net/http' 10 | require 'cgi' 11 | module ZCRMSDK 12 | module Utility 13 | # THIS CLASS IS USED TO SET PERSISTENCE HANDLER AND CREDENTIALS RELATED DETAILS 14 | class ZCRMConfigUtil 15 | def self.get_instance 16 | ZCRMConfigUtil.new 17 | end 18 | 19 | def self.init(is_to_initialize_oauth, config_details) 20 | $CONFIG_PROP_HASH = {} 21 | $CONFIG_PROP_HASH = config_details 22 | if $CONFIG_PROP_HASH[APIConstants::API_BASEURL].nil? 23 | $CONFIG_PROP_HASH[APIConstants::API_BASEURL] = 'https://www.zohoapis.com' 24 | end 25 | if $CONFIG_PROP_HASH[APIConstants::API_VERSION].nil? 26 | $CONFIG_PROP_HASH[APIConstants::API_VERSION] = 'v2' 27 | end 28 | if $CONFIG_PROP_HASH[APIConstants::SANDBOX].nil? 29 | $CONFIG_PROP_HASH[APIConstants::SANDBOX] = 'false' 30 | end 31 | if $CONFIG_PROP_HASH[APIConstants::CONSOLE].nil? || $CONFIG_PROP_HASH[APIConstants::CONSOLE] != 'true' 32 | $CONFIG_PROP_HASH[APIConstants::CONSOLE] = 'false' 33 | end 34 | if $CONFIG_PROP_HASH[APIConstants::LOGPATH].nil? 35 | $CONFIG_PROP_HASH[APIConstants::LOGPATH] = nil 36 | end 37 | if is_to_initialize_oauth 38 | ZCRMSDK::OAuthClient::ZohoOAuth.get_instance(config_details) 39 | end 40 | end 41 | 42 | def self.get_config_value(key_value) 43 | if $CONFIG_PROP_HASH.has_key?(key_value) && !$CONFIG_PROP_HASH[key_value].nil? 44 | $CONFIG_PROP_HASH[key_value].dup 45 | else 46 | return ' ' 47 | end 48 | end 49 | 50 | def self.get_api_base_url 51 | get_config_value(APIConstants::API_BASEURL) 52 | end 53 | 54 | def self.get_api_version 55 | get_config_value(APIConstants::API_VERSION) 56 | end 57 | 58 | def get_access_token 59 | user_email = RestClient::ZCRMRestClient.current_user_email 60 | if user_email.nil? 61 | raise ZCRMException.new('current_user_email', APIConstants::RESPONSECODE_BAD_REQUEST, 'Current user should either be set in ZCRMRestClient or in configuration array', 'CURRENT USER NOT SET') 62 | end 63 | 64 | client_ins = OAuthClient::ZohoOAuth.get_client_instance 65 | client_ins.get_access_token(user_email) 66 | end 67 | end 68 | # THIS CLASS IS USED TO CONSTUCT API SUPPORTED JSON 69 | class CommonUtil 70 | def self.create_api_supported_input_json(input_json, api_key) 71 | input_json = {} if input_json.nil? 72 | input_json_arr = [] 73 | input_json_arr.push(input_json) 74 | req_body_json = {} 75 | req_body_json[api_key] = input_json_arr 76 | req_body_json 77 | end 78 | end 79 | # THIS CLASS IS USED TO LOG THE SDK RELATED ACTIVITY 80 | class SDKLogger 81 | def self.add_log(message, level, exception = nil) 82 | if $CONFIG_PROP_HASH.empty? 83 | raise exception, 'Please Initialize the SDK before using it!' 84 | end 85 | 86 | unless $CONFIG_PROP_HASH[APIConstants::LOGPATH].nil? 87 | logger = Logger.new File.new($CONFIG_PROP_HASH[APIConstants::LOGPATH].dup, 'a') 88 | print_log(logger, message, level, exception) 89 | end 90 | 91 | if $CONFIG_PROP_HASH[APIConstants::CONSOLE] == 'true' 92 | logger = Logger.new STDOUT 93 | print_log(logger, message, level, exception) 94 | end 95 | end 96 | 97 | def self.print_log(logger, message, level, exception) 98 | unless exception.nil? 99 | message += "; Exception Class::#{exception.class}; exception occured in #{exception.url}" 100 | end 101 | 102 | case level 103 | when 'error' 104 | logger.error(message) 105 | when 'info' 106 | logger.info(message) 107 | when 'warning' 108 | logger.warning(message) 109 | when 'fatal' 110 | logger.fatal(message) 111 | end 112 | end 113 | end 114 | # THIS CLASS CONSISTS OF COMMON CONSTANTS FREQUENTLY USED 115 | class APIConstants 116 | ERROR = 'error' 117 | REQUEST_METHOD_GET = 'GET' 118 | REQUEST_METHOD_POST = 'POST' 119 | REQUEST_METHOD_PUT = 'PUT' 120 | REQUEST_METHOD_DELETE = 'DELETE' 121 | REQUEST_METHOD_PATCH = 'PATCH' 122 | OAUTH_HEADER_PREFIX = 'Zoho-oauthtoken ' 123 | AUTHORIZATION = 'Authorization' 124 | API_NAME = 'api_name' 125 | INVALID_ID_MSG = 'The given id seems to be invalid.' 126 | API_MAX_RECORDS_MSG = 'Cannot process more than 100 records at a time.' 127 | INVALID_DATA = 'INVALID_DATA' 128 | CODE_SUCCESS = 'SUCCESS' 129 | STATUS_SUCCESS = 'success' 130 | STATUS_ERROR = 'error' 131 | LEADS = 'Leads' 132 | ACCOUNTS = 'Accounts' 133 | CONTACTS = 'Contacts' 134 | DEALS = 'Deals' 135 | QUOTES = 'Quotes' 136 | SALESORDERS = 'SalesOrders' 137 | INVOICES = 'Invoices' 138 | PURCHASEORDERS = 'PurchaseOrders' 139 | PER_PAGE = 'per_page' 140 | PAGE = 'page' 141 | COUNT = 'count' 142 | MORE_RECORDS = 'more_records' 143 | MESSAGE = 'message' 144 | CODE = 'code' 145 | STATUS = 'status' 146 | DETAILS = 'details' 147 | DATA = 'data' 148 | VARIABLE = 'variables' 149 | VARIABLE_GROUP = 'variable_groups' 150 | INFO = 'info' 151 | FIELDS = 'fields' 152 | LAYOUTS = 'layouts' 153 | TAG = 'tags' 154 | CUSTOM_VIEWS = 'custom_views' 155 | MODULES = 'modules' 156 | RELATED_LISTS = 'related_lists' 157 | ORG = 'org' 158 | ROLES = 'roles' 159 | PROFILES = 'profiles' 160 | USERS = 'users' 161 | TAXES = 'taxes' 162 | CONSOLE = 'log_in_console' 163 | LOGPATH = 'application_log_file_path' 164 | CUSTOM_FUNCTIONS = 'custom_functions' 165 | RESPONSECODE_OK = 200 166 | RESPONSECODE_CREATED = 201 167 | RESPONSECODE_ACCEPTED = 202 168 | RESPONSECODE_NO_CONTENT = 204 169 | RESPONSECODE_MOVED_PERMANENTLY = 301 170 | RESPONSECODE_MOVED_TEMPORARILY = 302 171 | RESPONSECODE_NOT_MODIFIED = 304 172 | RESPONSECODE_BAD_REQUEST = 400 173 | RESPONSECODE_AUTHORIZATION_ERROR = 401 174 | RESPONSECODE_FORBIDDEN = 403 175 | RESPONSECODE_NOT_FOUND = 404 176 | RESPONSECODE_METHOD_NOT_ALLOWED = 405 177 | RESPONSECODE_REQUEST_ENTITY_TOO_LARGE = 413 178 | RESPONSECODE_UNSUPPORTED_MEDIA_TYPE = 415 179 | RESPONSECODE_TOO_MANY_REQUEST = 429 180 | RESPONSECODE_INTERNAL_SERVER_ERROR = 500 181 | RESPONSECODE_INVALID_INPUT = 0 182 | SANDBOX = 'sandbox' 183 | API_BASEURL = 'api_base_url' 184 | API_VERSION = 'api_version' 185 | CURRENT_USER_EMAIL = 'current_user_email' 186 | ACTION = 'action' 187 | DUPLICATE_FIELD = 'duplicate_field' 188 | NO_CONTENT = 'No Content' 189 | FAULTY_RESPONSE_CODES = [RESPONSECODE_NO_CONTENT, RESPONSECODE_NOT_FOUND, RESPONSECODE_AUTHORIZATION_ERROR, RESPONSECODE_BAD_REQUEST, RESPONSECODE_FORBIDDEN, RESPONSECODE_INTERNAL_SERVER_ERROR, RESPONSECODE_METHOD_NOT_ALLOWED, RESPONSECODE_MOVED_PERMANENTLY, RESPONSECODE_MOVED_TEMPORARILY, RESPONSECODE_REQUEST_ENTITY_TOO_LARGE, RESPONSECODE_TOO_MANY_REQUEST, RESPONSECODE_UNSUPPORTED_MEDIA_TYPE].freeze 190 | ATTACHMENT_URL = 'attachmentUrl' 191 | ACCESS_TOKEN_EXPIRY = 'X-ACCESSTOKEN-RESET' 192 | CURR_WINDOW_API_LIMIT = 'X-RATELIMIT-LIMIT' 193 | CURR_WINDOW_REMAINING_API_COUNT = 'X-RATELIMIT-REMAINING' 194 | CURR_WINDOW_RESET = 'X-RATELIMIT-RESET' 195 | API_COUNT_REMAINING_FOR_THE_DAY = 'X-RATELIMIT-DAY-REMAINING' 196 | API_LIMIT_FOR_THE_DAY = 'X-RATELIMIT-DAY-LIMIT' 197 | INVENTORY_MODULES = ["Invoices", "Sales_Orders","Purchase_Orders","Quotes"] 198 | end 199 | # THIS CLASS IS USED TO FIRE THE API REQUEST 200 | class ZohoHTTPConnector 201 | attr_accessor :url, :req_headers, :req_method, :req_params, :req_body, :api_key, :is_bulk_req, :form_data 202 | def self.get_instance(url, params = nil, headers = nil, body = nil, method = nil, api_key = 'data', is_bulk_req = false, form_data = nil) 203 | ZohoHTTPConnector.new(url, params, headers, body, method, api_key, is_bulk_req, form_data) 204 | end 205 | 206 | def initialize(url, params, headers, body, method, api_key, is_bulk_req, form_data = nil) 207 | @url = url 208 | @req_headers = headers 209 | @req_method = method 210 | @req_params = params 211 | @req_body = body 212 | @api_key = api_key 213 | @req_form_data = form_data 214 | @is_bulk_req = is_bulk_req 215 | end 216 | 217 | def trigger_request 218 | unless @req_params.nil? 219 | @req_params.each do |param_key, value| 220 | @req_params[param_key] = CGI.escape(value) if value.is_a? String 221 | end 222 | end 223 | query_string = @req_params.to_a.map { |x| "#{x[0]}=#{x[1]}" }.join('&') 224 | if !query_string.nil? && (query_string.strip != '') 225 | @url += '?' + query_string 226 | end 227 | url = URI(@url) 228 | http = Net::HTTP.new(url.host, url.port) 229 | http.use_ssl = true 230 | if @req_method == APIConstants::REQUEST_METHOD_GET 231 | req = Net::HTTP::Get.new(url.request_uri) 232 | elsif @req_method == APIConstants::REQUEST_METHOD_POST 233 | req = Net::HTTP::Post.new(url.request_uri) 234 | req.body = @req_body.to_s 235 | elsif @req_method == APIConstants::REQUEST_METHOD_PUT 236 | req = Net::HTTP::Put.new(url.request_uri) 237 | req.body = @req_body.to_s 238 | elsif @req_method == APIConstants::REQUEST_METHOD_PATCH 239 | req = Net::HTTP::Patch.new(url.request_uri) 240 | req.body = @req_body.to_s 241 | elsif @req_method == APIConstants::REQUEST_METHOD_DELETE 242 | req = Net::HTTP::Delete.new(url.request_uri) 243 | end 244 | @req_headers.each { |key, value| req.add_field(key, value) } 245 | unless @req_form_data.nil? 246 | req.set_form @req_form_data, 'multipart/form-data' 247 | end 248 | response = http.request(req) 249 | response 250 | end 251 | 252 | def self.set_url(url) 253 | @url = url 254 | end 255 | 256 | def self.get_url 257 | @url 258 | end 259 | 260 | def add_http_header(key, value) 261 | @req_headers[key] = value 262 | end 263 | 264 | def get_http_headers 265 | req_headers 266 | end 267 | 268 | def set_http_request_method(method) 269 | @req_method = method 270 | end 271 | 272 | def get_http_request_method 273 | @req_method 274 | end 275 | 276 | def set_request_body(req_body) 277 | @req_body = req_body 278 | end 279 | 280 | def get_request_body 281 | @req_body 282 | end 283 | 284 | def add_http_request_params(key, value) 285 | @req_params.store(key, value) 286 | end 287 | 288 | def get_http_request_params 289 | @req_params 290 | end 291 | end 292 | # THIS CLASS IS USED TO HANDLE ZCRM EXCEPTION 293 | class ZCRMException < StandardError 294 | attr_accessor :url, :status_code, :error_message, :exception_code, :error_details, :error_content 295 | def initialize(url, status_code, err_message, exception_code = 'error', details = nil, content = nil) 296 | @url = url 297 | @status_code = status_code 298 | @error_message = err_message 299 | @exception_code = exception_code 300 | @error_details = details 301 | @error_content = content 302 | SDKLogger.add_log(error_message, 'error', self) 303 | end 304 | 305 | def self.get_instance(url, status_code, err_message, exception_code = 'error', details = nil, content = nil) 306 | ZCRMException.new(url, status_code, err_message, exception_code, details, content) 307 | end 308 | end 309 | end 310 | end 311 | -------------------------------------------------------------------------------- /lib/ZCRMSDK/oauth_client.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'json' 4 | require_relative 'oauth_utility' 5 | require_relative 'persistence' 6 | module ZCRMSDK 7 | module OAuthClient 8 | # THIS CLASS IS USED TO STORE OAUTH RELATED CREDENTIALS 9 | class ZohoOAuth 10 | $OAUTH_CONFIG_PROPERTIES = {} 11 | def self.get_instance(config_details) 12 | ZohoOAuth.new(config_details) 13 | end 14 | 15 | def initialize(config_details) 16 | $OAUTH_CONFIG_PROPERTIES = {} 17 | $OAUTH_CONFIG_PROPERTIES = config_details 18 | mandatory_keys = [OAuthUtility::ZohoOAuthConstants::CLIENT_ID, OAuthUtility::ZohoOAuthConstants::CLIENT_SECRET, OAuthUtility::ZohoOAuthConstants::REDIRECT_URL] 19 | mandatory_keys.each do |item| 20 | if $OAUTH_CONFIG_PROPERTIES[item].nil? 21 | raise OAuthUtility::ZohoOAuthException.get_instance('initialize(config_details)', item + ' is mandatory!', 'Exception occured while reading oauth configurations', OAuthUtility::ZohoOAuthConstants::ERROR) 22 | end 23 | end 24 | if $OAUTH_CONFIG_PROPERTIES.key? OAuthUtility::ZohoOAuthConstants::CURRENT_USER_EMAIL 25 | unless $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::CURRENT_USER_EMAIL].nil? 26 | ZCRMSDK::RestClient::ZCRMRestClient.current_user_email = $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::CURRENT_USER_EMAIL] 27 | end 28 | end 29 | if $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::ACCESS_TYPE].nil? 30 | $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::ACCESS_TYPE] = 'offline' 31 | end 32 | if $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::PERSISTENCE_HANDLER_CLASS_PATH].nil? 33 | $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::PERSISTENCE_HANDLER_CLASS_PATH] = nil 34 | end 35 | if $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::PERSISTENCE_HANDLER_CLASS].nil? 36 | $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::PERSISTENCE_HANDLER_CLASS] = nil 37 | end 38 | if $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::IAM_URL].nil? 39 | $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::IAM_URL] = 'https://accounts.zoho.com' 40 | end 41 | if $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::TOKEN_PERSISTENCE_PATH].nil? 42 | $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::TOKEN_PERSISTENCE_PATH] = nil 43 | if $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::DATABASE_PORT].nil? 44 | $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::DATABASE_PORT] = '3306' 45 | end 46 | if $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::DATABASE_USERNAME].nil? 47 | $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::DATABASE_USERNAME] = 'root' 48 | end 49 | if $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::DATABASE_PASSWORD].nil? 50 | $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::DATABASE_PASSWORD] = '' 51 | end 52 | end 53 | if $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::SANDBOX].nil? 54 | $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::SANDBOX] = 'false' 55 | end 56 | oauth_params = OAuthUtility::ZohoOAuthParams.get_instance($OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::CLIENT_ID].dup, $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::CLIENT_SECRET].dup, $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::REDIRECT_URL].dup) 57 | ZohoOAuthClient.get_instance(oauth_params) 58 | end 59 | 60 | def self.get_grant_url 61 | ($OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::IAM_URL].dup + '/oauth/v2/auth') 62 | end 63 | 64 | def self.get_token_url 65 | ($OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::IAM_URL].dup + '/oauth/v2/token') 66 | end 67 | 68 | def self.get_refresh_token_url 69 | ($OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::IAM_URL].dup + '/oauth/v2/token') 70 | end 71 | 72 | def self.get_revoke_token_url 73 | ($OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::IAM_URL].dup + '/oauth/v2/token/revoke') 74 | end 75 | 76 | def self.get_user_info_url 77 | ($OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::IAM_URL].dup + '/oauth/user/info') 78 | end 79 | 80 | def self.get_client_instance 81 | oauth_client_ins = ZohoOAuthClient.get_instance 82 | if oauth_client_ins.nil? 83 | raise OAuthUtility::ZohoOAuthException.get_instance('get_client_instance', 'ZCRMSDK::RestClient::ZCRMRestClient.init(config_details) must be called before this', 'Error occured while getting client instance', OAuthUtility::ZohoOAuthConstants::ERROR) 84 | end 85 | 86 | oauth_client_ins 87 | end 88 | 89 | def self.get_persistence_instance 90 | if !$OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::PERSISTENCE_HANDLER_CLASS_PATH].nil? 91 | if !File.exist?($OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::PERSISTENCE_HANDLER_CLASS_PATH]) 92 | raise OAuthUtility::ZohoOAuthException.get_instance('get_persistence_instance', 'file does not exist!', 'Error occured while getting persistence instance', OAuthUtility::ZohoOAuthConstants::ERROR) 93 | end 94 | 95 | require $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::PERSISTENCE_HANDLER_CLASS_PATH] 96 | if $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::PERSISTENCE_HANDLER_CLASS].nil? 97 | raise OAuthUtility::ZohoOAuthException.get_instance('get_persistence_instance', 'class name not given', 'Exception occured while getting persistence instance', OAuthUtility::ZohoOAuthConstants::ERROR) 98 | end 99 | 100 | class_name = $OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::PERSISTENCE_HANDLER_CLASS].dup 101 | begin 102 | persistence_instance = Object.const_get(class_name).new 103 | rescue NameError 104 | raise OAuthUtility::ZohoOAuthException.get_instance('get_persistence_instance', 'Please check the handler class details', 'Error occured while getting persistence instance', OAuthUtility::ZohoOAuthConstants::ERROR) 105 | end 106 | persistence_instance 107 | elsif !$OAUTH_CONFIG_PROPERTIES[OAuthUtility::ZohoOAuthConstants::TOKEN_PERSISTENCE_PATH].nil? 108 | Persistence::ZohoOAuthFilePersistenceHandler.get_instance 109 | else 110 | require 'mysql2' 111 | Persistence::ZohoOAuthPersistenceHandler.get_instance 112 | end 113 | end 114 | end 115 | # THIS CLASS IS USED TO GENERATED TOKENS 116 | class ZohoOAuthClient 117 | @@oauth_params = nil 118 | @@oauth_client_instance = nil 119 | def initialize(oauth_params) 120 | @@oauth_params = oauth_params 121 | end 122 | 123 | def self.get_oauth_params 124 | @@oauth_params 125 | end 126 | 127 | def self.get_instance(param = nil) 128 | if !param.nil? 129 | @@oauth_client_instance = ZohoOAuthClient.new(param) 130 | end 131 | @@oauth_client_instance 132 | end 133 | 134 | def get_access_token(user_email) 135 | handler = ZohoOAuth.get_persistence_instance 136 | oauth_tokens = handler.get_oauth_tokens(user_email) 137 | begin 138 | return oauth_tokens.get_access_token 139 | rescue ZCRMSDK::OAuthUtility::ZohoOAuthException 140 | oauth_tokens = refresh_access_token(oauth_tokens.refresh_token, user_email) 141 | return oauth_tokens.access_token 142 | end 143 | end 144 | 145 | def generate_access_token_from_refresh_token(refresh_token,user_email) 146 | refresh_access_token(refresh_token, user_email) 147 | end 148 | 149 | def refresh_access_token(refresh_token, user_email) 150 | if refresh_token.nil? 151 | raise OAuthUtility::ZohoOAuthException.get_instance('refresh_access_token(refresh_token, user_email)', 'Refresh token not provided!', 'Exception occured while refreshing oauthtoken', OAuthUtility::ZohoOAuthConstants::ERROR) 152 | end 153 | 154 | begin 155 | connector = get_connector(ZohoOAuth.get_refresh_token_url) 156 | connector.add_http_request_params(OAuthUtility::ZohoOAuthConstants::GRANT_TYPE, OAuthUtility::ZohoOAuthConstants::GRANT_TYPE_REFRESH) 157 | connector.add_http_request_params(OAuthUtility::ZohoOAuthConstants::REFRESH_TOKEN, refresh_token) 158 | connector.set_http_request_method(OAuthUtility::ZohoOAuthConstants::REQUEST_METHOD_POST) 159 | response = connector.trigger_request 160 | response_json = JSON.parse(response.body) 161 | if response_json[OAuthUtility::ZohoOAuthConstants::ACCESS_TOKEN].nil? 162 | raise OAuthUtility::ZohoOAuthException.get_instance('refresh_access_token(refresh_token, user_email)', 'Response is' + response_json.to_s, 'Exception occured while refreshing oauthtoken', OAuthUtility::ZohoOAuthConstants::ERROR) 163 | else 164 | oauth_tokens = get_tokens_from_json(response_json) 165 | oauth_tokens.user_identifier = user_email 166 | oauth_tokens.refresh_token = refresh_token 167 | ZohoOAuth.get_persistence_instance.save_oauth_tokens(oauth_tokens) 168 | return oauth_tokens 169 | end 170 | end 171 | end 172 | 173 | def generate_access_token(grant_token) 174 | if grant_token.nil? 175 | raise OAuthUtility::ZohoOAuthException.get_instance('generate_access_token(grant_token)', 'Grant token not provided!', 'Exception occured while fetching accesstoken from Grant Token', OAuthUtility::ZohoOAuthConstants::ERROR) 176 | end 177 | 178 | connector = get_connector(ZohoOAuth.get_token_url) 179 | connector.add_http_request_params(OAuthUtility::ZohoOAuthConstants::GRANT_TYPE, OAuthUtility::ZohoOAuthConstants::GRANT_TYPE_AUTH_CODE) 180 | connector.add_http_request_params(OAuthUtility::ZohoOAuthConstants::CODE, grant_token) 181 | connector.set_http_request_method(OAuthUtility::ZohoOAuthConstants::REQUEST_METHOD_POST) 182 | response = connector.trigger_request 183 | response_json = JSON.parse(response.body) 184 | if !response_json[OAuthUtility::ZohoOAuthConstants::ACCESS_TOKEN].nil? 185 | oauth_tokens = get_tokens_from_json(response_json) 186 | oauth_tokens.user_identifier = get_user_email_from_iam(oauth_tokens.access_token) 187 | ZohoOAuth.get_persistence_instance.save_oauth_tokens(oauth_tokens) 188 | return oauth_tokens 189 | else 190 | raise OAuthUtility::ZohoOAuthException.get_instance('generate_access_token(grant_token)', 'Response is' + response_json.to_s, 'Exception occured while fetching accesstoken from Grant Token', OAuthUtility::ZohoOAuthConstants::ERROR) 191 | end 192 | end 193 | 194 | def get_tokens_from_json(response_json) 195 | expires_in = response_json[OAuthUtility::ZohoOAuthConstants::EXPIRES_IN] 196 | unless response_json.has_key?(OAuthUtility::ZohoOAuthConstants::EXPIRES_IN_SEC) 197 | expires_in = expires_in * 1000 198 | end 199 | expires_in += ZCRMSDK::OAuthClient::ZohoOAuthTokens.get_current_time_in_millis 200 | access_token = response_json[OAuthUtility::ZohoOAuthConstants::ACCESS_TOKEN] 201 | refresh_token = nil 202 | unless response_json[OAuthUtility::ZohoOAuthConstants::REFRESH_TOKEN].nil? 203 | refresh_token = response_json[OAuthUtility::ZohoOAuthConstants::REFRESH_TOKEN] 204 | end 205 | oauth_tokens = ZohoOAuthTokens.get_instance(refresh_token, access_token, expires_in) 206 | oauth_tokens 207 | end 208 | 209 | def get_connector(url) 210 | connector = OAuthUtility::ZohoOAuthHTTPConnector.get_instance(url, {}) 211 | connector.add_http_request_params(OAuthUtility::ZohoOAuthConstants::CLIENT_ID, OAuthClient::ZohoOAuthClient.get_oauth_params.client_id) 212 | connector.add_http_request_params(OAuthUtility::ZohoOAuthConstants::CLIENT_SECRET, OAuthClient::ZohoOAuthClient.get_oauth_params.client_secret) 213 | connector.add_http_request_params(OAuthUtility::ZohoOAuthConstants::REDIRECT_URL, OAuthClient::ZohoOAuthClient.get_oauth_params.redirect_uri) 214 | connector 215 | end 216 | 217 | def get_user_email_from_iam(access_token) 218 | begin 219 | header = {} 220 | header[OAuthUtility::ZohoOAuthConstants::AUTHORIZATION] = OAuthUtility::ZohoOAuthConstants::OAUTH_HEADER_PREFIX + access_token 221 | connector = OAuthUtility::ZohoOAuthHTTPConnector.get_instance(ZohoOAuth.get_user_info_url, nil, header, nil, OAuthUtility::ZohoOAuthConstants::REQUEST_METHOD_GET) 222 | response = connector.trigger_request 223 | JSON.parse(response.body)[OAuthUtility::ZohoOAuthConstants::EMAIL] 224 | rescue StandardError => e 225 | raise OAuthUtility::ZohoOAuthException.get_instance('generate_access_token(grant_token)', 'Exception occured while fetching User Id from access Token,Make sure AAAserver.profile.Read scope is included while generating the Grant token', 'Exception occured while fetching User Id from access Token', OAuthUtility::ZohoOAuthConstants::ERROR) 226 | end 227 | end 228 | end 229 | # THIS CLASS IS USED TO STORE THE TOKEN AS A INSTANCE AND CHECK THE VALIDITY OF THE TOKEN 230 | class ZohoOAuthTokens 231 | attr_accessor :refresh_token, :access_token, :expiry_time, :user_email, :user_identifier 232 | @user_email = nil 233 | def self.get_instance(refresh_token, access_token, expiry_time, user_identifier = nil) 234 | ZohoOAuthTokens.new(refresh_token, access_token, expiry_time, user_identifier) 235 | end 236 | 237 | def initialize(refresh_token, access_token, expiry_time, user_identifier = nil) 238 | @refresh_token = refresh_token 239 | @access_token = access_token 240 | @expiry_time = expiry_time 241 | @user_identifier = user_identifier 242 | end 243 | 244 | def get_access_token 245 | if (@expiry_time - ZCRMSDK::OAuthClient::ZohoOAuthTokens.get_current_time_in_millis) > 15_000 246 | @access_token 247 | else 248 | raise OAuthUtility::ZohoOAuthException.get_instance('get_access_token', 'Access token got expired!', 'Access token expired hence refreshing', OAuthUtility::ZohoOAuthConstants::INFO) 249 | end 250 | end 251 | 252 | def self.get_current_time_in_millis 253 | (Time.now.to_f * 1000).to_i 254 | end 255 | end 256 | end 257 | end 258 | -------------------------------------------------------------------------------- /spec/record_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'mysql2' 4 | require 'json' 5 | activity_module = %w[Tasks Events Calls] 6 | sort_order_module = %w[Leads Vendors Price_Books Products Campaigns Solutions Accounts Contacts Deals Quotes Sales_Orders Purchase_Orders Invoices Cases Tasks Events Calls] 7 | config_details = { 'client_id' => 'client_id', 'client_secret' => 'client_secret', 'redirect_uri' => 'www.zoho.com', 'api_base_url' => 'https://www.zohoapis.com', 'api_version' => 'v2', 'sandbox' => 'false', 'application_log_file_path' => nil, 'current_user_email' => 'current_user_email', 'db_port' => '3306' } 8 | ZCRMSDK::RestClient::ZCRMRestClient.init(config_details) 9 | rest = ZCRMSDK::RestClient::ZCRMRestClient.get_instance 10 | current_user = rest.get_organization_instance.get_current_user.data[0] 11 | current_user_id = current_user.id 12 | current_user_name = current_user.full_name 13 | file_path = '/Users/path/Downloads/resource.jpg' 14 | file_link = 'https://archive.org/download/android_logo_low_quality/android_logo_low_quality.jpg' 15 | con = Mysql2::Client.new(host: config_details['db_address'], username: config_details['db_username'], password: config_details['db_password'], database: 'zohooauth', port: config_details['db_port']) 16 | query = "select * from oauthtokens where useridentifier='" + config_details['current_user_email'] + "'" 17 | rs = con.query(query) 18 | oauth_tokens = nil 19 | accesstoken = nil 20 | rs.each do |row| 21 | accesstoken = row['accesstoken'] 22 | con.close 23 | end 24 | url = URI('https://zohoapis.com/crm/v2/Contacts/roles') 25 | http = Net::HTTP.new(url.host, url.port) 26 | req = Net::HTTP::Get.new(url.request_uri) 27 | accesstoken = 'Zoho-oauthtoken ' + accesstoken 28 | req.add_field('Authorization', accesstoken) 29 | http.use_ssl = true 30 | response = http.request(req) 31 | contact_role_id = JSON.parse(response.body)['contact_roles'][0]['id'] 32 | modules = [] 33 | record_count = 1 34 | modules = rest.get_all_modules.data 35 | module_api_names = [] 36 | creatable_module_api_names = [] 37 | created_record = {} 38 | deleted_record_response = {} 39 | convert_lead_response = nil 40 | add_note_response = {} 41 | update_note_response = {} 42 | added_note = {} 43 | updated_note = {} 44 | deleted_note = {} 45 | note_ids = {} 46 | upload_attachment_response = {} 47 | upload_attachment_link_response = {} 48 | get_attachment_response = {} 49 | download_attachment_response = {} 50 | delete_attachment_attachment_response = {} 51 | upload_photo_response = {} 52 | download_photo_response = {} 53 | delete_photo_response = {} 54 | add_tags_record = {} 55 | remove_tags_record = {} 56 | add_relation_response = {} 57 | remove_relation_response = {} 58 | get_relatedrecords = {} 59 | tag_delete_response = nil 60 | tag_merge_response = nil 61 | tag_update_response = nil 62 | note_upload_attachment_res = nil 63 | note_download_attachment_res = nil 64 | note_delete_attachment_res = [] 65 | note_get_attachment = nil 66 | modulevsfields = {} # moduleapiname vs all fields data 67 | moduleapinamevsfieldsarrayvsfielddetail = {} 68 | modules.each do |module_instance| 69 | if module_instance.is_api_supported 70 | module_api_names.push(module_instance.api_name) 71 | end 72 | if module_instance.is_quick_create 73 | creatable_module_api_names.push(module_instance.api_name) 74 | end 75 | end 76 | sort_order_module.each do |module_apiname| 77 | if creatable_module_api_names.include? module_apiname 78 | creatable_module_api_names -= [module_apiname] 79 | creatable_module_api_names.push(module_apiname) 80 | end 81 | end 82 | #module_api_names = %w[Leads Contacts Price_Books Accounts Deals Activities Products Quotes Sales_Orders Purchase_Orders Invoices Campaigns Vendors Price_Books Cases Solutions Visits Tasks Events Notes Attachments Calls Actions_Performed Approvals] 83 | #module_api_names = %w[Leads Vendors Price_Books Products Campaigns Solutions Accounts Contacts Deals Quotes Sales_Orders Purchase_Orders Invoices Cases Tasks Events Calls] 84 | #module_api_names = %w[Leads Price_Books Products Campaigns Accounts Contacts Deals] 85 | module_api_names.each do |module_api_name| # fields 86 | if module_api_name != 'Approvals' 87 | module_instance = ZCRMSDK::Operations::ZCRMModule.get_instance(module_api_name) 88 | modulevsfields[module_api_name] = module_instance.get_all_fields.data 89 | end 90 | end 91 | module_api_names.each do |module_api_name| # setting module vs fields 92 | next unless module_api_name != 'Approvals' 93 | 94 | fieldsarray = {} 95 | modulevsfields[module_api_name].each do |field| 96 | fielddetails = {} 97 | next unless (field.field_layout_permissions.include?('CREATE') || field.api_name == 'Tag') && field.api_name != 'Exchange_Rate' 98 | 99 | fielddetails = {} 100 | if field.field_layout_permissions.include?('EDIT') 101 | fielddetails['editable'] == true 102 | end 103 | fielddetails['data_type'] = field.data_type 104 | fielddetails['decimal_place'] = field.decimal_place 105 | fielddetails['field_label'] = field.field_label 106 | fielddetails['length'] = field.length unless field.length.nil? 107 | if field.data_type == 'lookup' 108 | fielddetails['lookup'] = field.lookup_field 109 | elsif field.data_type == 'multiselectlookup' 110 | fielddetails['multiselectlookup'] = field.multiselectlookup 111 | elsif field.data_type == 'picklist' || field.data_type == 'multiselectpicklist' 112 | fielddetails['picklist'] = field.picklist_values 113 | elsif field.data_type == 'currency' 114 | fielddetails['precision'] = field.precision 115 | fielddetails['rounding_option'] = field.rounding_option 116 | end 117 | fieldsarray[field.api_name] = fielddetails 118 | end 119 | moduleapinamevsfieldsarrayvsfielddetail[module_api_name] = fieldsarray 120 | end 121 | #creatable_module_api_names = %w[Leads Price_Books Products Campaigns Accounts Contacts Deals] 122 | creatable_module_api_names.each do |creatable_module_api_name| # create() 123 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, nil) 124 | moduleapinamevsfieldsarrayvsfielddetail[creatable_module_api_name].each do |field_api_name, field_details| 125 | datatype = field_details['data_type'] 126 | length = field_details['length'] 127 | fieldlabel = field_details['field_label'] 128 | lookup_ins = field_details['lookup'] 129 | if datatype == 'ownerlookup' 130 | record1.owner = ZCRMSDK::Operations::ZCRMUser.get_instance(current_user_id) 131 | elsif fieldlabel == 'Pricing Details' 132 | price_ins = ZCRMSDK::Operations::ZCRMPriceBookPricing.get_instance 133 | price_ins.from_range = 1 134 | price_ins.to_range = 100 135 | price_ins.discount = 5 136 | record1.price_details = [price_ins] 137 | elsif fieldlabel == 'Product Details' 138 | line_item_instance = ZCRMSDK::Operations::ZCRMInventoryLineItem.get_instance(ZCRMSDK::Operations::ZCRMRecord.get_instance('Products', created_record['Products'][0].entity_id)) 139 | line_item_instance.description = 'ruby_automation_lineitem' 140 | line_item_instance.list_price = 123 141 | line_item_instance.quantity = 10 142 | line_item_instance.discount = 10 143 | record1.line_items.push(line_item_instance) 144 | elsif fieldlabel == 'Participants' 145 | record1.field_data[field_api_name] = [{ 'type' => 'user', 'participant' => current_user_id }] 146 | elsif fieldlabel == 'Call Duration' 147 | record1.field_data[field_api_name] = '10:00' 148 | elsif datatype == 'lookup' 149 | if created_record[lookup_ins.module_apiname] 150 | record1.field_data[field_api_name] = created_record[lookup_ins.module_apiname][0].entity_id 151 | end 152 | if lookup_ins.module_apiname == 'se_module' 153 | record1.field_data['$se_module'] = 'Accounts' 154 | record1.field_data[field_api_name] = { 'id' => created_record['Accounts'][0].entity_id } 155 | end 156 | elsif datatype == 'text' 157 | word = '1234567890' 158 | word = word[0, length - 1] 159 | record1.field_data[field_api_name] = word 160 | elsif datatype == 'RRULE' 161 | if creatable_module_api_name == 'Events' 162 | record1.field_data[field_api_name] = { 'RRULE' => 'FREQ=YEARLY;INTERVAL=99;DTSTART=2017-08-29;UNTIL=2017-08-29' } 163 | else 164 | record1.field_data[field_api_name] = { 'RRULE' => 'FREQ=DAILY;INTERVAL=99;DTSTART=2017-08-29;UNTIL=2017-08-29' } 165 | end 166 | elsif datatype == 'event_reminder' 167 | record1.field_data[field_api_name] = '0' 168 | elsif datatype == 'ALARM' 169 | record1.field_data[field_api_name] = { 'ALARM' => 'FREQ=DAILY;ACTION=EMAIL;TRIGGER=DATE-TIME:2019-10-29T17:59:00+05:30' } 170 | elsif datatype == 'picklist' 171 | if field_details['picklist'].length > 1 172 | record1.field_data[field_api_name] = field_details['picklist'][1].display_value 173 | elsif 174 | record1.field_data[field_api_name] = field_details['picklist'][0].display_value 175 | end 176 | elsif datatype == 'multiselectpicklist' 177 | record1.field_data[field_api_name] = [field_details['picklist'][0].display_value] 178 | elsif datatype == 'email' 179 | record1.field_data[field_api_name] = 'rubysdk+automation@zoho.com' 180 | elsif datatype == 'fileupload' 181 | # record1.field_data[field_api_name]=[{"file_id"=>fileid}] 182 | elsif datatype == 'website' 183 | record1.field_data[field_api_name] = 'www.zoho.com' 184 | elsif datatype == 'integer' || datatype == 'bigint' 185 | record1.field_data[field_api_name] = 123 186 | elsif datatype == 'phone' 187 | record1.field_data[field_api_name] = '123' 188 | elsif datatype == 'currency' 189 | record1.field_data[field_api_name] = 123 190 | elsif datatype == 'boolean' 191 | record1.field_data[field_api_name] = true 192 | elsif datatype == 'date' 193 | record1.field_data[field_api_name] = '2019-07-11' 194 | elsif datatype == 'double' 195 | record1.field_data[field_api_name] = 2.1 196 | elsif datatype == 'textarea' 197 | record1.field_data[field_api_name] = 'ruby_automation_at_work' 198 | elsif datatype == 'datetime' 199 | record1.field_data[field_api_name] = '2019-06-15T15:53:00+05:30' 200 | end 201 | end 202 | create_record_response = record1.create 203 | if create_record_response.code == 'SUCCESS' 204 | create_record_id = create_record_response.details['id'] 205 | created_record[creatable_module_api_name] = [ZCRMSDK::Operations::ZCRMModule.get_instance(creatable_module_api_name).get_record(create_record_id).data] 206 | end 207 | end 208 | creatable_module_api_names.each do |creatable_module_api_name| 209 | if creatable_module_api_name != 'Calls' 210 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 211 | upload_attachment_response[creatable_module_api_name] = record1.upload_attachment(file_path) 212 | end 213 | end 214 | creatable_module_api_names.each do |creatable_module_api_name| 215 | if creatable_module_api_name != 'Calls' 216 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 217 | upload_attachment_link_response[creatable_module_api_name] = record1.upload_link_as_attachment(file_link) 218 | end 219 | end 220 | creatable_module_api_names.each do |creatable_module_api_name| 221 | if creatable_module_api_name != 'Calls' 222 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 223 | get_attachment_response[creatable_module_api_name] = record1.get_attachments.data 224 | end 225 | end 226 | creatable_module_api_names.each do |creatable_module_api_name| 227 | if creatable_module_api_name != 'Calls' 228 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 229 | download_attachment_response[creatable_module_api_name] = record1.download_attachment(upload_attachment_response[creatable_module_api_name].details['id']) 230 | end 231 | end 232 | creatable_module_api_names.each do |creatable_module_api_name| 233 | next unless creatable_module_api_name != 'Calls' 234 | 235 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 236 | delete_attachment_attachment_response[creatable_module_api_name] = [] 237 | delete_attachment_attachment_response[creatable_module_api_name].push(record1.delete_attachment(upload_attachment_response[creatable_module_api_name].details['id'])) 238 | delete_attachment_attachment_response[creatable_module_api_name].push(record1.delete_attachment(upload_attachment_link_response[creatable_module_api_name].details['id'])) 239 | end 240 | creatable_module_api_names.each do |creatable_module_api_name| 241 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 242 | note = ZCRMSDK::Operations::ZCRMNote.get_instance(record1, nil) 243 | note.title = 'ruby_automation_note_create' 244 | note.content = 'ruby_automation_note_create' 245 | add_note_response[creatable_module_api_name] = record1.add_note(note) 246 | note_ids[creatable_module_api_name] = add_note_response[creatable_module_api_name].details['id'] 247 | next unless creatable_module_api_names[0] == creatable_module_api_name 248 | 249 | note.id = note_ids[creatable_module_api_name] 250 | note_upload_attachment_res = note.upload_attachment(file_path) 251 | note_get_attachment = note.get_attachments.data 252 | note_download_attachment_res = note.download_attachment(note_upload_attachment_res.details['id']) 253 | note_delete_attachment_res.push(note.delete_attachment(note_upload_attachment_res.details['id'])) 254 | end 255 | 256 | creatable_module_api_names.each do |creatable_module_api_name| 257 | if add_note_response[creatable_module_api_name].code == 'SUCCESS' 258 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 259 | added_note[creatable_module_api_name] = record1.get_notes.data 260 | end 261 | end 262 | 263 | creatable_module_api_names.each do |creatable_module_api_name| 264 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 265 | note = ZCRMSDK::Operations::ZCRMNote.get_instance(record1, note_ids[creatable_module_api_name]) 266 | note.title = 'ruby_automation_note_update' 267 | note.content = 'ruby_automation_note_update' 268 | update_note_response[creatable_module_api_name] = record1.update_note(note) 269 | end 270 | 271 | creatable_module_api_names.each do |creatable_module_api_name| 272 | if update_note_response[creatable_module_api_name].code == 'SUCCESS' 273 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 274 | updated_note[creatable_module_api_name] = record1.get_notes.data 275 | end 276 | end 277 | 278 | creatable_module_api_names.each do |creatable_module_api_name| 279 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 280 | note = ZCRMSDK::Operations::ZCRMNote.get_instance(record1, note_ids[creatable_module_api_name]) 281 | deleted_note[creatable_module_api_name] = record1.delete_note(note) 282 | end 283 | creatable_module_api_names.each do |creatable_module_api_name| 284 | next unless %w[Leads Vendors Products Accounts Contacts].include?(creatable_module_api_name) 285 | 286 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 287 | upload_photo_response[creatable_module_api_name] = record1.upload_photo(file_path) 288 | download_photo_response[creatable_module_api_name] = record1.download_photo 289 | delete_photo_response[creatable_module_api_name] = record1.delete_photo 290 | end 291 | creatable_module_api_names.each do |creatable_module_api_name| 292 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 293 | tagnames = %w[ruby_automation_tag_1 ruby_automation_tag_2] 294 | add_tags_record[creatable_module_api_name] = record1.add_tags(tagnames) 295 | remove_tags_record[creatable_module_api_name] = record1.remove_tags(tagnames) 296 | tags = ZCRMSDK::Operations::ZCRMModule.get_instance(creatable_module_api_name).get_tags.data 297 | tags.each(&:delete) 298 | end 299 | creatable_module_api_names.each do |creatable_module_api_name| 300 | next unless %w[Leads Price_Books Accounts Contacts Deals].include?(creatable_module_api_name) 301 | 302 | add_relation_response[creatable_module_api_name] = [] 303 | get_relatedrecords[creatable_module_api_name] = [] 304 | remove_relation_response[creatable_module_api_name] = [] 305 | if creatable_module_api_names.include?('Campaigns') && %w[Leads Contacts].include?(creatable_module_api_name) 306 | parent_record = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 307 | junction_record = ZCRMSDK::Operations::ZCRMJunctionRecord.get_instance('Campaigns', created_record['Campaigns'][0].entity_id) 308 | if creatable_module_api_name == 'Contacts' 309 | junction_record.related_data['Contact_Role'] = contact_role_id 310 | end 311 | add_relation_response[creatable_module_api_name].push(parent_record.add_relation(junction_record)) 312 | get_relatedrecords[creatable_module_api_name].push(parent_record.get_relatedlist_records('Campaigns').data) 313 | remove_relation_response[creatable_module_api_name].push(parent_record.remove_relation(junction_record)) 314 | end 315 | next unless creatable_module_api_names.include?('Products') 316 | 317 | parent_record = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 318 | junction_record = ZCRMSDK::Operations::ZCRMJunctionRecord.get_instance('Products', created_record['Products'][0].entity_id) 319 | if creatable_module_api_name == 'Price_Books' 320 | junction_record.related_data['list_price'] = 123.0 321 | end 322 | add_relation_response[creatable_module_api_name].push(parent_record.add_relation(junction_record)) 323 | get_relatedrecords[creatable_module_api_name].push(parent_record.get_relatedlist_records('Products').data) 324 | remove_relation_response[creatable_module_api_name].push(parent_record.remove_relation(junction_record)) 325 | end 326 | creatable_module_api_names.each do |creatable_module_api_name| # convert a lead 327 | next unless creatable_module_api_name == 'Leads' 328 | 329 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, nil) 330 | moduleapinamevsfieldsarrayvsfielddetail[creatable_module_api_name].each do |field_api_name, field_details| 331 | datatype = field_details['data_type'] 332 | length = field_details['length'] 333 | fieldlabel = field_details['field_label'] 334 | lookup_ins = field_details['lookup'] 335 | if datatype == 'ownerlookup' 336 | record1.owner = ZCRMSDK::Operations::ZCRMUser.get_instance(current_user_id) 337 | elsif fieldlabel == 'Pricing Details' 338 | price_ins = ZCRMSDK::Operations::ZCRMPriceBookPricing.get_instance 339 | price_ins.from_range = 1 340 | price_ins.to_range = 100 341 | price_ins.discount = 5 342 | record1.price_details = [price_ins] 343 | elsif fieldlabel == 'Product Details' 344 | line_item_instance = ZCRMSDK::Operations::ZCRMInventoryLineItem.get_instance(ZCRMSDK::Operations::ZCRMRecord.get_instance('Products', created_record['Products'][0].entity_id)) 345 | line_item_instance.description = 'ruby_automation_lineitem' 346 | line_item_instance.list_price = 123 347 | line_item_instance.quantity = 10 348 | line_item_instance.discount = 10 349 | record1.line_items.push(line_item_instance) 350 | elsif fieldlabel == 'Participants' 351 | record1.field_data[field_api_name] = [{ 'type' => 'user', 'participant' => current_user_id }] 352 | elsif fieldlabel == 'Call Duration' 353 | record1.field_data[field_api_name] = '10:00' 354 | elsif datatype == 'lookup' 355 | if created_record[lookup_ins.module_apiname] 356 | record1.field_data[field_api_name] = created_record[lookup_ins.module_apiname][0].entity_id 357 | end 358 | if lookup_ins.module_apiname == 'se_module' 359 | record1.field_data['$se_module'] = 'Accounts' 360 | record1.field_data[field_api_name] = { 'id' => created_record['Accounts'][0].entity_id } 361 | end 362 | elsif datatype == 'text' 363 | word = '1234567890' 364 | word = word[0, length - 1] 365 | record1.field_data[field_api_name] = word 366 | elsif datatype == 'RRULE' 367 | if creatable_module_api_name == 'Events' 368 | record1.field_data[field_api_name] = { 'RRULE' => 'FREQ=YEARLY;INTERVAL=99;DTSTART=2017-08-29;UNTIL=2017-08-29' } 369 | else 370 | record1.field_data[field_api_name] = { 'RRULE' => 'FREQ=DAILY;INTERVAL=99;DTSTART=2017-08-29;UNTIL=2017-08-29' } 371 | end 372 | elsif datatype == 'event_reminder' 373 | record1.field_data[field_api_name] = '0' 374 | elsif datatype == 'ALARM' 375 | record1.field_data[field_api_name] = { 'ALARM' => 'FREQ=DAILY;ACTION=EMAIL;TRIGGER=DATE-TIME:2019-10-29T17:59:00+05:30' } 376 | elsif datatype == 'picklist' 377 | if field_details['picklist'].length > 1 378 | record1.field_data[field_api_name] = field_details['picklist'][1].display_value 379 | elsif 380 | record1.field_data[field_api_name] = field_details['picklist'][0].display_value 381 | end 382 | elsif datatype == 'multiselectpicklist' 383 | record1.field_data[field_api_name] = [field_details['picklist'][0].display_value] 384 | elsif datatype == 'email' 385 | record1.field_data[field_api_name] = 'rubysdk+automation@zoho.com' 386 | elsif datatype == 'fileupload' 387 | # record1.field_data[field_api_name]=[{"file_id"=>fileid}] 388 | elsif datatype == 'website' 389 | record1.field_data[field_api_name] = 'www.zoho.com' 390 | elsif datatype == 'integer' || datatype == 'bigint' 391 | record1.field_data[field_api_name] = 123 392 | elsif datatype == 'phone' 393 | record1.field_data[field_api_name] = '123' 394 | elsif datatype == 'currency' 395 | record1.field_data[field_api_name] = 123 396 | elsif datatype == 'boolean' 397 | record1.field_data[field_api_name] = true 398 | elsif datatype == 'date' 399 | record1.field_data[field_api_name] = '2019-07-11' 400 | elsif datatype == 'double' 401 | record1.field_data[field_api_name] = 2.1 402 | elsif datatype == 'textarea' 403 | record1.field_data[field_api_name] = 'ruby_automation_at_work' 404 | elsif datatype == 'datetime' 405 | record1.field_data[field_api_name] = '2019-06-15T15:53:00+05:30' 406 | end 407 | end 408 | create_record_response = record1.create 409 | if create_record_response.code == 'SUCCESS' 410 | record1.entity_id = create_record_response.details['id'] 411 | end 412 | deal = ZCRMSDK::Operations::ZCRMRecord.get_instance('Deals', nil) 413 | deal.field_data = { 'Deal_Name' => 'test3', 'stage' => 'Qualification', 'Closing_Date' => '2016-03-30' } 414 | details = Array('overwrite' => TRUE, 'notify_lead_owner' => TRUE, 'notify_new_entity_owner' => TRUE, 'Accounts' => created_record['Accounts'][0].entity_id, 'Contacts' => created_record['Contacts'][0].entity_id, 'assign_to' => current_user_id) 415 | convert_lead_response = record1.convert(deal, details) 416 | deal.entity_id = convert_lead_response['Deals'] 417 | deal.delete 418 | end 419 | creatable_module_api_names.each do |creatable_module_api_name| 420 | next unless creatable_module_api_names[0] == creatable_module_api_name 421 | 422 | tags = [] 423 | tag1 = ZCRMSDK::Operations::ZCRMTag.get_instance(nil, 'ruby_automation_tag_test1') 424 | tags.push(tag1) 425 | tag2 = ZCRMSDK::Operations::ZCRMTag.get_instance(nil, 'ruby_automation_tag_test2') 426 | tags.push(tag2) 427 | tag_creation_response = ZCRMSDK::Operations::ZCRMModule.get_instance(creatable_module_api_name).create_tags(tags) 428 | tags_ins = tag_creation_response.data 429 | tags_ins[0].name = 'ruby_update_tag_test' 430 | tags_ins[0].module_apiname = creatable_module_api_name 431 | tag_update_response = tags_ins[0].update 432 | tag_merge_response = tags_ins[0].merge(tags_ins[1]) 433 | tag_delete_response = tags_ins[0].delete 434 | end 435 | creatable_module_api_names.reverse! 436 | creatable_module_api_names.each do |creatable_module_api_name| # delete() and delete_records() 437 | record1 = ZCRMSDK::Operations::ZCRMRecord.get_instance(creatable_module_api_name, created_record[creatable_module_api_name][0].entity_id) 438 | deleted_record_response[creatable_module_api_name] = record1.delete 439 | end 440 | 441 | RSpec.describe 'meta_data' do 442 | it 'note_upload_attachment' do 443 | expect(note_upload_attachment_res.code).to eql 'SUCCESS' 444 | end 445 | it 'note_download_attachment' do 446 | expect(note_download_attachment_res.status_code).to eql 200 447 | expect(note_download_attachment_res.filename).to eql 'resource.jpg' 448 | end 449 | it 'note_get_attachments' do 450 | note_get_attachment.each do |zcrmattachment_ins| 451 | expect(zcrmattachment_ins).to be_an_instance_of(ZCRMSDK::Operations::ZCRMAttachment) 452 | expect(zcrmattachment_ins.id).to be_a_kind_of(String) 453 | expect(zcrmattachment_ins.file_name).to eql('resource.jpg') 454 | expect(zcrmattachment_ins.type).to eql('Attachment') 455 | expect(zcrmattachment_ins.file_id).to be_a_kind_of(String) 456 | owner = zcrmattachment_ins.owner 457 | expect(owner).to be_an_instance_of(ZCRMSDK::Operations::ZCRMUser) 458 | expect(owner.id).to eql(current_user_id) 459 | expect(owner.name).to eql(current_user_name) 460 | created_by = zcrmattachment_ins.created_by 461 | expect(created_by).to be_an_instance_of(ZCRMSDK::Operations::ZCRMUser) 462 | expect(created_by.id).to eql(current_user_id) 463 | expect(created_by.name).to eql(current_user_name) 464 | modified_by = zcrmattachment_ins.modified_by 465 | unless modified_by.nil? 466 | expect(modified_by).to be_an_instance_of(ZCRMSDK::Operations::ZCRMUser) 467 | expect(modified_by.id).to eql(current_user_id) 468 | expect(modified_by.name).to eql(current_user_name) 469 | expect(zcrmattachment_ins.modified_time).to be_a_kind_of(String) 470 | end 471 | expect(zcrmattachment_ins.created_time).to be_a_kind_of(String) 472 | expect(zcrmattachment_ins.parent_module).to eql('Notes') 473 | expect(zcrmattachment_ins.parent_id).to be_a_kind_of(String) 474 | expect(zcrmattachment_ins.parent_name).to be_a_kind_of(String) 475 | expect(zcrmattachment_ins.size).to be_a_kind_of(String) 476 | expect(zcrmattachment_ins.is_editable).to be(true).or be(false) 477 | end 478 | end 479 | it 'note_delete_attachment' do 480 | expect(note_delete_attachment_res[0].status_code).to eql 200 481 | expect(note_delete_attachment_res[0].code).to eql 'SUCCESS' 482 | expect(note_delete_attachment_res[0].message).to eql 'record deleted' 483 | end 484 | it 'upload_attachment' do 485 | creatable_module_api_names.each do |creatable_module_api_name| 486 | if creatable_module_api_name != 'Calls' 487 | expect(upload_attachment_response[creatable_module_api_name].code).to eql 'SUCCESS' 488 | end 489 | end 490 | end 491 | it 'upload_attachment_as_link' do 492 | creatable_module_api_names.each do |creatable_module_api_name| 493 | if creatable_module_api_name != 'Calls' 494 | expect(upload_attachment_link_response[creatable_module_api_name].code).to eql 'SUCCESS' 495 | end 496 | end 497 | end 498 | it 'download_attachment' do 499 | creatable_module_api_names.each do |creatable_module_api_name| 500 | if creatable_module_api_name != 'Calls' 501 | expect(download_attachment_response[creatable_module_api_name].status_code).to eql 200 502 | expect(download_attachment_response[creatable_module_api_name].filename).to eql 'resource.jpg' 503 | end 504 | end 505 | end 506 | it 'delete_attachment' do 507 | creatable_module_api_names.each do |creatable_module_api_name| 508 | next unless creatable_module_api_name != 'Calls' 509 | 510 | expect(delete_attachment_attachment_response[creatable_module_api_name][0].status_code).to eql 200 511 | expect(delete_attachment_attachment_response[creatable_module_api_name][0].code).to eql 'SUCCESS' 512 | expect(delete_attachment_attachment_response[creatable_module_api_name][0].message).to eql 'record deleted' 513 | expect(delete_attachment_attachment_response[creatable_module_api_name][1].status_code).to eql 200 514 | expect(delete_attachment_attachment_response[creatable_module_api_name][1].code).to eql 'SUCCESS' 515 | expect(delete_attachment_attachment_response[creatable_module_api_name][1].message).to eql 'record deleted' 516 | end 517 | end 518 | it 'get_attachments' do 519 | creatable_module_api_names.each do |creatable_module_api_name| 520 | next unless creatable_module_api_name != 'Calls' 521 | 522 | get_attachment_response[creatable_module_api_name].each do |zcrmattachment_ins| 523 | expect(zcrmattachment_ins).to be_an_instance_of(ZCRMSDK::Operations::ZCRMAttachment) 524 | expect(zcrmattachment_ins.id).to be_a_kind_of(String) 525 | expect(zcrmattachment_ins.file_name).to eql('resource.jpg').or eql('android_logo_low_quality.jpg') 526 | expect(zcrmattachment_ins.type).to eql('Link URL').or eql('Attachment') 527 | if zcrmattachment_ins.type == 'Link URL' 528 | expect(zcrmattachment_ins.link_url).to eql(file_link) 529 | else 530 | expect(zcrmattachment_ins.file_id).to be_a_kind_of(String) 531 | end 532 | owner = zcrmattachment_ins.owner 533 | expect(owner).to be_an_instance_of(ZCRMSDK::Operations::ZCRMUser) 534 | expect(owner.id).to eql(current_user_id) 535 | expect(owner.name).to eql(current_user_name) 536 | created_by = zcrmattachment_ins.created_by 537 | expect(created_by).to be_an_instance_of(ZCRMSDK::Operations::ZCRMUser) 538 | expect(created_by.id).to eql(current_user_id) 539 | expect(created_by.name).to eql(current_user_name) 540 | modified_by = zcrmattachment_ins.modified_by 541 | unless modified_by.nil? 542 | expect(modified_by).to be_an_instance_of(ZCRMSDK::Operations::ZCRMUser) 543 | expect(modified_by.id).to eql(current_user_id) 544 | expect(modified_by.name).to eql(current_user_name) 545 | expect(zcrmattachment_ins.modified_time).to be_a_kind_of(String) 546 | end 547 | expect(zcrmattachment_ins.created_time).to be_a_kind_of(String) 548 | expect(zcrmattachment_ins.parent_module).to eql(creatable_module_api_name) 549 | expect(zcrmattachment_ins.parent_id).to be_a_kind_of(String) 550 | expect(zcrmattachment_ins.parent_name).to be_a_kind_of(String) 551 | expect(zcrmattachment_ins.size).to be_a_kind_of(String) 552 | expect(zcrmattachment_ins.is_editable).to be(true).or be(false) 553 | end 554 | end 555 | end 556 | it 'add_note' do 557 | creatable_module_api_names.each do |creatable_module_api_name| 558 | added_note[creatable_module_api_name].each do |zcrmnote_ins| 559 | expect(zcrmnote_ins.id).to be_a_kind_of(String) 560 | expect(zcrmnote_ins.title).to eql('ruby_automation_note_create') 561 | expect(zcrmnote_ins.content).to eql('ruby_automation_note_create') 562 | owner = zcrmnote_ins.owner 563 | expect(owner).to be_an_instance_of(ZCRMSDK::Operations::ZCRMUser) 564 | expect(owner.id).to eql(current_user_id) 565 | expect(owner.name).to eql(current_user_name) 566 | created_by = zcrmnote_ins.created_by 567 | expect(created_by).to be_an_instance_of(ZCRMSDK::Operations::ZCRMUser) 568 | expect(created_by.id).to eql(current_user_id) 569 | expect(created_by.name).to eql(current_user_name) 570 | expect(zcrmnote_ins.modified_time).to be_a_kind_of(String) 571 | expect(zcrmnote_ins.created_time).to be_a_kind_of(String) 572 | expect(zcrmnote_ins.is_voice_note).to be(false) 573 | if creatable_module_api_name == 'Accounts' 574 | expect(zcrmnote_ins.parent_module).to eql(creatable_module_api_name).or eql('Calls').or eql('Events').or eql('Tasks').or eql('Deals').or eql('Contacts') 575 | end 576 | if creatable_module_api_name == 'Contacts' 577 | expect(zcrmnote_ins.parent_module).to eql(creatable_module_api_name).or eql('Calls').or eql('Events').or eql('Tasks').or eql('Deals') 578 | end 579 | if creatable_module_api_name == 'Tasks' || creatable_module_api_name == 'Calls' || creatable_module_api_name == 'Events' 580 | expect(zcrmnote_ins.parent_module).to eql(creatable_module_api_name).or eql('Contacts') 581 | end 582 | expect(zcrmnote_ins.parent_id).to be_a_kind_of(String) 583 | expect(zcrmnote_ins.parent_name).to be_a_kind_of(String) 584 | expect(zcrmnote_ins.is_editable).to be(true) 585 | end 586 | end 587 | end 588 | it 'update_note' do 589 | creatable_module_api_names.each do |creatable_module_api_name| 590 | updated_note[creatable_module_api_name].each do |zcrmnote_ins| 591 | expect(zcrmnote_ins.id).to be_a_kind_of(String) 592 | expect(zcrmnote_ins.title).to eql('ruby_automation_note_update') 593 | expect(zcrmnote_ins.content).to eql('ruby_automation_note_update') 594 | owner = zcrmnote_ins.owner 595 | expect(owner).to be_an_instance_of(ZCRMSDK::Operations::ZCRMUser) 596 | expect(owner.id).to eql(current_user_id) 597 | expect(owner.name).to eql(current_user_name) 598 | created_by = zcrmnote_ins.created_by 599 | expect(created_by).to be_an_instance_of(ZCRMSDK::Operations::ZCRMUser) 600 | expect(created_by.id).to eql(current_user_id) 601 | expect(created_by.name).to eql(current_user_name) 602 | modified_by = zcrmnote_ins.modified_by 603 | expect(modified_by).to be_an_instance_of(ZCRMSDK::Operations::ZCRMUser) 604 | expect(modified_by.id).to eql(current_user_id) 605 | expect(modified_by.name).to eql(current_user_name) 606 | expect(zcrmnote_ins.created_time).to be_a_kind_of(String) 607 | expect(zcrmnote_ins.is_voice_note).to be(false) 608 | if creatable_module_api_name == 'Accounts' 609 | expect(zcrmnote_ins.parent_module).to eql(creatable_module_api_name).or eql('Calls').or eql('Events').or eql('Tasks').or eql('Deals').or eql('Contacts') 610 | end 611 | if creatable_module_api_name == 'Contacts' 612 | expect(zcrmnote_ins.parent_module).to eql(creatable_module_api_name).or eql('Calls').or eql('Events').or eql('Tasks').or eql('Deals') 613 | end 614 | if creatable_module_api_name == 'Tasks' || creatable_module_api_name == 'Calls' || creatable_module_api_name == 'Events' 615 | expect(zcrmnote_ins.parent_module).to eql(creatable_module_api_name).or eql('Contacts') 616 | end 617 | expect(zcrmnote_ins.parent_id).to be_a_kind_of(String) 618 | expect(zcrmnote_ins.parent_name).to be_a_kind_of(String) 619 | expect(zcrmnote_ins.is_editable).to be(true) 620 | end 621 | end 622 | end 623 | it 'delete_note' do 624 | creatable_module_api_names.each do |creatable_module_api_name| 625 | expect(deleted_note[creatable_module_api_name].code).to eql('SUCCESS') 626 | expect(deleted_note[creatable_module_api_name].message).to eql('record deleted') 627 | expect(deleted_note[creatable_module_api_name].details['id']).to eql(note_ids[creatable_module_api_name]) 628 | expect(deleted_note[creatable_module_api_name].status).to eql('success') 629 | end 630 | end 631 | it 'upload_photo' do 632 | creatable_module_api_names.each do |creatable_module_api_name| 633 | next unless %w[Leads Vendors Products Accounts Contacts].include?(creatable_module_api_name) 634 | 635 | expect(upload_photo_response[creatable_module_api_name].code).to eql('SUCCESS') 636 | expect(upload_photo_response[creatable_module_api_name].message).to eql('photo uploaded successfully') 637 | expect(upload_photo_response[creatable_module_api_name].status).to eql('success') 638 | end 639 | end 640 | it 'download_photo' do 641 | creatable_module_api_names.each do |creatable_module_api_name| 642 | if %w[Leads Vendors Products Accounts Contacts].include?(creatable_module_api_name) 643 | expect(download_photo_response[creatable_module_api_name].status_code).to eql(200) 644 | end 645 | end 646 | end 647 | it 'delete_photo' do 648 | creatable_module_api_names.each do |creatable_module_api_name| 649 | next unless %w[Leads Vendors Products Accounts Contacts].include?(creatable_module_api_name) 650 | 651 | expect(delete_photo_response[creatable_module_api_name].code).to eql('SUCCESS') 652 | expect(delete_photo_response[creatable_module_api_name].message).to eql('Photo deleted') 653 | expect(delete_photo_response[creatable_module_api_name].status).to eql('success') 654 | end 655 | end 656 | it 'add_tags_record' do 657 | creatable_module_api_names.each do |creatable_module_api_name| 658 | expect(add_tags_record[creatable_module_api_name].status).to eql('success') 659 | expect(add_tags_record[creatable_module_api_name].message).to eql('tags updated successfully') 660 | add_tags_record[creatable_module_api_name].details['tags'].each do |tag_name| 661 | expect(tag_name).to eql('ruby_automation_tag_1').or eql('ruby_automation_tag_2') 662 | end 663 | end 664 | end 665 | it 'remove_tags_record' do 666 | creatable_module_api_names.each do |creatable_module_api_name| 667 | expect(remove_tags_record[creatable_module_api_name].status).to eql('success') 668 | expect(add_tags_record[creatable_module_api_name].message).to eql('tags updated successfully') 669 | end 670 | end 671 | it 'converted_lead' do 672 | expect(convert_lead_response['Accounts']).to eql(created_record['Accounts'][0].entity_id) 673 | expect(convert_lead_response['Contacts']).to eql(created_record['Contacts'][0].entity_id) 674 | expect(convert_lead_response['Deals']).to be_a_kind_of(String) 675 | end 676 | it 'add_relation' do 677 | creatable_module_api_names.each do |creatable_module_api_name| 678 | next unless %w[Leads Accounts Contacts Deals Price_Books].include?(creatable_module_api_name) 679 | 680 | add_relation_response[creatable_module_api_name].each do |res| 681 | expect(res.code).to eql('SUCCESS') 682 | expect(res.status).to eql('success') 683 | expect(res.message).to eql('relation added') 684 | end 685 | end 686 | end 687 | it 'get_related_records' do 688 | creatable_module_api_names.each do |creatable_module_api_name| 689 | next unless %w[Leads Accounts Contacts Deals Price_Books].include?(creatable_module_api_name) 690 | 691 | get_relatedrecords[creatable_module_api_name].each do |records| 692 | records.each do |record| 693 | expect(record.module_api_name).to be_a_kind_of(String) 694 | expect(record.entity_id).to eql(created_record[record.module_api_name][0].entity_id) 695 | end 696 | end 697 | end 698 | end 699 | it 'remove_relation' do 700 | creatable_module_api_names.each do |creatable_module_api_name| 701 | next unless %w[Leads Accounts Contacts Deals Price_Books].include?(creatable_module_api_name) 702 | 703 | remove_relation_response[creatable_module_api_name].each do |res| 704 | expect(res.code).to eql('SUCCESS') 705 | expect(res.status).to eql('success') 706 | expect(res.message).to eql('relation removed') 707 | end 708 | end 709 | end 710 | 711 | it 'tag_update' do 712 | expect(tag_update_response.status).to eql('success') 713 | expect(tag_update_response.code).to eql('SUCCESS') 714 | expect(tag_update_response.message).to eql('tags updated successfully') 715 | end 716 | it 'tag_merge' do 717 | expect(tag_merge_response.status).to eql('success') 718 | expect(tag_merge_response.code).to eql('SUCCESS') 719 | expect(tag_merge_response.message).to eql('tags merged successfully') 720 | end 721 | it 'tag_delete' do 722 | expect(tag_delete_response.status).to eql('success') 723 | expect(tag_delete_response.code).to eql('SUCCESS') 724 | expect(tag_delete_response.message).to eql('tags deleted successfully') 725 | end 726 | end 727 | -------------------------------------------------------------------------------- /lib/ZCRMSDK/operations.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'utility' 4 | require_relative 'handler' 5 | module ZCRMSDK 6 | module Operations 7 | # THIS CLASS IS USED TO STORE AND EXECTUTE MODULE RELATED FUNCTIONS 8 | class ZCRMModule 9 | attr_accessor :is_inventory_template_supported, :layouts, :visibility, :is_feeds_required, :is_quick_create, :is_email_template_support, :is_webform_supported, :is_filter_supported, :is_kanban_view_supported, :generated_type, :arguments, :parent_module, :is_filter_status, :is_kanban_view, :is_presence_sub_menu, :api_name, :is_convertable, :is_creatable, :is_editable, :is_deletable, :web_link, :singular_label, :plural_label, :modified_by, :modified_time, :is_viewable, :is_api_supported, :is_custom_module, :is_scoring_supported, :id, :module_name, :business_card_field_limit, :business_card_fields, :profiles, :display_field_name, :display_field_id, :related_lists, :fields, :related_list_properties, :properties, :per_page, :search_layout_fields, :default_territory_name, :default_territory_id, :default_custom_view_id, :default_custom_view, :is_global_search_supported, :sequence_number 10 | def initialize(module_apiname) 11 | @api_name = module_apiname 12 | @visibility = nil 13 | @fields = nil 14 | @layouts = nil 15 | @is_convertable = nil 16 | @is_feeds_required = nil 17 | @is_creatable = nil 18 | @is_editable = nil 19 | @is_deletable = nil 20 | @web_link = nil 21 | @singular_label = nil 22 | @plural_label = nil 23 | @modified_by = nil 24 | @modified_time = nil 25 | @is_viewable = nil 26 | @is_api_supported = nil 27 | @is_custom_module = nil 28 | @is_scoring_supported = nil 29 | @is_webform_supported = nil 30 | @is_email_template_support = nil 31 | @is_inventory_template_supported = nil 32 | @id = nil 33 | @module_name = nil 34 | @business_card_field_limit = nil 35 | @business_card_fields = [] 36 | @profiles = [] 37 | @display_field_name = nil 38 | @related_lists = nil 39 | @related_list_properties = nil 40 | @properties = nil 41 | @per_page = nil 42 | @search_layout_fields = nil 43 | @default_territory_name = nil 44 | @default_territory_id = nil 45 | @default_custom_view_id = nil 46 | @default_custom_view = nil 47 | @is_global_search_supported = nil 48 | @sequence_number = nil 49 | @is_kanban_view = nil 50 | @is_filter_status = nil 51 | @parent_module = nil 52 | @is_presence_sub_menu = nil 53 | @arguments = [] 54 | @generated_type = nil 55 | @is_quick_create = nil 56 | @is_kanban_view_supported = nil 57 | @is_filter_supported = nil 58 | end 59 | 60 | def self.get_instance(module_apiname) 61 | ZCRMModule.new(module_apiname) 62 | end 63 | 64 | def get_record(entity_id) 65 | record = ZCRMRecord.get_instance(@api_name, entity_id) 66 | Handler::EntityAPIHandler.get_instance(record).get_record 67 | end 68 | 69 | def get_records(cvid = nil, sort_by = nil, sort_order = nil, page = 1, per_page = 200, headers = nil) 70 | Handler::MassEntityAPIHandler.get_instance(self).get_records(cvid, sort_by, sort_order, page, per_page, headers) 71 | end 72 | 73 | def get_all_deleted_records(page = 1, per_page = 200) 74 | Handler::MassEntityAPIHandler.get_instance(self).get_deleted_records('all', page, per_page) 75 | end 76 | 77 | def get_recyclebin_records(page = 1, per_page = 200) 78 | Handler::MassEntityAPIHandler.get_instance(self).get_deleted_records('recycle', page, per_page) 79 | end 80 | 81 | def get_permanently_deleted_records(page = 1, per_page = 200) 82 | Handler::MassEntityAPIHandler.get_instance(self).get_deleted_records('permanent', page, per_page) 83 | end 84 | 85 | def get_all_fields 86 | Handler::ModuleAPIHandler.get_instance(self).get_all_fields 87 | end 88 | 89 | def get_field(field_id) 90 | Handler::ModuleAPIHandler.get_instance(self).get_field(field_id) 91 | end 92 | 93 | def get_all_layouts 94 | Handler::ModuleAPIHandler.get_instance(self).get_all_layouts 95 | end 96 | 97 | def get_layout(layout_id) 98 | Handler::ModuleAPIHandler.get_instance(self).get_layout(layout_id) 99 | end 100 | 101 | def get_all_customviews 102 | Handler::ModuleAPIHandler.get_instance(self).get_all_customviews 103 | end 104 | 105 | def get_customview(customview_id) 106 | Handler::ModuleAPIHandler.get_instance(self).get_customview(customview_id) 107 | end 108 | 109 | def get_all_relatedlists 110 | Handler::ModuleAPIHandler.get_instance(self).get_all_relatedlists 111 | end 112 | 113 | def get_relatedlist(relatedlist_id) 114 | Handler::ModuleAPIHandler.get_instance(self).get_relatedlist(relatedlist_id) 115 | end 116 | 117 | def create_records(record_ins_list, lar_id = nil) 118 | Handler::MassEntityAPIHandler.get_instance(self).create_records(record_ins_list, lar_id) 119 | end 120 | 121 | def upsert_records(record_ins_list, duplicate_check_fields = nil, lar_id = nil) 122 | Handler::MassEntityAPIHandler.get_instance(self).upsert_records(record_ins_list, duplicate_check_fields, lar_id) 123 | end 124 | 125 | def update_records(record_ins_list) 126 | Handler::MassEntityAPIHandler.get_instance(self).update_records(record_ins_list) 127 | end 128 | 129 | def update_customview(customview_instance) 130 | Handler::ModuleAPIHandler.get_instance(self).update_customview(customview_instance) 131 | end 132 | 133 | def mass_update_records(entityid_list, field_api_name, value) 134 | Handler::MassEntityAPIHandler.get_instance(self).mass_update_records(entityid_list, field_api_name, value) 135 | end 136 | 137 | def delete_records(entityid_list) 138 | Handler::MassEntityAPIHandler.get_instance(self).delete_records(entityid_list) 139 | end 140 | 141 | def search_records(search_word, page = 1, per_page = 200) 142 | Handler::MassEntityAPIHandler.get_instance(self).search_records(search_word, page, per_page, 'word') 143 | end 144 | 145 | def search_records_by_phone(phone, page = 1, per_page = 200) 146 | Handler::MassEntityAPIHandler.get_instance(self).search_records(phone, page, per_page, 'phone') 147 | end 148 | 149 | def search_records_by_email(email, page = 1, per_page = 200) 150 | Handler::MassEntityAPIHandler.get_instance(self).search_records(email, page, per_page, 'email') 151 | end 152 | 153 | def search_records_by_criteria(criteria, page = 1, per_page = 200) 154 | Handler::MassEntityAPIHandler.get_instance(self).search_records(criteria, page, per_page, 'criteria') 155 | end 156 | 157 | def get_tags 158 | Handler::TagAPIHandler.get_instance(self).get_tags 159 | end 160 | 161 | def get_tag_count(tag_id) 162 | Handler::TagAPIHandler.get_instance(self).get_tag_count(tag_id) 163 | end 164 | 165 | def create_tags(tags_list) 166 | Handler::TagAPIHandler.get_instance(self).create_tags(tags_list) 167 | end 168 | 169 | def update_tags(tags_list) 170 | Handler::TagAPIHandler.get_instance(self).update_tags(tags_list) 171 | end 172 | 173 | def add_tags_to_multiple_records(tags_list, record_list) 174 | Handler::TagAPIHandler.get_instance(self).add_tags_to_multiple_records(tags_list, record_list) 175 | end 176 | 177 | def remove_tags_from_multiple_records(tags_list, record_list) 178 | Handler::TagAPIHandler.get_instance(self).remove_tags_from_multiple_records(tags_list, record_list) 179 | end 180 | end 181 | # THIS CLASS IS USED TO STORE SUBFORM RELATED DATA 182 | class ZCRMSubForm 183 | attr_accessor :id, :name, :owner, :created_time, :modified_time, :layout, :field_data, :properties 184 | def initialize(id = nil) 185 | @id = id 186 | @name = nil 187 | @owner = nil 188 | @created_time = nil 189 | @modified_time = nil 190 | @layout = nil 191 | @field_data = {} 192 | @properties = {} 193 | end 194 | 195 | def self.get_instance(id = nil) 196 | ZCRMSubForm.new(id) 197 | end 198 | end 199 | # THIS CLASS IS USED TO STORE AND EXECTUTE TAG RELATED FUNCTIONS 200 | class ZCRMTag 201 | attr_accessor :id, :module_apiname, :name, :created_by, :modified_by, :created_time, :modified_time, :count 202 | def initialize(id = nil, name = nil) 203 | @id = id 204 | @module_apiname = nil 205 | @name = name 206 | @created_by = nil 207 | @modified_by = nil 208 | @created_time = nil 209 | @modified_time = nil 210 | @count = nil 211 | end 212 | 213 | def self.get_instance(id = nil, name = nil) 214 | ZCRMTag.new(id, name) 215 | end 216 | 217 | def delete 218 | Handler::TagAPIHandler.get_instance.delete(@id) 219 | end 220 | 221 | def merge(merge_tag) 222 | Handler::TagAPIHandler.get_instance.merge(@id, merge_tag.id) 223 | end 224 | 225 | def update 226 | Handler::TagAPIHandler.get_instance.update(self) 227 | end 228 | end 229 | # THIS CLASS IS USED TO STORE AND EXECTUTE RECORD RELATED FUNCTIONS 230 | class ZCRMRecord 231 | attr_accessor :tag_list, :name, :module_api_name, :entity_id, :line_items, :lookup_label, :owner, :created_by, :modified_by, :created_time, :modified_time, :field_data, :properties, :participants, :price_details, :layout, :tax_list, :last_activity_time 232 | def initialize(module_apiname, entity_id = nil) 233 | @module_api_name = module_apiname 234 | @entity_id = entity_id 235 | @line_items = [] 236 | @lookup_label = nil 237 | @name = nil 238 | @owner = nil 239 | @created_by = nil 240 | @modified_by = nil 241 | @created_time = nil 242 | @modified_time = nil 243 | @field_data = {} 244 | @properties = {} 245 | @participants = [] 246 | @price_details = [] 247 | @layout = nil 248 | @tax_list = [] 249 | @tag_list = [] 250 | end 251 | 252 | def self.get_instance(module_api_name, entity_id = nil) 253 | ZCRMRecord.new(module_api_name, entity_id) 254 | end 255 | 256 | def get 257 | Handler::EntityAPIHandler.get_instance(self).get_record 258 | end 259 | 260 | def create 261 | Handler::EntityAPIHandler.get_instance(self).create_record 262 | end 263 | 264 | def update 265 | Handler::EntityAPIHandler.get_instance(self).update_record 266 | end 267 | 268 | def delete 269 | Handler::EntityAPIHandler.get_instance(self).delete_record 270 | end 271 | 272 | def convert(potential_record = nil, details = nil) 273 | Handler::EntityAPIHandler.get_instance(self).convert_record(potential_record, details) 274 | end 275 | 276 | def upload_attachment(file_path) 277 | ZCRMModuleRelation.get_instance(self, 'Attachments').upload_attachment(file_path) 278 | end 279 | 280 | def upload_link_as_attachment(link_url) 281 | ZCRMModuleRelation.get_instance(self, 'Attachments').upload_link_as_attachment(link_url) 282 | end 283 | 284 | def download_attachment(attachment_id) 285 | ZCRMModuleRelation.get_instance(self, 'Attachments').download_attachment(attachment_id) 286 | end 287 | 288 | def delete_attachment(attachment_id) 289 | ZCRMModuleRelation.get_instance(self, 'Attachments').delete_attachment(attachment_id) 290 | end 291 | 292 | def upload_photo(file_path) 293 | Handler::EntityAPIHandler.get_instance(self).upload_photo(file_path) 294 | end 295 | 296 | def download_photo 297 | Handler::EntityAPIHandler.get_instance(self).download_photo 298 | end 299 | 300 | def delete_photo 301 | Handler::EntityAPIHandler.get_instance(self).delete_photo 302 | end 303 | 304 | def add_relation(junction_record) 305 | ZCRMModuleRelation.get_instance(self, junction_record).add_relation 306 | end 307 | 308 | def remove_relation(junction_record) 309 | ZCRMModuleRelation.get_instance(self, junction_record).remove_relation 310 | end 311 | 312 | def add_notes(note_instances) 313 | ZCRMModuleRelation.get_instance(self, 'Notes').add_notes(note_instances) 314 | end 315 | 316 | def update_note(note_ins) 317 | ZCRMModuleRelation.get_instance(self, 'Notes').update_note(note_ins) 318 | end 319 | 320 | def delete_note(note_ins) 321 | ZCRMModuleRelation.get_instance(self, 'Notes').delete_note(note_ins) 322 | end 323 | 324 | def get_notes(sort_by = nil, sort_order = nil, page = 1, per_page = 20) 325 | ZCRMModuleRelation.get_instance(self, 'Notes').get_notes(sort_by, sort_order, page, per_page) 326 | end 327 | 328 | def get_attachments(page = 1, per_page = 20) 329 | ZCRMModuleRelation.get_instance(self, 'Attachments').get_attachments(page, per_page) 330 | end 331 | 332 | def get_relatedlist_records(relatedlist_api_name, sort_by = nil, sort_order = nil, page = 1, per_page = 20) 333 | ZCRMModuleRelation.get_instance(self, relatedlist_api_name).get_records(sort_by, sort_order, page, per_page) 334 | end 335 | 336 | def add_tags(tagnames) 337 | Handler::TagAPIHandler.get_instance.add_tags(self, tagnames) 338 | end 339 | 340 | def remove_tags(tagnames) 341 | Handler::TagAPIHandler.get_instance.remove_tags(self, tagnames) 342 | end 343 | end 344 | # THIS CLASS IS USED TO STORE LINE ITEM RELATED DATA 345 | class ZCRMInventoryLineItem 346 | attr_accessor :product, :id, :discount_percentage, :list_price, :quantity, :description, :total, :discount, :total_after_discount, :tax_amount, :net_total, :delete_flag, :line_tax 347 | def initialize(param = nil) 348 | if param.is_a?(Operations::ZCRMRecord) 349 | @product = param 350 | @id = nil 351 | else 352 | @id = param 353 | @product = nil 354 | @list_price = nil 355 | @quantity = nil 356 | @description = nil 357 | @total = nil 358 | @discount = nil 359 | @discount_percentage = nil 360 | @total_after_discount = nil 361 | @tax_amount = nil 362 | @net_total = nil 363 | @delete_flag = false 364 | @line_tax = [] 365 | end 366 | end 367 | 368 | def self.get_instance(param = nil) 369 | ZCRMInventoryLineItem.new(param) 370 | end 371 | end 372 | # THIS CLASS IS USED TO STORE TAX RELATED DATA 373 | class ZCRMTax 374 | attr_accessor :name, :percentage, :value 375 | def initialize(name) 376 | @name = name 377 | @percentage = nil 378 | @value = nil 379 | end 380 | 381 | def self.get_instance(name) 382 | ZCRMTax.new(name) 383 | end 384 | end 385 | # THIS CLASS IS USED TO STORE ORG TAX RELATED DATA 386 | class ZCRMOrgTax 387 | attr_accessor :id, :name, :display_label, :value, :sequence_number 388 | def initialize(id = nil, name = nil) 389 | @id = id 390 | @name = name 391 | @display_label = nil 392 | @value = nil 393 | @sequence_number = nil 394 | end 395 | 396 | def self.get_instance(id = nil, name = nil) 397 | ZCRMOrgTax.new(id, name) 398 | end 399 | end 400 | # THIS CLASS IS USED TO STORE EVENT PARTICIPANT RELATED DATA 401 | class ZCRMEventParticipant 402 | attr_accessor :id, :type, :email, :name, :is_invited, :status 403 | def initialize(participant_type, participant_id) 404 | @id = participant_id 405 | @type = participant_type 406 | @email = nil 407 | @name = nil 408 | @is_invited = nil 409 | @status = nil 410 | end 411 | 412 | def self.get_instance(participant_type, participant_id) 413 | ZCRMEventParticipant.new(participant_type, participant_id) 414 | end 415 | end 416 | # THIS CLASS IS USED TO STORE PRICING BOOK RELATED DATA 417 | class ZCRMPriceBookPricing 418 | attr_accessor :id, :to_range, :from_range, :discount 419 | def initialize(price_book_id = nil) 420 | @id = price_book_id 421 | @to_range = nil 422 | @from_range = nil 423 | @discount = nil 424 | end 425 | 426 | def self.get_instance(price_book_id = nil) 427 | ZCRMPriceBookPricing.new(price_book_id) 428 | end 429 | end 430 | # THIS CLASS IS USED TO STORE USER RELATED DATA 431 | class ZCRMUser 432 | attr_accessor :id, :is_microsoft, :offset, :name, :field_apiname_vs_value, :signature, :country, :role, :customize_info, :city, :name_format, :language, :locale, :is_personal_account, :default_tab_group, :street, :alias_aka, :theme, :state, :country_locale, :fax, :first_name, :email, :zip, :decimal_separator, :website, :time_format, :profile, :mobile, :last_name, :time_zone, :zuid, :is_confirm, :full_name, :phone, :dob, :date_format, :status, :created_by, :modified_by, :territories, :reporting_to, :is_online, :currency, :created_time, :modified_time 433 | def initialize(user_id = nil, name = nil) 434 | @id = user_id 435 | @name = name 436 | @offset = nil 437 | @is_microsoft = nil 438 | @signature = nil 439 | @country = nil 440 | @role = nil 441 | @customize_info = nil 442 | @city = nil 443 | @name_format = nil 444 | @language = nil 445 | @locale = nil 446 | @is_personal_account = nil 447 | @default_tab_group = nil 448 | @street = nil 449 | @alias_aka = nil 450 | @theme = nil 451 | @state = nil 452 | @country_locale = nil 453 | @fax = nil 454 | @first_name = nil 455 | @email = nil 456 | @zip = nil 457 | @decimal_separator = nil 458 | @website = nil 459 | @time_format = nil 460 | @profile = nil 461 | @mobile = nil 462 | @last_name = nil 463 | @time_zone = nil 464 | @zuid = nil 465 | @is_confirm = nil 466 | @full_name = nil 467 | @phone = nil 468 | @dob = nil 469 | @date_format = nil 470 | @status = nil 471 | @created_by = nil 472 | @modified_by = nil 473 | @territories = nil 474 | @reporting_to = nil 475 | @is_online = nil 476 | @currency = nil 477 | @created_time = nil 478 | @modified_time = nil 479 | @field_apiname_vs_value = nil 480 | end 481 | 482 | def self.get_instance(user_id = nil, name = nil) 483 | ZCRMUser.new(user_id, name) 484 | end 485 | end 486 | # THIS CLASS IS USED TO STORE USER CUSTOM INFO RELATED DATA 487 | class ZCRMUserCustomizeInfo 488 | attr_accessor :notes_desc, :is_to_show_right_panel, :is_bc_view, :is_to_show_home, :is_to_show_detail_view, :unpin_recent_item 489 | def initialize 490 | @notes_desc = nil 491 | @is_to_show_right_panel = nil 492 | @is_bc_view = nil 493 | @is_to_show_home = nil 494 | @is_to_show_detail_view = nil 495 | @unpin_recent_item = nil 496 | end 497 | 498 | def self.get_instance 499 | ZCRMUserCustomizeInfo.new 500 | end 501 | end 502 | # THIS CLASS IS USED TO STORE USER THEME RELATED DATA 503 | class ZCRMUserTheme 504 | attr_accessor :normal_tab_font_color, :normal_tab_background, :selected_tab_font_color, :selected_tab_background, :new_background, :background, :screen, :type 505 | def initialize 506 | @normal_tab_font_color = nil 507 | @normal_tab_background = nil 508 | @selected_tab_font_color = nil 509 | @selected_tab_background = nil 510 | @new_background = nil 511 | @background = nil 512 | @screen = nil 513 | @type = nil 514 | end 515 | 516 | def self.get_instance 517 | ZCRMUserTheme.new 518 | end 519 | end 520 | # THIS CLASS IS USED TO STORE ROLE RELATED DATA 521 | class ZCRMRole 522 | attr_accessor :name, :id, :reporting_to, :display_label, :is_admin, :forecast_manager, :is_share_with_peers, :description 523 | def initialize(role_id, role_name = nil) 524 | @name = role_name 525 | @id = role_id 526 | @reporting_to = nil 527 | @display_label = nil 528 | @is_admin = nil 529 | @forecast_manager = nil 530 | @is_share_with_peers = nil 531 | @description = nil 532 | end 533 | 534 | def self.get_instance(role_id, role_name = nil) 535 | ZCRMRole.new(role_id, role_name) 536 | end 537 | end 538 | # THIS CLASS IS USED TO STORE LAYOUT RELATED DATA 539 | class ZCRMLayout 540 | attr_accessor :created_for, :id, :name, :created_time, :modified_time, :is_visible, :modified_by, :accessible_profiles, :created_by, :sections, :status, :convert_mapping 541 | def initialize(layout_id) 542 | @id = layout_id 543 | @name = nil 544 | @created_time = nil 545 | @modified_time = nil 546 | @is_visible = nil 547 | @modified_by = nil 548 | @accessible_profiles = nil 549 | @created_by = nil 550 | @sections = nil 551 | @status = nil 552 | @convert_mapping = {} 553 | @created_for = nil 554 | end 555 | 556 | def self.get_instance(layout_id) 557 | ZCRMLayout.new(layout_id) 558 | end 559 | end 560 | # THIS CLASS IS USED TO STORE ATTACHMENT RELATED DATA 561 | class ZCRMAttachment 562 | attr_accessor :is_editable, :link_url, :file_id, :id, :parent_record, :file_name, :type, :size, :owner, :created_by, :created_time, :modified_by, :modified_time, :parent_module, :attachment_type, :parent_name, :parent_id 563 | def initialize(parent_record, attachment_id = nil) 564 | @id = attachment_id 565 | @parent_record = parent_record 566 | @file_name = nil 567 | @type = nil 568 | @size = nil 569 | @owner = nil 570 | @created_by = nil 571 | @created_time = nil 572 | @modified_by = nil 573 | @modified_time = nil 574 | @parent_module = nil 575 | @attachment_type = nil 576 | @parent_name = nil 577 | @parent_id = nil 578 | @file_id = nil 579 | @link_url = nil 580 | @is_editable = nil 581 | end 582 | 583 | def self.get_instance(parent_record, attachment_id = nil) 584 | ZCRMAttachment.new(parent_record, attachment_id) 585 | end 586 | end 587 | # THIS CLASS IS USED TO STORE CUSTOM VIEW RELATED DATA 588 | class ZCRMCustomView 589 | attr_accessor :is_system_defined, :shared_details, :criteria_pattern, :criteria_condition, :id, :module_api_name, :display_value, :is_default, :name, :system_name, :sort_by, :category, :fields, :favorite, :sort_order, :criteria, :categories, :is_off_line 590 | def initialize(custom_view_id, module_api_name = nil) 591 | @id = custom_view_id 592 | @module_api_name = module_api_name 593 | @display_value = nil 594 | @is_default = nil 595 | @name = nil 596 | @system_name = nil 597 | @sort_by = nil 598 | @category = nil 599 | @fields = [] 600 | @favorite = nil 601 | @sort_order = nil 602 | @criteria = nil 603 | @criteria_pattern = nil 604 | @criteria_condition = nil 605 | @categories = [] 606 | @is_off_line = nil 607 | @shared_details = nil 608 | @is_system_defined = nil 609 | end 610 | 611 | def self.get_instance(custom_view_id, module_api_name = nil) 612 | ZCRMCustomView.new(custom_view_id, module_api_name) 613 | end 614 | 615 | def get_records(sort_by = nil, sort_order = nil, page = 1, per_page = 200, headers = nil) 616 | Operations::ZCRMModule.get_instance(module_api_name).get_records(id, sort_by, sort_order, page, per_page, headers) 617 | end 618 | end 619 | # THIS CLASS IS USED TO STORE CUSTOMVIEW CATEGORY RELATED DATA 620 | class ZCRMCustomViewCategory 621 | attr_accessor :display_value, :actual_value 622 | def initialize 623 | @display_value = nil 624 | @actual_value = nil 625 | end 626 | 627 | def self.get_instance 628 | ZCRMCustomViewCategory.new 629 | end 630 | end 631 | # THIS CLASS IS USED TO STORE CUSTOMVIEW CATEGORY CRITERIA RELATED DATA 632 | class ZCRMCustomViewCriteria 633 | attr_accessor :comparator, :field, :value, :group, :group_operator, :pattern, :index, :criteria 634 | def initialize 635 | @comparator = nil 636 | @field = nil 637 | @value = nil 638 | @group = nil 639 | @group_operator = nil 640 | @pattern = nil 641 | @index = nil 642 | @criteria = nil 643 | end 644 | 645 | def self.get_instance 646 | ZCRMCustomViewCriteria.new 647 | end 648 | end 649 | # THIS CLASS IS USED TO STORE FIELD RELATED DATA 650 | class ZCRMField 651 | attr_accessor :is_webhook, :crypt, :tooltip, :is_field_read_only, :association_details, :subform, :is_mass_update, :multiselectlookup, :api_name, :is_custom_field, :lookup_field, :convert_mapping, :is_visible, :field_label, :length, :created_source, :default_value, :is_mandatory, :sequence_number, :is_read_only, :is_unique_field, :is_case_sensitive, :data_type, :is_formula_field, :is_currency_field, :id, :picklist_values, :is_auto_number, :is_business_card_supported, :field_layout_permissions, :decimal_place, :precision, :rounding_option, :formula_return_type, :formula_expression, :prefix, :suffix, :start_number, :json_type 652 | def initialize(api_name, id = nil) 653 | @api_name = api_name 654 | @is_webhook = nil 655 | @crypt = nil 656 | @tooltip = nil 657 | @is_field_read_only = nil 658 | @association_details = nil 659 | @subform = nil 660 | @is_mass_update = nil 661 | @multiselectlookup = {} 662 | @is_custom_field = nil 663 | @lookup_field = {} 664 | @convert_mapping = nil 665 | @is_visible = nil 666 | @field_label = nil 667 | @length = nil 668 | @created_source = nil 669 | @default_value = nil 670 | @is_mandatory = nil 671 | @sequence_number = nil 672 | @is_read_only = nil 673 | @is_unique_field = nil 674 | @is_case_sensitive = nil 675 | @data_type = nil 676 | @is_formula_field = nil 677 | @is_currency_field = nil 678 | @id = id 679 | @picklist_values = [] 680 | @is_auto_number = nil 681 | @is_business_card_supported = nil 682 | @field_layout_permissions = nil 683 | @decimal_place = nil 684 | @precision = nil 685 | @rounding_option = nil 686 | @formula_return_type = nil 687 | @formula_expression = nil 688 | @prefix = nil 689 | @suffix = nil 690 | @start_number = nil 691 | @json_type = nil 692 | end 693 | 694 | def self.get_instance(api_name, id = nil) 695 | ZCRMField.new(api_name, id) 696 | end 697 | end 698 | # THIS CLASS IS USED TO STORE JUNCTION RECORD RELATED DATA 699 | class ZCRMJunctionRecord 700 | attr_accessor :id, :api_name, :related_data 701 | def initialize(api_name, record_id) 702 | @id = record_id 703 | @api_name = api_name 704 | @related_data = {} 705 | end 706 | 707 | def self.get_instance(api_name, record_id) 708 | ZCRMJunctionRecord.new(api_name, record_id) 709 | end 710 | end 711 | # THIS CLASS IS USED TO STORE LEAD CONVERT MAPPING RELATED DATA 712 | class ZCRMLeadConvertMapping 713 | attr_accessor :id, :name, :fields 714 | def initialize(name, converted_id) 715 | @id = converted_id 716 | @name = name 717 | @fields = [] 718 | end 719 | 720 | def self.get_instance(name, converted_id) 721 | ZCRMLeadConvertMapping.new(name, converted_id) 722 | end 723 | end 724 | # THIS CLASS IS USED TO STORE LEAD CONVERT MAPPING FIELD RELATED DATA 725 | class ZCRMLeadConvertMappingField 726 | attr_accessor :id, :api_name, :field_label, :is_required 727 | def initialize(api_name, field_id) 728 | @id = field_id 729 | @api_name = api_name 730 | @field_label = nil 731 | @is_required = nil 732 | end 733 | 734 | def self.get_instance(api_name, field_id) 735 | ZCRMLeadConvertMappingField.new(api_name, field_id) 736 | end 737 | end 738 | # THIS CLASS IS USED TO STORE LOOKUP FIELD RELATED DATA 739 | class ZCRMLookupField 740 | attr_accessor :api_name, :display_label, :module_apiname, :id 741 | def initialize(api_name) 742 | @api_name = api_name 743 | @display_label = nil 744 | @module_apiname = nil 745 | @id = nil 746 | end 747 | 748 | def self.get_instance(api_name) 749 | ZCRMLookupField.new(api_name) 750 | end 751 | end 752 | # THIS CLASS IS USED TO STORE MODULE RELATED LIST RELATED DATA 753 | class ZCRMModuleRelatedList 754 | attr_accessor :api_name, :module_apiname, :display_label, :is_visible, :name, :id, :href, :type, :action, :sequence_number 755 | def initialize(api_name) 756 | @api_name = api_name 757 | @module_apiname = nil 758 | @display_label = nil 759 | @is_visible = nil 760 | @name = nil 761 | @id = nil 762 | @href = nil 763 | @type = nil 764 | @action = nil 765 | @sequence_number = nil 766 | end 767 | 768 | def self.get_instance(api_name) 769 | ZCRMModuleRelatedList.new(api_name) 770 | end 771 | end 772 | # THIS CLASS IS USED TO STORE MODULE RELATION RELATED DATA 773 | class ZCRMModuleRelation 774 | attr_accessor :parent_record, :parent_module_api_name, :junction_record, :api_name, :label, :id, :is_visible 775 | def initialize(parentmodule_apiname_or_parentrecord, related_list_apiname_or_junction_record = nil) 776 | if parentmodule_apiname_or_parentrecord.is_a?(Operations::ZCRMRecord) 777 | @parent_record = parentmodule_apiname_or_parentrecord 778 | @parent_module_api_name = nil 779 | else 780 | @parent_module_api_name = parentmodule_apiname_or_parentrecord 781 | @parent_record = nil 782 | end 783 | if related_list_apiname_or_junction_record.is_a?(Operations::ZCRMJunctionRecord) 784 | @junction_record = related_list_apiname_or_junction_record 785 | @api_name = nil 786 | else 787 | @api_name = related_list_apiname_or_junction_record 788 | @junction_record = nil 789 | end 790 | @label = nil 791 | @id = nil 792 | @is_visible = nil 793 | end 794 | 795 | def self.get_instance(parentmodule_apiname_or_parentrecord, related_list_apiname_or_junction_record) 796 | ZCRMModuleRelation.new(parentmodule_apiname_or_parentrecord, related_list_apiname_or_junction_record) 797 | end 798 | 799 | def get_records(sort_by_field = nil, sort_order = nil, page = 1, per_page = 20) 800 | Handler::RelatedListAPIHandler.get_instance(@parent_record, self).get_records(sort_by_field, sort_order, page, per_page) 801 | end 802 | 803 | def upload_attachment(file_path) 804 | Handler::RelatedListAPIHandler.get_instance(@parent_record, self).upload_attachment(file_path) 805 | end 806 | 807 | def upload_link_as_attachment(link_url) 808 | Handler::RelatedListAPIHandler.get_instance(@parent_record, self).upload_link_as_attachment(link_url) 809 | end 810 | 811 | def download_attachment(attachment_id) 812 | Handler::RelatedListAPIHandler.get_instance(@parent_record, self).download_attachment(attachment_id) 813 | end 814 | 815 | def delete_attachment(attachment_id) 816 | Handler::RelatedListAPIHandler.get_instance(@parent_record, self).delete_attachment(attachment_id) 817 | end 818 | 819 | def add_relation 820 | Handler::RelatedListAPIHandler.get_instance(@parent_record, @junction_record).add_relation 821 | end 822 | 823 | def remove_relation 824 | Handler::RelatedListAPIHandler.get_instance(@parent_record, @junction_record).remove_relation 825 | end 826 | 827 | def add_notes(zcrm_note_instances) 828 | Handler::RelatedListAPIHandler.get_instance(@parent_record, self).add_notes(zcrm_note_instances) 829 | end 830 | 831 | def update_note(zcrm_note_ins) 832 | Handler::RelatedListAPIHandler.get_instance(@parent_record, self).update_note(zcrm_note_ins) 833 | end 834 | 835 | def delete_note(zcrm_note_ins) 836 | Handler::RelatedListAPIHandler.get_instance(@parent_record, self).delete_note(zcrm_note_ins) 837 | end 838 | 839 | def get_notes(sort_by = nil, sort_order = nil, page = 1, per_page = 200) 840 | Handler::RelatedListAPIHandler.get_instance(@parent_record, self).get_notes(sort_by, sort_order, page, per_page) 841 | end 842 | 843 | def get_attachments(page = 1, per_page = 20) 844 | Handler::RelatedListAPIHandler.get_instance(@parent_record, self).get_attachments(page, per_page) 845 | end 846 | end 847 | # THIS CLASS IS USED TO STORE AND EXECUTE NOTES RELATED FUNCTIONALITY 848 | class ZCRMNote 849 | attr_accessor :is_editable, :id, :parent_record, :title, :content, :owner, :created_by, :created_time, :modified_by, :modified_time, :attachments, :size, :is_voice_note, :parent_module, :parent_name, :parent_id 850 | def initialize(parent_record = nil, note_id = nil) 851 | @id = note_id 852 | @parent_record = parent_record 853 | @title = nil 854 | @content = nil 855 | @owner = nil 856 | @created_by = nil 857 | @created_time = nil 858 | @modified_by = nil 859 | @modified_time = nil 860 | @attachments = nil 861 | @size = nil 862 | @is_voice_note = nil 863 | unless parent_record.nil? 864 | @parent_module = parent_record.module_api_name 865 | @parent_id = parent_record.entity_id 866 | end 867 | @parent_name = nil 868 | @is_editable = nil 869 | end 870 | 871 | def upload_attachment(file_path) 872 | ZCRMModuleRelation.get_instance(ZCRMRecord.get_instance('Notes', @id), 'Attachments').upload_attachment(file_path) 873 | end 874 | 875 | def download_attachment(attachment_id) 876 | ZCRMModuleRelation.get_instance(ZCRMRecord.get_instance('Notes', @id), 'Attachments').download_attachment(attachment_id) 877 | end 878 | 879 | def get_attachments(page = 1, per_page = 20) 880 | ZCRMModuleRelation.get_instance(ZCRMRecord.get_instance('Notes', @id), 'Attachments').get_attachments(page, per_page) 881 | end 882 | 883 | def delete_attachment(attachment_id) 884 | ZCRMModuleRelation.get_instance(ZCRMRecord.get_instance('Notes', @id), 'Attachments').delete_attachment(attachment_id) 885 | end 886 | 887 | def self.get_instance(parent_record = nil, note_id = nil) 888 | ZCRMNote.new(parent_record , note_id) 889 | end 890 | end 891 | # THIS CLASS IS USED TO STORE PROFILE PERMISSIONS RELATED DATA 892 | class ZCRMPermission 893 | attr_accessor :id, :name, :display_label, :module_api_name, :is_enabled 894 | def initialize(permission_name, permission_id) 895 | @id = permission_id 896 | @name = permission_name 897 | @display_label = nil 898 | @module_api_name = nil 899 | @is_enabled = nil 900 | end 901 | 902 | def self.get_instance(permission_name, permission_id) 903 | ZCRMPermission.new(permission_name, permission_id) 904 | end 905 | end 906 | # THIS CLASS IS USED TO STORE PICK LIST VALUE RELATED DATA 907 | class ZCRMPickListValue 908 | attr_accessor :display_value, :sequence_number, :actual_value, :maps 909 | def initialize 910 | @display_value = nil 911 | @sequence_number = nil 912 | @actual_value = nil 913 | @maps = nil 914 | end 915 | 916 | def self.get_instance 917 | ZCRMPickListValue.new 918 | end 919 | end 920 | # THIS CLASS IS USED TO STORE MULTI SELECT LOOKUP RELATED DATA 921 | class ZCRMMultiSelectLookupField 922 | attr_accessor :display_label, :linking_module, :connected_module, :api_name, :id 923 | def initialize(api_name) 924 | @display_label = nil 925 | @linking_module = nil 926 | @connected_module = nil 927 | @api_name = api_name 928 | @id = nil 929 | end 930 | 931 | def self.get_instance(api_name) 932 | ZCRMMultiSelectLookupField.new(api_name) 933 | end 934 | end 935 | # THIS CLASS IS USED TO STORE PROFILE RELATED DATA 936 | class ZCRMProfile 937 | attr_accessor :name, :id, :is_default, :created_time, :modified_time, :modified_by, :description, :created_by, :category, :permissions, :sections 938 | def initialize(profile_id, profile_name = nil) 939 | @name = profile_name 940 | @id = profile_id 941 | @is_default = nil 942 | @created_time = nil 943 | @modified_time = nil 944 | @modified_by = nil 945 | @description = nil 946 | @created_by = nil 947 | @category = nil 948 | @permissions = [] 949 | @sections = [] 950 | end 951 | 952 | def self.get_instance(profile_id, profile_name = nil) 953 | ZCRMProfile.new(profile_id, profile_name) 954 | end 955 | end 956 | # THIS CLASS IS USED TO STORE PROFILE CATEGORY DATA 957 | class ZCRMProfileCategory 958 | attr_accessor :name, :module_api_name, :display_label, :permission_ids 959 | def initialize(profile_category_name) 960 | @name = profile_category_name 961 | @module_api_name = nil 962 | @display_label = nil 963 | @permission_ids = [] 964 | end 965 | 966 | def self.get_instance(profile_category_name) 967 | ZCRMProfileCategory.new(profile_category_name) 968 | end 969 | end 970 | # THIS CLASS IS USED TO STORE PROFILE SECTION DATA 971 | class ZCRMProfileSection 972 | attr_accessor :name, :categories 973 | def initialize(section_name) 974 | @name = section_name 975 | @categories = [] 976 | end 977 | 978 | def self.get_instance(section_name) 979 | ZCRMProfileSection.new(section_name) 980 | end 981 | end 982 | # THIS CLASS IS USED TO STORE RELATED LIST PROPERTIES RELATED DATA 983 | class ZCRMRelatedListProperties 984 | attr_accessor :sort_by, :sort_order, :fields 985 | def initialize 986 | @sort_by = nil 987 | @sort_order = nil 988 | @fields = nil 989 | end 990 | 991 | def self.get_instance 992 | ZCRMRelatedListProperties.new 993 | end 994 | end 995 | # THIS CLASS IS USED TO STORE SECTIONS RELATED DATA 996 | class ZCRMSection 997 | attr_accessor :properties, :api_name, :name, :display_label, :column_count, :sequence_number, :fields, :is_subform_section, :tab_traversal 998 | def initialize(section_name) 999 | @name = section_name 1000 | @display_label = nil 1001 | @column_count = nil 1002 | @sequence_number = nil 1003 | @fields = nil 1004 | @is_subform_section = nil 1005 | @tab_traversal = nil 1006 | @api_name = nil 1007 | @properties = nil 1008 | end 1009 | 1010 | def self.get_instance(section_name) 1011 | ZCRMSection.new(section_name) 1012 | end 1013 | end 1014 | # THIS CLASS IS USED TO STORE SECTION PROPERTIES RELATED DATA 1015 | class ZCRMSectionProperties 1016 | attr_accessor :reorder_rows, :tooltip, :maximum_rows 1017 | def initialize 1018 | @reorder_rows = nil 1019 | @tooltip = nil 1020 | @maximum_rows = nil 1021 | end 1022 | 1023 | def self.get_instance 1024 | ZCRMSectionProperties.new 1025 | end 1026 | end 1027 | # THIS CLASS IS USED TO STORE TRASH RECORD RELATED DATA 1028 | class ZCRMTrashRecord 1029 | attr_accessor :id, :type, :display_name, :deleted_time, :created_by, :deleted_by, :module_api_name 1030 | def initialize(module_api_name, entity_type, entity_id = nil) 1031 | @id = entity_id 1032 | @module_api_name = module_api_name 1033 | @type = entity_type 1034 | @display_name = nil 1035 | @deleted_time = nil 1036 | @created_by = nil 1037 | @deleted_by = nil 1038 | end 1039 | 1040 | def self.get_instance(module_api_name, entity_type, entity_id = nil) 1041 | ZCRMTrashRecord.new(module_api_name, entity_type, entity_id) 1042 | end 1043 | end 1044 | class ZCRMVariable 1045 | attr_accessor :id, :name, :api_name, :type, :value, :variable_group, :description 1046 | def initialize(api_name =nil ,id = nil) 1047 | @id = id 1048 | @name = nil 1049 | @api_name = api_name 1050 | @type = nil 1051 | @value = nil 1052 | @variable_group = nil 1053 | @description = nil 1054 | end 1055 | 1056 | def self.get_instance(api_name=nil,id = nil) 1057 | ZCRMVariable.new(api_name,id) 1058 | end 1059 | 1060 | def get(group_id) 1061 | Handler::VariableAPIHandler.get_instance(self).get_variable(group_id) 1062 | end 1063 | 1064 | def update 1065 | Handler::VariableAPIHandler.get_instance(self).update_variable 1066 | end 1067 | 1068 | def delete 1069 | Handler::VariableAPIHandler.get_instance(self).delete_variable 1070 | end 1071 | end 1072 | class ZCRMVariableGroup 1073 | attr_accessor :id, :name, :api_name,:display_label, :description 1074 | def initialize(api_name=nil,id = nil) 1075 | @id = id 1076 | @name = nil 1077 | @api_name = api_name 1078 | @display_label = nil 1079 | @description = nil 1080 | end 1081 | 1082 | def self.get_instance(api_name=nil,id = nil) 1083 | ZCRMVariableGroup.new(api_name,id) 1084 | end 1085 | 1086 | def get 1087 | Handler::VariableGroupAPIHandler.get_instance(self).get_variable_group 1088 | end 1089 | end 1090 | end 1091 | end 1092 | --------------------------------------------------------------------------------