bullhorn-rails 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/bullhorn-rails-0.1.0.gem +0 -0
- data/bullhorn-rails.gemspec +10 -1
- data/lib/.DS_Store +0 -0
- data/lib/bullhorn/bullhorn.rb +26 -0
- data/lib/bullhorn/bullhorn/candidates.rb +171 -0
- data/lib/bullhorn/bullhorn/categories.rb +51 -0
- data/lib/bullhorn/bullhorn/client.rb +174 -0
- data/lib/bullhorn/bullhorn/files.rb +195 -0
- data/lib/bullhorn/bullhorn/jobs.rb +168 -0
- data/lib/bullhorn/bullhorn/util.rb +9 -0
- metadata +11 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
Binary file
|
data/bullhorn-rails.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "bullhorn-rails"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jack Thorsen"]
|
@@ -26,8 +26,17 @@ Gem::Specification.new do |s|
|
|
26
26
|
"Rakefile",
|
27
27
|
"VERSION",
|
28
28
|
"bullhorn-rails-.gem",
|
29
|
+
"bullhorn-rails-0.1.0.gem",
|
29
30
|
"bullhorn-rails.gemspec",
|
31
|
+
"lib/.DS_Store",
|
30
32
|
"lib/bullhorn-rails.rb",
|
33
|
+
"lib/bullhorn/bullhorn.rb",
|
34
|
+
"lib/bullhorn/bullhorn/candidates.rb",
|
35
|
+
"lib/bullhorn/bullhorn/categories.rb",
|
36
|
+
"lib/bullhorn/bullhorn/client.rb",
|
37
|
+
"lib/bullhorn/bullhorn/files.rb",
|
38
|
+
"lib/bullhorn/bullhorn/jobs.rb",
|
39
|
+
"lib/bullhorn/bullhorn/util.rb",
|
31
40
|
"spec/bullhorn-rails_spec.rb",
|
32
41
|
"spec/spec_helper.rb"
|
33
42
|
]
|
data/lib/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'savon'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'net/https'
|
4
|
+
|
5
|
+
require 'bullhorn/util'
|
6
|
+
require 'bullhorn/client'
|
7
|
+
require 'bullhorn/categories'
|
8
|
+
|
9
|
+
module Bullhorn
|
10
|
+
|
11
|
+
Savon.configure do |config|
|
12
|
+
|
13
|
+
# TODO Add logger based on environment
|
14
|
+
# The default log level used by Savon is :debug.
|
15
|
+
config.log_level = :debug
|
16
|
+
|
17
|
+
# In a Rails application you might want Savon to use the Rails logger.
|
18
|
+
#config.logger = Rails.logger
|
19
|
+
|
20
|
+
# The XML logged by Savon can be formatted for debugging purposes.
|
21
|
+
# Unfortunately, this feature comes with a performance and is not
|
22
|
+
# recommended for production environments.
|
23
|
+
config.pretty_print_xml = true
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module Bullhorn
|
2
|
+
|
3
|
+
class Candidates
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
|
8
|
+
###--------------So I can set credentials from console
|
9
|
+
def credentials
|
10
|
+
Bullhorn::Client.username = '525.resumes'
|
11
|
+
Bullhorn::Client.password = 'scrub04k'
|
12
|
+
Bullhorn::Client.apiKey = '943C63E3-FB1A-4089-A3813849B9626393'
|
13
|
+
end
|
14
|
+
|
15
|
+
###---------------- Find a Candidate by Id
|
16
|
+
def find_by id
|
17
|
+
(select_fields results(Bullhorn::Client.findMultiple find_multiple_request([id]))).first
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
###---------------- Find an array of Candidates by an array of Ids
|
22
|
+
def find_multiple_by ids
|
23
|
+
candidates = []
|
24
|
+
index = 1
|
25
|
+
while ids.page(index) != nil
|
26
|
+
candidate_detail_response = Bullhorn::Client.findMultiple candidate_detail_request(ids.page(index))
|
27
|
+
details = get_candidate_details_from(candidate_detail_response)
|
28
|
+
|
29
|
+
details = [details] if !(details.class == Array)
|
30
|
+
select_fields resultsdetails
|
31
|
+
index += 1
|
32
|
+
end
|
33
|
+
candidates
|
34
|
+
end
|
35
|
+
|
36
|
+
###----------------- Find a Candidate by Email
|
37
|
+
### returns Candidate dto, or nil if not found
|
38
|
+
def query_by email
|
39
|
+
request = candidate_query_request
|
40
|
+
request[:query][:where] = "email='" + email + "'"
|
41
|
+
response=(Bullhorn::Client.query request).body[:query_response][:return]
|
42
|
+
find_by response[:ids] if response.has_key?(:ids)
|
43
|
+
end
|
44
|
+
|
45
|
+
###----------------- Find a Candidate using a query string
|
46
|
+
def query_where conditions
|
47
|
+
candidate_query_request[:query][:where] = conditions
|
48
|
+
response=(Bullhorn::Client.query candidate_query_request).body[:query_response][:return]
|
49
|
+
find_by response[:ids] if response.has_key?(:ids)
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
###----------------- Gets first qty of Ids, for testing purposes
|
54
|
+
def get_ids qty
|
55
|
+
get_id_response qty
|
56
|
+
end
|
57
|
+
|
58
|
+
###----------------- Gets first qty of Ids, for testing purposes
|
59
|
+
def get_id_response qty
|
60
|
+
request = candidate_query_request
|
61
|
+
request[:query][:maxResults] = qty if qty
|
62
|
+
response = (Bullhorn::Client.query request).body[:query_response][:return][:ids]
|
63
|
+
response
|
64
|
+
end
|
65
|
+
|
66
|
+
###------------------- Save Candidate
|
67
|
+
def save candidate
|
68
|
+
request = save_request(candidate)
|
69
|
+
(Bullhorn::Client.save request).body[:save_response]
|
70
|
+
end
|
71
|
+
|
72
|
+
def default_candidate
|
73
|
+
{
|
74
|
+
:address => {
|
75
|
+
:address1 => "",
|
76
|
+
:address2 => "",
|
77
|
+
:city => "",
|
78
|
+
:state => "",
|
79
|
+
:countryID => 1,
|
80
|
+
:zip => ""
|
81
|
+
},
|
82
|
+
:category_id => 45, #integer
|
83
|
+
:comments => "",
|
84
|
+
:email => "",
|
85
|
+
:employee_type => "",
|
86
|
+
:first_name => "",
|
87
|
+
:is_deleted => 0, #boolean
|
88
|
+
:is_editable => 1, #boolean
|
89
|
+
:last_name => "",
|
90
|
+
:name => "",
|
91
|
+
:owner_id => 43832, #integer
|
92
|
+
:password => "hireminds123",
|
93
|
+
:preferred_contact => "",
|
94
|
+
:status => "",
|
95
|
+
:username => "",
|
96
|
+
:user_type_id => 35,
|
97
|
+
:is_day_light_savings => true,
|
98
|
+
:mass_mail_opt_out => false,
|
99
|
+
:time_zone_offset_est => 0,
|
100
|
+
:day_rate => 0,
|
101
|
+
:day_rate_low => 0,
|
102
|
+
:degree_list => "",
|
103
|
+
:salary => 0,
|
104
|
+
:travel_limit => 0,
|
105
|
+
:will_relocate => false,
|
106
|
+
:work_authorized => true,
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
protected
|
111
|
+
|
112
|
+
def results response
|
113
|
+
response.body[:find_multiple_response][:return][:dtos]
|
114
|
+
end
|
115
|
+
|
116
|
+
def api operation, body
|
117
|
+
Bullhorn::Client.api operation, body
|
118
|
+
end
|
119
|
+
|
120
|
+
def select_fields response
|
121
|
+
candidates = []
|
122
|
+
response = [response] if !(response.kind_of?(Array))
|
123
|
+
response.each do |dto|
|
124
|
+
candidate = dto
|
125
|
+
candidates << candidate
|
126
|
+
end
|
127
|
+
candidates
|
128
|
+
end
|
129
|
+
|
130
|
+
def find_candidate_request id
|
131
|
+
{
|
132
|
+
:entity => 'Candidate',
|
133
|
+
:id => id,
|
134
|
+
:attributes! => { :id => {"xsi:type" => "xsd:int"}}
|
135
|
+
}
|
136
|
+
end
|
137
|
+
|
138
|
+
def find_multiple_request page_of_ids
|
139
|
+
{
|
140
|
+
:entityName => "Candidate",
|
141
|
+
:ids => page_of_ids,
|
142
|
+
:attributes! => { :ids => { "xsi:type" => "xsd:int" } }
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
def candidate_query_request
|
147
|
+
{:query => {:entityName => "Candidate", :maxResults => 10}}
|
148
|
+
end
|
149
|
+
|
150
|
+
def save_request candidate
|
151
|
+
{
|
152
|
+
:dto => candidate,
|
153
|
+
:attributes! => {
|
154
|
+
:dto => {
|
155
|
+
"xsi:type"=>"ns4:candidateDto",
|
156
|
+
"xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance",
|
157
|
+
"xmlns:ns4"=>"http://candidate.entity.bullhorn.com/"
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
end
|
162
|
+
|
163
|
+
def clean_up response
|
164
|
+
response
|
165
|
+
end
|
166
|
+
|
167
|
+
#----------------------------------------------------
|
168
|
+
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Bullhorn
|
2
|
+
|
3
|
+
class Categories
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def all
|
8
|
+
response = Bullhorn::Client.query category_id_request
|
9
|
+
ids = get_ids_from response
|
10
|
+
get_category_names_from ids
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def category_id_request
|
16
|
+
{ :query => { :entityName => "Category" } }
|
17
|
+
end
|
18
|
+
|
19
|
+
def category_detail_request page_of_ids
|
20
|
+
{
|
21
|
+
:entityName => "Category",
|
22
|
+
:ids => page_of_ids,
|
23
|
+
:attributes! => { :ids => { "xsi:type" => "xsd:int" } }
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_ids_from response
|
28
|
+
response[:query_response][:return][:ids]
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_category_details_from page_of_category_results
|
32
|
+
page_of_category_results[:find_multiple_response][:return][:dtos]
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_category_names_from ids
|
36
|
+
categories = []
|
37
|
+
index = 1
|
38
|
+
|
39
|
+
while ids.page(index) != nil
|
40
|
+
category_detail_response = Bullhorn::Client.findMultiple category_detail_request(ids.page(index))
|
41
|
+
|
42
|
+
get_category_details_from(category_detail_response).each { |c| categories << {:id => c[:category_id], :name => c[:name].titleize} }
|
43
|
+
|
44
|
+
index += 1
|
45
|
+
end
|
46
|
+
|
47
|
+
categories
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
module Bullhorn
|
2
|
+
|
3
|
+
class Client
|
4
|
+
|
5
|
+
class NoCredentials < StandardError; end
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
attr_writer :username, :password, :apiKey
|
10
|
+
|
11
|
+
def api operation, body
|
12
|
+
client = connection
|
13
|
+
session = @session
|
14
|
+
client.request :tns, operation.to_sym do
|
15
|
+
body[:session] = session
|
16
|
+
soap.body = body
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_entity_files body
|
21
|
+
client = connection
|
22
|
+
session = @session
|
23
|
+
client.request :tns, :getEntityFiles do
|
24
|
+
body[:session] = session
|
25
|
+
soap.body = body
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse body
|
30
|
+
client = connection
|
31
|
+
session = @session
|
32
|
+
client.request :tns, :parseResume do
|
33
|
+
body[:session] = session
|
34
|
+
soap.body = body
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_file body
|
39
|
+
client = connection
|
40
|
+
session = @session
|
41
|
+
client.request :tns, :addFile do
|
42
|
+
body[:session] = session
|
43
|
+
soap.body = body
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def update_file body
|
48
|
+
client = connection
|
49
|
+
session = @session
|
50
|
+
client.request :tns, :updateFile do
|
51
|
+
body[:session] = session
|
52
|
+
soap.body = body
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def findCandidate body
|
57
|
+
client = connection
|
58
|
+
session = @session
|
59
|
+
client.request :findCandidate do
|
60
|
+
body[:session] = session
|
61
|
+
soap.body = body
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def save body
|
66
|
+
client = connection
|
67
|
+
session = @session
|
68
|
+
client.request :save do
|
69
|
+
body[:session] = session
|
70
|
+
soap.body = body
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def query body
|
75
|
+
client = connection
|
76
|
+
session = @session
|
77
|
+
client.request :query do
|
78
|
+
body[:session] = session
|
79
|
+
soap.body = body
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def getFile body
|
84
|
+
client = connection
|
85
|
+
session = @session
|
86
|
+
client.request :tns, :getFile do
|
87
|
+
body[:session] = session
|
88
|
+
soap.body = body
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def findMultiple body
|
93
|
+
client = connection
|
94
|
+
session = @session
|
95
|
+
client.request :tns, :findMultiple do
|
96
|
+
body[:session] = session
|
97
|
+
soap.body = body
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def getAssociationIds body
|
102
|
+
client = connection
|
103
|
+
session = @session
|
104
|
+
client.request :tns, :getAssociationIds do
|
105
|
+
body[:session] = session
|
106
|
+
soap.body = body
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def eventsSubscribe body
|
111
|
+
client = connection
|
112
|
+
session = @session
|
113
|
+
client.request :tns, :eventsSubscribe do
|
114
|
+
body[:session] = session
|
115
|
+
soap.body = body
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def eventsUnsubscribe body
|
120
|
+
client = connection
|
121
|
+
session = @session
|
122
|
+
client.request :tns, :eventsUnsubscribe do
|
123
|
+
body[:session] = session
|
124
|
+
soap.body = body
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def eventsGetEvents body
|
129
|
+
client = connection
|
130
|
+
session = @session
|
131
|
+
client.request :tns, :eventsGetEvents do
|
132
|
+
body[:session] = session
|
133
|
+
soap.body = body
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
def connection
|
140
|
+
|
141
|
+
raise NoCredentials if @username.nil?
|
142
|
+
raise NoCredentials if @password.nil?
|
143
|
+
raise NoCredentials if @apiKey.nil?
|
144
|
+
|
145
|
+
@connection ||= new_connection
|
146
|
+
end
|
147
|
+
|
148
|
+
def new_connection
|
149
|
+
@connection = Savon.client "https://api.bullhornstaffing.com/webservices-2.5/?wsdl"
|
150
|
+
authenticate
|
151
|
+
end
|
152
|
+
|
153
|
+
def authenticate
|
154
|
+
username = @username
|
155
|
+
password = @password
|
156
|
+
apiKey = @apiKey
|
157
|
+
response = @connection.request :start_session do
|
158
|
+
soap.body = {
|
159
|
+
:username => username,
|
160
|
+
:password => password,
|
161
|
+
:apiKey => apiKey
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
@session = response.body[:start_session_response][:return][:session]
|
166
|
+
@connection
|
167
|
+
end
|
168
|
+
|
169
|
+
def clear_connection
|
170
|
+
@connection = nil
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
module Bullhorn
|
2
|
+
|
3
|
+
class Files
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
#--------- Upload a new File and attach it to a Candidate (New) Returns new File Id
|
8
|
+
def add file, entity_id=114755, entity_name="Candidate"
|
9
|
+
response = (Bullhorn::Client.add_file file_request(file, entity_name, entity_id)).body[:add_file_response][:return][:id]
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
#---------- Upload a replacement to a File attached to a Candidate (Udate)
|
14
|
+
def update file, entity_id=114755, entity_name="Candidate"
|
15
|
+
Bullhorn::Client.update_file file_request(file)
|
16
|
+
end
|
17
|
+
|
18
|
+
#---------- Get list of all Files' meta data attached to a Candidate (Index)
|
19
|
+
#---------- Returns: :comments, :content_sub_type, :content_type, :id, :name, :type
|
20
|
+
def get_entity_files entity_id = 114755, entity = "Candidate"
|
21
|
+
response = (Bullhorn::Client.get_entity_files get_entity_files_request(entity_id, entity)).body[:get_entity_files_response][:return][:api_entity_metas]
|
22
|
+
end
|
23
|
+
|
24
|
+
#---------- Get a File specified by its Id (Show) Returns File
|
25
|
+
def get_file_by id, entity_id=114775, entity_name="Candidate"
|
26
|
+
(Bullhorn::Client.getFile get_file_request(id, entity_name, entity_id)).body[:get_file_response][:return][:file_data]
|
27
|
+
end
|
28
|
+
|
29
|
+
#---------- Delete all files for a Candidate
|
30
|
+
def delete_all candidate_id
|
31
|
+
(get_entity_files candidate_id).each do |file|
|
32
|
+
Bullhorn::Client.api "deleteFile", delete_file_request(file, candidate_id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
###--------- Find a Candidate by Email or create a new Candidate,
|
39
|
+
### then update Candidate fields with resume file and save
|
40
|
+
def store file_by_candidate
|
41
|
+
sum = []
|
42
|
+
response = (Bullhorn::Candidates.query_by file_by_candidate[:email]) || Bullhorn::Candidates.default_candidate
|
43
|
+
candidate = {
|
44
|
+
:address => response[:address],
|
45
|
+
:categoryID => response[:category_id], #integer
|
46
|
+
:comments => response[:comments],
|
47
|
+
:email => response[:email],
|
48
|
+
:employeeType => response[:employee_type],
|
49
|
+
:firstName => response[:first_name],
|
50
|
+
:isDeleted => response[:is_deleted], #boolean
|
51
|
+
:isEditable => response[:is_editable], #boolean
|
52
|
+
:lastName => response[:last_name],
|
53
|
+
:name => response[:name],
|
54
|
+
:ownerID => response[:owner_id], #integer
|
55
|
+
:password => response[:password],
|
56
|
+
:preferredContact => response[:preferred_contact],
|
57
|
+
:status => response[:status],
|
58
|
+
:username => response[:username],
|
59
|
+
:userTypeID => response[:user_type_id],
|
60
|
+
:isDayLightSavings => response[:is_day_light_savings],
|
61
|
+
:massMailOptOut => response[:mass_mail_opt_out],
|
62
|
+
:timeZoneOffsetEST => response[:time_zone_offset_est],
|
63
|
+
:dayRate => response[:day_rate],
|
64
|
+
:dayRateLow => response[:day_rate_low],
|
65
|
+
:degreeList => response[:degree_list],
|
66
|
+
:salary => response[:salary],
|
67
|
+
:travelLimit => response[:travel_limit],
|
68
|
+
:willRelocate => response[:will_relocate],
|
69
|
+
:workAuthorized => response[:work_authorized],
|
70
|
+
|
71
|
+
:attributes! => {
|
72
|
+
:categoryID => {"xsi:type" => "xs:int"},
|
73
|
+
:isDeleted => {"xsi:type" => "xs:boolean"},
|
74
|
+
:isEditable => {"xsi:type" => "xs:boolean"},
|
75
|
+
:ownerID => {"xsi:type" => "xs:int"},
|
76
|
+
:userTypeID => {"xsi:type" => "xs:int"},
|
77
|
+
:isDayLightSavings => {"xsi:type" => "xs:boolean"},
|
78
|
+
}
|
79
|
+
}
|
80
|
+
file_by_candidate.each do |key, value|
|
81
|
+
if (value.class != HashWithIndifferentAccess)
|
82
|
+
candidate[key.camelize(:lower).to_sym] = value if (value && (value != ""))
|
83
|
+
else
|
84
|
+
value.each do |k, v|
|
85
|
+
candidate[key.to_sym][k.to_sym] = v if (v != (nil || "" || " "))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
###--------- Clean up DTO
|
91
|
+
candidate.delete(:attachment)
|
92
|
+
if response.has_key?(:user_id)
|
93
|
+
sum << "has id"
|
94
|
+
sum << (candidate[:userID] = response[:user_id])
|
95
|
+
candidate[:attributes!][:userID] = {"xsi:type" => "xs:int"}
|
96
|
+
else
|
97
|
+
sum << "no id"
|
98
|
+
candidate[:username] = candidate[:email]
|
99
|
+
sum << candidate[:username]
|
100
|
+
sum << candidate[:lastName]
|
101
|
+
candidate[:password] = "hireminds766"
|
102
|
+
end
|
103
|
+
[:"@xmlns:xsi", :"@xmlns:ns4", :"@xsi:type", :alerts].each do |key|
|
104
|
+
candidate.delete(key)
|
105
|
+
end
|
106
|
+
|
107
|
+
Bullhorn::Candidates.save candidate
|
108
|
+
|
109
|
+
|
110
|
+
sum << candidate
|
111
|
+
end
|
112
|
+
|
113
|
+
###---------- Parse a Resume or return nil if parsing fails
|
114
|
+
def parse resume
|
115
|
+
request = {:base64ChunkedResume => resume}
|
116
|
+
response = nil
|
117
|
+
index = 15
|
118
|
+
|
119
|
+
#--- Bullhorn's parseResume sometimes does't return the proper result. Keep trying up to index times until captured
|
120
|
+
while index > 0 do
|
121
|
+
index -= 1
|
122
|
+
response = (Bullhorn::Client.parse request).body[:parse_resume_response][:return][:hr_xml]
|
123
|
+
return response if response
|
124
|
+
end
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
protected
|
131
|
+
|
132
|
+
def delete_file_request file, entity_id, entity = "Candidate"
|
133
|
+
{
|
134
|
+
:entityName => entity,
|
135
|
+
:entityId => entity_id.to_i,
|
136
|
+
:fileId => file[:id],
|
137
|
+
:attributes! => {
|
138
|
+
:fileId => {"xsi:type" => "xsd:int"},
|
139
|
+
:entityId => {"xsi:type" => "xsd:int"}
|
140
|
+
}
|
141
|
+
}
|
142
|
+
end
|
143
|
+
|
144
|
+
def get_file_request id, entity_name, entity_id
|
145
|
+
{
|
146
|
+
:entityName => entity_name,
|
147
|
+
:entityId => entity_id,
|
148
|
+
:fileId => id,
|
149
|
+
:attributes! => {
|
150
|
+
:entity_Id => { "xsi:type" => "xsd:int" },
|
151
|
+
:fileId => { "xsi:type" => "xsd:int" }
|
152
|
+
}
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
156
|
+
def file_request file, entity_name="Candidate", entity_id=114755
|
157
|
+
{
|
158
|
+
:fileMetaData => {
|
159
|
+
:comments => "Uploaded file",
|
160
|
+
:contentSubType => "",
|
161
|
+
:contentType => file[:content_type],
|
162
|
+
:name => file[:filename],
|
163
|
+
:type => "Resume",
|
164
|
+
},
|
165
|
+
:fileContent => Base64.encode64(file[:document]),
|
166
|
+
:entityName => entity_name,
|
167
|
+
:entityId => entity_id,
|
168
|
+
:attributes! => { :entityId => {"xsi:type" => "xsd:int"}}
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
def get_entity_files_request entity_id, entity
|
173
|
+
{
|
174
|
+
:entityName => entity,
|
175
|
+
:entityId => entity_id,
|
176
|
+
:attributes! => { :entityId => {"xsi:type" => "xsd:int"}}
|
177
|
+
}
|
178
|
+
end
|
179
|
+
|
180
|
+
def save_request file
|
181
|
+
{
|
182
|
+
:dto => file,
|
183
|
+
:attributes! => {
|
184
|
+
:dto => {
|
185
|
+
"xsi:type"=>"ns4:fileDto",
|
186
|
+
"xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance",
|
187
|
+
"xmlns:ns4"=>"http://file.entity.bullhorn.com/"
|
188
|
+
}
|
189
|
+
}
|
190
|
+
}
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module Bullhorn
|
2
|
+
|
3
|
+
class Jobs
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# Get all Jobs
|
8
|
+
def all
|
9
|
+
response = Bullhorn::Client.query open_approved_job_id_request
|
10
|
+
ids = get_ids_from response
|
11
|
+
get_jobs_from ids
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get Job Description Array from Id Array
|
15
|
+
def fetch_job_descriptions job_ids
|
16
|
+
get_jobs_from job_ids
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch_job_description job_id
|
20
|
+
get_job_from job_id
|
21
|
+
end
|
22
|
+
|
23
|
+
# Get Nested Hash of Category ID's by Job ID
|
24
|
+
def fetch_category_ids_from_job_ids job_ids
|
25
|
+
get_category_ids_from_job_ids job_ids
|
26
|
+
end
|
27
|
+
|
28
|
+
def subscribe
|
29
|
+
Bullhorn::Client.eventsSubscribe subscribe_request #[:body][:subscription_meta_data]
|
30
|
+
end
|
31
|
+
|
32
|
+
def unsubscribe
|
33
|
+
(Bullhorn::Client.eventsUnsubscribe unsubscribe_request).body[:events_unsubscribe_response][:return][:unsubscribed]
|
34
|
+
end
|
35
|
+
|
36
|
+
def new_events
|
37
|
+
event_response = (Bullhorn::Client.eventsGetEvents get_events_request).body[:events_get_events_response][:return][:results]
|
38
|
+
if event_response
|
39
|
+
if event_response[:events].kind_of?(Array)
|
40
|
+
event_response[:events]
|
41
|
+
else
|
42
|
+
return [event_response[:events]]
|
43
|
+
end
|
44
|
+
else
|
45
|
+
puts "NO EVENTS?"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
protected
|
50
|
+
|
51
|
+
def open_approved_job_id_request
|
52
|
+
{ :query => { :entityName => "JobOrder", :where => "isOpen=1 AND isPublic=1 AND (status='Accepting Candidates' OR status='Website Only')"} }
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_category_ids_from_job_ids job_ids
|
56
|
+
responses = []
|
57
|
+
job_ids.each do |job_id|
|
58
|
+
job_id_response = Bullhorn::Client.getAssociationIds category_ids_from_job_id_request(job_id)
|
59
|
+
responses << {job_id => job_id_response.body[:get_association_ids_response][:return][:ids]}
|
60
|
+
end
|
61
|
+
responses
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_events_request
|
65
|
+
{
|
66
|
+
:subscriptionId => "JobOrderEvent",
|
67
|
+
:max_events => 2
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def subscribe_request
|
72
|
+
{
|
73
|
+
:subscriptionId => "JobOrderEvent",
|
74
|
+
:criteria => {
|
75
|
+
:entityNames => "JobOrder",
|
76
|
+
:entityEventTypes => "INSERTED"
|
77
|
+
},
|
78
|
+
:attributes! => {
|
79
|
+
:criteria => {
|
80
|
+
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
81
|
+
"xmlns:ns4" => "http://subscription.dataevent.bullhorn.com/",
|
82
|
+
"xsi:type" => "ns4:entityEventSubscriptionCriteria"
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def unsubscribe_request
|
89
|
+
{
|
90
|
+
:subscriptionId => "JobOrderEvent"
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
def category_ids_from_job_id_request job_id
|
95
|
+
{
|
96
|
+
:entityName => "JobOrder",
|
97
|
+
:id => job_id,
|
98
|
+
:attributes! => { :id => {"xsi:type" => "xsd:int"}},
|
99
|
+
:associationName => "categories"
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
def job_detail_request page_of_ids
|
104
|
+
{
|
105
|
+
:entityName => "JobOrder",
|
106
|
+
:ids => page_of_ids,
|
107
|
+
:attributes! => { :ids => { "xsi:type" => "xsd:int" } }
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_ids_from response
|
112
|
+
response[:query_response][:return][:ids]
|
113
|
+
end
|
114
|
+
|
115
|
+
def job_detail job
|
116
|
+
{
|
117
|
+
:id => job[:job_order_id].to_i,
|
118
|
+
:title => job[:title],
|
119
|
+
:years => job[:years_required],
|
120
|
+
:added => job[:date_added],
|
121
|
+
:description => remove_html(job[:public_description]),
|
122
|
+
:site => job[:on_site],
|
123
|
+
:employment => job[:employment_type],
|
124
|
+
:status => job[:status],
|
125
|
+
:is_open => job[:is_open],
|
126
|
+
:is_public => job[:is_public]
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
def get_job_details_from page_of_job_results
|
131
|
+
page = page_of_job_results[:find_multiple_response][:return][:dtos]
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
def remove_html html
|
136
|
+
html
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
def get_job_from id
|
141
|
+
job_detail_response = Bullhorn::Client.findMultiple job_detail_request([id])
|
142
|
+
job_detail(get_job_details_from(job_detail_response))
|
143
|
+
end
|
144
|
+
|
145
|
+
def get_jobs_from ids
|
146
|
+
jobs = []
|
147
|
+
index = 1
|
148
|
+
while ids.page(index) != nil
|
149
|
+
job_detail_response = Bullhorn::Client.findMultiple job_detail_request(ids.page(index))
|
150
|
+
details = get_job_details_from(job_detail_response)
|
151
|
+
|
152
|
+
details = [details] if !(details.class == Array)
|
153
|
+
puts details
|
154
|
+
details.each do |job|
|
155
|
+
puts job.inspect
|
156
|
+
jobs << job_detail(job)
|
157
|
+
end
|
158
|
+
|
159
|
+
index += 1
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
|
164
|
+
jobs
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bullhorn-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -108,8 +108,17 @@ files:
|
|
108
108
|
- Rakefile
|
109
109
|
- VERSION
|
110
110
|
- bullhorn-rails-.gem
|
111
|
+
- bullhorn-rails-0.1.0.gem
|
111
112
|
- bullhorn-rails.gemspec
|
113
|
+
- lib/.DS_Store
|
112
114
|
- lib/bullhorn-rails.rb
|
115
|
+
- lib/bullhorn/bullhorn.rb
|
116
|
+
- lib/bullhorn/bullhorn/candidates.rb
|
117
|
+
- lib/bullhorn/bullhorn/categories.rb
|
118
|
+
- lib/bullhorn/bullhorn/client.rb
|
119
|
+
- lib/bullhorn/bullhorn/files.rb
|
120
|
+
- lib/bullhorn/bullhorn/jobs.rb
|
121
|
+
- lib/bullhorn/bullhorn/util.rb
|
113
122
|
- spec/bullhorn-rails_spec.rb
|
114
123
|
- spec/spec_helper.rb
|
115
124
|
homepage: http://github.com/jthorsen/bullhorn-rails
|
@@ -127,7 +136,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
127
136
|
version: '0'
|
128
137
|
segments:
|
129
138
|
- 0
|
130
|
-
hash:
|
139
|
+
hash: 444463454353317294
|
131
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
141
|
none: false
|
133
142
|
requirements:
|